XuqmGroup-PrivateDeploy/scripts/bench.sh

95 行
3.1 KiB
Bash

#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
. "$ROOT_DIR/scripts/lib.sh"
load_env
PROFILE="${1:-base}"
DURATION="${2:-30}"
REPORT_FILE="$ROOT_DIR/dist/bench-$(date +%Y%m%d%H%M%S).json"
mkdir -p "$ROOT_DIR/dist"
audit "bench" "STARTED" "profile=$PROFILE duration=${DURATION}s"
progress "bench" "STARTED" "profile=$PROFILE"
require_cmd curl
require_cmd docker
BASE_URL="${CONSOLE_DOMAIN:-http://localhost}"
bench_http() {
local name="$1"
local url="$2"
local concurrency="${3:-10}"
local requests="${4:-100}"
local pass_rps="${5:-50}"
local pass_p99_ms="${6:-500}"
printf 'Benchmarking %s (%s)...\n' "$name" "$url"
if command -v ab >/dev/null 2>&1; then
RAW="$(ab -n "$requests" -c "$concurrency" -q "$url" 2>/dev/null || true)"
RPS="$(printf '%s' "$RAW" | grep 'Requests per second' | awk '{print $4}' | cut -d. -f1)"
P99="$(printf '%s' "$RAW" | grep '99%' | awk '{print $2}')"
RPS="${RPS:-0}"
P99="${P99:-9999}"
elif command -v wrk >/dev/null 2>&1; then
RAW="$(wrk -t2 -c"$concurrency" -d"${DURATION}s" "$url" 2>/dev/null || true)"
RPS="$(printf '%s' "$RAW" | grep 'Requests/sec' | awk '{print $2}' | cut -d. -f1)"
P99="${P99:-0}"
RPS="${RPS:-0}"
else
# Fallback: sequential curl timing
total_ms=0
for _ in $(seq 1 20); do
ms="$(curl -sk -o /dev/null -w '%{time_total}' --max-time 5 "$url" 2>/dev/null | awk '{printf "%d", $1*1000}')"
total_ms=$((total_ms + ms))
done
AVG_MS=$((total_ms / 20))
RPS=$((1000 / (AVG_MS + 1)))
P99="$AVG_MS"
fi
PASS="true"
[ "$RPS" -lt "$pass_rps" ] && PASS="false"
[ "$P99" -gt "$pass_p99_ms" ] && PASS="false"
printf ' RPS: %s (min %s) | P99: %sms (max %sms) | %s\n' \
"$RPS" "$pass_rps" "$P99" "$pass_p99_ms" "$( [ "$PASS" = "true" ] && printf 'PASS' || printf 'FAIL')"
printf '{"name":"%s","url":"%s","rps":%s,"p99_ms":%s,"target_rps":%s,"target_p99_ms":%s,"pass":%s}' \
"$name" "$url" "$RPS" "$P99" "$pass_rps" "$pass_p99_ms" "$PASS"
}
RESULTS=()
RESULTS+=("$(bench_http "tenant-api-health" "$BASE_URL/actuator/health" 5 50 20 1000)")
if printf '%s' "$PROFILE" | grep -q 'im' && [ -n "${IM_DOMAIN:-}" ]; then
RESULTS+=("$(bench_http "im-api-health" "${IM_DOMAIN}/actuator/health" 5 50 20 1000)")
fi
if printf '%s' "$PROFILE" | grep -q 'update' && [ -n "${UPDATE_DOMAIN:-}" ]; then
RESULTS+=("$(bench_http "update-api-health" "${UPDATE_DOMAIN}/actuator/health" 5 50 20 1000)")
fi
# Docker stats snapshot
DOCKER_STATS="$(docker stats --no-stream --format '{"container":"{{.Name}}","cpu":"{{.CPUPerc}}","mem":"{{.MemUsage}}"}' 2>/dev/null || echo '[]')"
RESULTS_JSON="$(printf '%s\n' "${RESULTS[@]}" | paste -sd ',' - | sed 's/^/[/' | sed 's/$/]/')"
cat > "$REPORT_FILE" <<EOF
{
"timestamp": "$(now)",
"profile": "$PROFILE",
"durationSec": $DURATION,
"privateVersion": "${PRIVATE_VERSION:-unknown}",
"results": $RESULTS_JSON,
"dockerStats": $DOCKER_STATS
}
EOF
audit "bench" "DONE" "report=$REPORT_FILE"
progress "bench" "DONE" "profile=$PROFILE"
printf 'Benchmark report: %s\n' "$REPORT_FILE"