perf(P22PROD1-3,P22PROD1-4): 资产exact-first搜索优化与三条benchmark脚本
这个提交包含在:
+89
@@ -0,0 +1,89 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
BASE_URL="${BASE_URL:-http://127.0.0.1:3000}"
|
||||
DEVICE_FINGERPRINT="${DEVICE_FINGERPRINT:-benchmark-assets}"
|
||||
ADMIN_IDENTIFIER="${ADMIN_IDENTIFIER:-finance_mgr@hyinda.com}"
|
||||
ADMIN_PASSWORD="${ADMIN_PASSWORD:-FinanceMgrPassword1234}"
|
||||
ITERATIONS="${ITERATIONS:-10}"
|
||||
ASSET_EXACT_ENDPOINT="${ASSET_EXACT_ENDPOINT:-/api/assets?q=ZC-001&mine=0}"
|
||||
ASSET_FUZZY_ENDPOINT="${ASSET_FUZZY_ENDPOINT:-/api/assets?q=%E6%B5%8B%E8%AF%95&mine=0}"
|
||||
|
||||
if ! command -v curl >/dev/null 2>&1; then
|
||||
echo "[ERROR] curl not found" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v jq >/dev/null 2>&1; then
|
||||
echo "[ERROR] jq not found" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
TMP_DIR="$(mktemp -d)"
|
||||
cleanup() {
|
||||
rm -rf "$TMP_DIR"
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
login() {
|
||||
local out_file="$1"
|
||||
local status
|
||||
status="$(curl -sS -o "$out_file" -w "%{http_code}" \
|
||||
-X POST "$BASE_URL/api/auth/login" \
|
||||
-H "content-type: application/json" \
|
||||
-H "x-device-fingerprint: $DEVICE_FINGERPRINT" \
|
||||
-d "{\"identifier\":\"$ADMIN_IDENTIFIER\",\"password\":\"$ADMIN_PASSWORD\"}")"
|
||||
|
||||
if [[ "$status" != "200" ]]; then
|
||||
echo "[ERROR] login failed: HTTP $status" >&2
|
||||
cat "$out_file" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
jq -er '.data.accessToken' "$out_file"
|
||||
}
|
||||
|
||||
benchmark_endpoint() {
|
||||
local label="$1"
|
||||
local endpoint="$2"
|
||||
local token="$3"
|
||||
|
||||
local total_ms=0
|
||||
local max_ms=0
|
||||
local min_ms=999999
|
||||
|
||||
for _ in $(seq 1 "$ITERATIONS"); do
|
||||
local body_file="$TMP_DIR/assets.json"
|
||||
local elapsed
|
||||
elapsed="$(curl -sS -o "$body_file" -w "%{time_total}" \
|
||||
-H "authorization: Bearer $token" \
|
||||
"$BASE_URL$endpoint")"
|
||||
|
||||
local elapsed_ms
|
||||
elapsed_ms="$(python3 - <<PY
|
||||
value = float("$elapsed")
|
||||
print(int(round(value * 1000)))
|
||||
PY
|
||||
)"
|
||||
|
||||
total_ms=$((total_ms + elapsed_ms))
|
||||
if (( elapsed_ms > max_ms )); then
|
||||
max_ms=$elapsed_ms
|
||||
fi
|
||||
if (( elapsed_ms < min_ms )); then
|
||||
min_ms=$elapsed_ms
|
||||
fi
|
||||
done
|
||||
|
||||
local avg_ms=$((total_ms / ITERATIONS))
|
||||
echo "$label $endpoint avg=${avg_ms}ms min=${min_ms}ms max=${max_ms}ms iterations=$ITERATIONS"
|
||||
}
|
||||
|
||||
echo "[1/2] Login"
|
||||
TOKEN="$(login "$TMP_DIR/login.json")"
|
||||
|
||||
echo "[2/2] Assets search benchmark"
|
||||
benchmark_endpoint "exact" "$ASSET_EXACT_ENDPOINT" "$TOKEN"
|
||||
benchmark_endpoint "fuzzy" "$ASSET_FUZZY_ENDPOINT" "$TOKEN"
|
||||
|
||||
echo "[OK] Assets benchmark completed"
|
||||
@@ -0,0 +1,86 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
BASE_URL="${BASE_URL:-http://127.0.0.1:3000}"
|
||||
DEVICE_FINGERPRINT="${DEVICE_FINGERPRINT:-benchmark-travel-reconciliation}"
|
||||
ADMIN_IDENTIFIER="${ADMIN_IDENTIFIER:-finance_mgr@hyinda.com}"
|
||||
ADMIN_PASSWORD="${ADMIN_PASSWORD:-FinanceMgrPassword1234}"
|
||||
ITERATIONS="${ITERATIONS:-10}"
|
||||
TRAVEL_RECON_ENDPOINT="${TRAVEL_RECON_ENDPOINT:-/api/travel/reconciliation/batches?page=1&pageSize=20}"
|
||||
|
||||
if ! command -v curl >/dev/null 2>&1; then
|
||||
echo "[ERROR] curl not found" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v jq >/dev/null 2>&1; then
|
||||
echo "[ERROR] jq not found" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
TMP_DIR="$(mktemp -d)"
|
||||
cleanup() {
|
||||
rm -rf "$TMP_DIR"
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
login() {
|
||||
local out_file="$1"
|
||||
local status
|
||||
status="$(curl -sS -o "$out_file" -w "%{http_code}" \
|
||||
-X POST "$BASE_URL/api/auth/login" \
|
||||
-H "content-type: application/json" \
|
||||
-H "x-device-fingerprint: $DEVICE_FINGERPRINT" \
|
||||
-d "{\"identifier\":\"$ADMIN_IDENTIFIER\",\"password\":\"$ADMIN_PASSWORD\"}")"
|
||||
|
||||
if [[ "$status" != "200" ]]; then
|
||||
echo "[ERROR] login failed: HTTP $status" >&2
|
||||
cat "$out_file" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
jq -er '.data.accessToken' "$out_file"
|
||||
}
|
||||
|
||||
benchmark_endpoint() {
|
||||
local endpoint="$1"
|
||||
local token="$2"
|
||||
|
||||
local total_ms=0
|
||||
local max_ms=0
|
||||
local min_ms=999999
|
||||
|
||||
for _ in $(seq 1 "$ITERATIONS"); do
|
||||
local body_file="$TMP_DIR/travel-reconciliation.json"
|
||||
local elapsed
|
||||
elapsed="$(curl -sS -o "$body_file" -w "%{time_total}" \
|
||||
-H "authorization: Bearer $token" \
|
||||
"$BASE_URL$endpoint")"
|
||||
|
||||
local elapsed_ms
|
||||
elapsed_ms="$(python3 - <<PY
|
||||
value = float("$elapsed")
|
||||
print(int(round(value * 1000)))
|
||||
PY
|
||||
)"
|
||||
|
||||
total_ms=$((total_ms + elapsed_ms))
|
||||
if (( elapsed_ms > max_ms )); then
|
||||
max_ms=$elapsed_ms
|
||||
fi
|
||||
if (( elapsed_ms < min_ms )); then
|
||||
min_ms=$elapsed_ms
|
||||
fi
|
||||
done
|
||||
|
||||
local avg_ms=$((total_ms / ITERATIONS))
|
||||
echo "$endpoint avg=${avg_ms}ms min=${min_ms}ms max=${max_ms}ms iterations=$ITERATIONS"
|
||||
}
|
||||
|
||||
echo "[1/2] Login"
|
||||
TOKEN="$(login "$TMP_DIR/login.json")"
|
||||
|
||||
echo "[2/2] Travel reconciliation benchmark"
|
||||
benchmark_endpoint "$TRAVEL_RECON_ENDPOINT" "$TOKEN"
|
||||
|
||||
echo "[OK] Travel reconciliation benchmark completed"
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
BASE_URL="${BASE_URL:-http://127.0.0.1:3000}"
|
||||
DEVICE_FINGERPRINT="${DEVICE_FINGERPRINT:-benchmark-workflow}"
|
||||
ADMIN_IDENTIFIER="${ADMIN_IDENTIFIER:-manager@hyinda.com}"
|
||||
ADMIN_PASSWORD="${ADMIN_PASSWORD:-ManagerPassword1234}"
|
||||
ITERATIONS="${ITERATIONS:-10}"
|
||||
WORKFLOW_ENDPOINT="${WORKFLOW_ENDPOINT:-/api/workflow/tasks?status=pending&page=1&pageSize=20}"
|
||||
|
||||
if ! command -v curl >/dev/null 2>&1; then
|
||||
echo "[ERROR] curl not found" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v jq >/dev/null 2>&1; then
|
||||
echo "[ERROR] jq not found" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
TMP_DIR="$(mktemp -d)"
|
||||
cleanup() {
|
||||
rm -rf "$TMP_DIR"
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
login() {
|
||||
local out_file="$1"
|
||||
local status
|
||||
status="$(curl -sS -o "$out_file" -w "%{http_code}" \
|
||||
-X POST "$BASE_URL/api/auth/login" \
|
||||
-H "content-type: application/json" \
|
||||
-H "x-device-fingerprint: $DEVICE_FINGERPRINT" \
|
||||
-d "{\"identifier\":\"$ADMIN_IDENTIFIER\",\"password\":\"$ADMIN_PASSWORD\"}")"
|
||||
|
||||
if [[ "$status" != "200" ]]; then
|
||||
echo "[ERROR] login failed: HTTP $status" >&2
|
||||
cat "$out_file" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
jq -er '.data.accessToken' "$out_file"
|
||||
}
|
||||
|
||||
benchmark_endpoint() {
|
||||
local endpoint="$1"
|
||||
local token="$2"
|
||||
|
||||
local total_ms=0
|
||||
local max_ms=0
|
||||
local min_ms=999999
|
||||
|
||||
for _ in $(seq 1 "$ITERATIONS"); do
|
||||
local body_file="$TMP_DIR/workflow.json"
|
||||
local elapsed
|
||||
elapsed="$(curl -sS -o "$body_file" -w "%{time_total}" \
|
||||
-H "authorization: Bearer $token" \
|
||||
"$BASE_URL$endpoint")"
|
||||
|
||||
local elapsed_ms
|
||||
elapsed_ms="$(python3 - <<PY
|
||||
value = float("$elapsed")
|
||||
print(int(round(value * 1000)))
|
||||
PY
|
||||
)"
|
||||
|
||||
total_ms=$((total_ms + elapsed_ms))
|
||||
if (( elapsed_ms > max_ms )); then
|
||||
max_ms=$elapsed_ms
|
||||
fi
|
||||
if (( elapsed_ms < min_ms )); then
|
||||
min_ms=$elapsed_ms
|
||||
fi
|
||||
done
|
||||
|
||||
local avg_ms=$((total_ms / ITERATIONS))
|
||||
echo "$endpoint avg=${avg_ms}ms min=${min_ms}ms max=${max_ms}ms iterations=$ITERATIONS"
|
||||
}
|
||||
|
||||
echo "[1/2] Login"
|
||||
TOKEN="$(login "$TMP_DIR/login.json")"
|
||||
|
||||
echo "[2/2] Workflow tasks benchmark"
|
||||
benchmark_endpoint "$WORKFLOW_ENDPOINT" "$TOKEN"
|
||||
|
||||
echo "[OK] Workflow benchmark completed"
|
||||
在新工单中引用
屏蔽一个用户