#!/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)"