|
- #!/bin/bash
- # 并发 RPM 限流测试脚本
- # 使用 Redis 令牌桶,测试 RPM=2 的并发安全性
-
- BASE_URL="http://172.22.48.1:3000"
- API_KEY="sk-1-ShkCnu0B4FTDiggowWiVZWFf349QFRt6rpdNBKQ1AZBpsD33"
- MODEL="deepseek-r1"
- CONCURRENT=20
-
- echo "======================================"
- echo " 用户模型 RPM 限流 - Redis 并发测试"
- echo "======================================"
- echo "RPM=2, 并发=$CONCURRENT, 模型=$MODEL"
- echo "令牌桶参数: Capacity=120, Rate=2, Requested=60"
- echo ""
-
- # 先清理旧的 Redis key
- echo "[0] 清理旧限流 key..."
- redis-cli -p 36379 DEL "rateLimit:UMRL:1:deepseek-r1" 2>/dev/null
- redis-cli -p 36379 DEL "user_model_rate_limit:1" 2>/dev/null
- sleep 1
-
- echo ""
- echo "[1] 测试并发 $CONCURRENT 个请求..."
- success=0
- rejected=0
- pids=()
- results_dir=$(mktemp -d)
-
- for i in $(seq 1 $CONCURRENT); do
- (
- status_code=$(curl -s -o /dev/null -w "%{http_code}" \
- "$BASE_URL/v1/chat/completions" \
- -H "Authorization: Bearer $API_KEY" \
- -H "Content-Type: application/json" \
- -d "{\"model\":\"$MODEL\",\"messages\":[{\"role\":\"user\",\"content\":\"hi\"}],\"max_tokens\":5}" \
- --connect-timeout 5 \
- --max-time 30)
- echo "$status_code" > "$results_dir/req_$i"
- ) &
- pids+=($!)
- done
-
- # 等待所有请求完成
- for pid in "${pids[@]}"; do
- wait $pid 2>/dev/null
- done
-
- # 统计结果
- echo ""
- echo "--- 结果 ---"
- for i in $(seq 1 $CONCURRENT); do
- code=$(cat "$results_dir/req_$i" 2>/dev/null || echo "000")
- if [ "$code" = "200" ]; then
- success=$((success + 1))
- echo " 请求 $i: $code ✓"
- elif [ "$code" = "429" ]; then
- rejected=$((rejected + 1))
- echo " 请求 $i: $code (限流)"
- else
- echo " 请求 $i: $code (其他)"
- fi
- done
-
- echo ""
- echo "======================================"
- echo " 统计"
- echo "======================================"
- echo "成功 (200): $success"
- echo "限流 (429): $rejected"
- echo "预期: 成功 <= 2, 限流 >= $((CONCURRENT - 2))"
- echo ""
-
- if [ "$success" -le 2 ]; then
- echo "✅ 测试通过!并发安全,最多 2 个请求成功"
- else
- echo "❌ 测试失败!预期最多 2 个成功,实际 $success 个"
- fi
-
- # 检查 Redis 中的令牌桶状态
- echo ""
- echo "--- Redis 令牌桶状态 ---"
- redis-cli -p 36379 HGETALL "rateLimit:UMRL:1:deepseek-r1" 2>/dev/null || echo "(无法连接 Redis)"
-
- # 清理
- rm -rf "$results_dir"
-
- echo ""
- echo "[2] 测试顺序请求(3 次连续,第 3 次 429)..."
- redis-cli -p 36379 DEL "rateLimit:UMRL:1:deepseek-r1" 2>/dev/null
- sleep 1
-
- code1=$(curl -s -o /dev/null -w "%{http_code}" "$BASE_URL/v1/chat/completions" \
- -H "Authorization: Bearer $API_KEY" -H "Content-Type: application/json" \
- -d "{\"model\":\"$MODEL\",\"messages\":[{\"role\":\"user\",\"content\":\"test1\"}],\"max_tokens\":5}" \
- --connect-timeout 5 --max-time 30)
- echo " 请求 1: $code1"
-
- code2=$(curl -s -o /dev/null -w "%{http_code}" "$BASE_URL/v1/chat/completions" \
- -H "Authorization: Bearer $API_KEY" -H "Content-Type: application/json" \
- -d "{\"model\":\"$MODEL\",\"messages\":[{\"role\":\"user\",\"content\":\"test2\"}],\"max_tokens\":5}" \
- --connect-timeout 5 --max-time 30)
- echo " 请求 2: $code2"
-
- code3=$(curl -s -o /dev/null -w "%{http_code}" "$BASE_URL/v1/chat/completions" \
- -H "Authorization: Bearer $API_KEY" -H "Content-Type: application/json" \
- -d "{\"model\":\"$MODEL\",\"messages\":[{\"role\":\"user\",\"content\":\"test3\"}],\"max_tokens\":5}" \
- --connect-timeout 5 --max-time 30)
- echo " 请求 3: $code3"
-
- if [ "$code1" = "200" ] && [ "$code2" = "200" ] && [ "$code3" = "429" ]; then
- echo "✅ 顺序测试通过!前 2 次 200,第 3 次 429"
- else
- echo "❌ 顺序测试失败!预期 200/200/429,实际 $code1/$code2/$code3"
- fi
-
- echo ""
- echo "--- Redis 令牌桶最终状态 ---"
- redis-cli -p 36379 HGETALL "rateLimit:UMRL:1:deepseek-r1" 2>/dev/null || echo "(无法连接 Redis)"
|