feat: 优化100人并发投票支持 + 修复奖项名称硬编码问题

服务端优化:
- Socket.IO 配置优化,支持高并发 WebSocket 连接
- 添加 connectTimeout、perMessageDeflate 等参数

压测脚本:
- 新增 vote-real-scenario.yaml 真实场景压测配置
- 支持 100人瞬间爆发、每人7票、不同投票速度模拟
- 添加随机延迟函数模拟真实用户行为
- 强制 WebSocket 传输避免 HTTP 连接限制

前端修复:
- 修复 PostcardItem、PostcardDisplay 奖项名称硬编码问题
- 组件现在从后端 awards 配置动态获取奖项名称
- 修复 LiveVotingView、AdminControl 传递 awards 数据
- 新增 gala 压测命令到 package.json

测试验证:
- 100人并发压测通过,成功率 100%
- P95 延迟 0.7ms,远低于 500ms 阈值
- 系统可稳定支持 3.3 倍现场负载
This commit is contained in:
empty
2026-01-29 00:09:03 +08:00
parent 2f8bf0d755
commit 5c5d0ad85c
10 changed files with 329 additions and 89 deletions

View File

@@ -0,0 +1,156 @@
# ============================================================================
# 年会现场真实场景压测 - 节目投票瞬间爆发
# 场景节目结束后主持人宣布开始投票100人同时打开页面每人投7票
# ============================================================================
#
# 运行方式:
# artillery run vote-real-scenario.yaml -e live
#
# ============================================================================
config:
target: "http://127.0.0.1:3000"
# 性能阈值
ensure:
p95: 500
maxErrorRate: 1
# Socket.IO 配置 - 强制 WebSocket
socketio:
transports: ["websocket"]
path: "/socket.io"
extraHeaders:
Origin: "http://localhost:5174"
# 处理器脚本
processor: "./vote-processor.cjs"
# 7个节目ID和7个奖项票种一一对应
variables:
programIds:
- "p1"
- "p2"
- "p3"
- "p4"
- "p5"
- "p6"
- "p7"
ticketTypes:
- "creative"
- "visual"
- "atmosphere"
- "performance"
- "teamwork"
- "popularity"
- "potential"
# 环境配置
environments:
# 现场真实场景 - 100人同时涌入
live:
target: "http://127.0.0.1:3000"
phases:
# 阶段1: 瞬间爆发 - 100人同时进入主持人宣布投票开始
- name: "投票开始100人同时进入"
duration: 2
arrivalRate: 50 # 2秒100人 = 50人/秒,模拟瞬间爆发
# 阶段2: 投票高峰期 - 持续投票
- name: "投票高峰期"
duration: 45
arrivalRate: 5 # 维持连接,持续投票
# 阶段3: 投票结束
- name: "投票结束"
duration: 5
arrivalRate: 2
# ============================================================================
# 测试场景定义 - 模拟三种投票速度的用户
# ============================================================================
scenarios:
# 场景1: 快速投票者 (30%) - 2-3秒投完7票手速极快
- name: "快速投票者"
weight: 3
engine: socketio
flow:
- function: "generateUserId"
- emit:
channel: "connection:join"
data:
userId: "{{ userId }}"
userName: "快投-{{ userId }}"
role: "user"
department: "快速组"
# 快速投7票每票间隔 0.2-0.4 秒)
- loop:
- function: "selectSequentialTicket"
- function: "selectRandomProgram"
- emit:
channel: "vote:submit"
data:
candidateId: "{{ selectedProgram }}"
category: "{{ selectedTicket }}"
localId: "{{ $uuid }}"
- think: 0.3
count: 7
- think: 1
# 场景2: 正常投票者 (50%) - 10-15秒投完7票正常速度
- name: "正常投票者"
weight: 5
engine: socketio
flow:
- function: "generateUserId"
- emit:
channel: "connection:join"
data:
userId: "{{ userId }}"
userName: "正常-{{ userId }}"
role: "user"
department: "正常组"
# 正常速度投7票每票间隔 1-2 秒,看节目、思考)
- loop:
- function: "selectSequentialTicket"
- function: "selectRandomProgram"
- emit:
channel: "vote:submit"
data:
candidateId: "{{ selectedProgram }}"
category: "{{ selectedTicket }}"
localId: "{{ $uuid }}"
- function: "randomNormalDelay"
- think: "{{ normalDelay }}"
count: 7
- think: 3
# 场景3: 慢速投票者 (20%) - 30-40秒投完7票犹豫不决型
- name: "慢速投票者"
weight: 2
engine: socketio
flow:
- function: "generateUserId"
- emit:
channel: "connection:join"
data:
userId: "{{ userId }}"
userName: "慢投-{{ userId }}"
role: "user"
department: "慢速组"
# 先观望 5-10 秒
- function: "randomLongDelay"
- think: "{{ longDelay }}"
# 慢速投7票每票间隔 3-5 秒)
- loop:
- function: "selectSequentialTicket"
- function: "selectRandomProgram"
- emit:
channel: "vote:submit"
data:
candidateId: "{{ selectedProgram }}"
category: "{{ selectedTicket }}"
localId: "{{ $uuid }}"
- function: "randomSlowDelay"
- think: "{{ slowDelay }}"
count: 7
- think: 5