案例 · 在线教育大促日 50× 流量,AI 客服扛住的工程笔记
一家在线编程教育公司在 618 大促期间 24 小时承接 12 万咨询,AI 自助率 81%。工程团队怎么提前压测、限流、降级。
背景#
- 业务:成人在线编程教育
- 平时月均会话:~25k
- 618 大促当天:~120k(48× 平常)
- 团队:12 个客服坐席 + 2 个工程师
- 技术栈:Chatwoot + Dify + FastGPT + n8n(教育行业方案 的实例)
大促前的担忧#
平时跑得好好的系统,大促必爆。历史教训:
- 2024 年 618:客服系统挂了 4 小时
- 2025 年双 11:Dify 知识库检索延迟从 200ms 飙到 8s
- 2025 年 618:人工坐席堆积,平均响应 40 分钟
2026 年 618 上线 AI 后第一次大促,团队的目标:
- AI 自助率 > 70%
- 首响时间稳定 < 5 秒
- 全天 0 宕机
- 转人工的 < 30%
大促前 6 周准备#
Week 1:基准压测#
用 Locust 模拟流量:
| 并发用户 | 是否撑住 |
|---|---|
| 500 | ✓ |
| 1,000 | ✓ |
| 2,000 | ⚠ 首响 5s |
| 5,000 | ✗ Dify worker OOM |
| 10,000 | ✗ Postgres 连接耗尽 |
目标:10,000 并发稳定。
Week 2:基础设施扩容#
- Chatwoot:1 节点 → 3 节点(K8s HPA)
- Dify worker:副本 2 → 12
- Postgres:升级到 8C/16G,连接池 PgBouncer
- Redis:升级到 16GB
- 加 Cloudflare 前置(CDN + Turnstile 反 bot)
Week 3:知识库重构#
平时知识库 800+ 条 FAQ,但大促会有「秒杀」「拼团」「优惠码」等新条目。提前一周做:
- 加 200+ 大促专项 FAQ
- 用评估集回归(MRR@5 从 0.87 调到 0.91)
- 加「未匹配 → 模板回复 + 转人工」兜底
Week 4:降级方案#
写了 3 级降级:
| 触发条件 | 行动 |
|---|---|
| Dify QPS > 80 | 启用更快但更便宜的 DeepSeek-V3(替代 Qwen-72B) |
| Dify QPS > 150 | 启用「热门 FAQ 缓存」(Redis 缓存 top 100 问答) |
| Dify QPS > 250 | 启用「降级答案」(用 AnythingLLM 兜底,质量稍低但不挂) |
每级降级有自动告警 + 人工确认机制。
Week 5:限流与熔断#
n8n 加了多层限流:
- 单 IP 每分钟 30 次(防 bot)
- 单 user_id 每分钟 10 次
- 全局 Dify QPS 300
- 业务 API(订单查询)每秒 200,超出排队
- LLM tokens 月度上限:触发后强制走缓存
Week 6:演练#
模拟实战:
- 周一全天压测(10,000 并发持续 4 小时)
- 故意 down 一个 Dify 副本看自动恢复
- 故意把 Postgres 主切到备机
- 演练「客服全员收到限流告警」流程
发现 3 个问题,都改了。
大促当天数据#
流量曲线#
00:00 - 09:00:缓步上升,10k 累计
09:00:开抢,瞬间 500 QPS
09:00 - 09:30:峰值 1,200 并发
09:30 - 12:00:平台期,500-800 并发
12:00 - 18:00:下午波动,300-600 并发
18:00 - 22:00:第二波小高峰,700 并发
22:00 - 24:00:缓降
全天累计:121,400 会话。
AI 表现#
| 指标 | 目标 | 实际 |
|---|---|---|
| AI 自助率 | > 70% | 81% |
| 首响时间(平均) | < 5 秒 | 1.8 秒 |
| 首响 P95 | < 8 秒 | 4.2 秒 |
| 首响 P99 | < 15 秒 | 9.8 秒 |
| 转人工率 | < 30% | 19% |
| 系统宕机 | 0 | 0 |
全部超额完成。
降级实际触发#
- 09:05 触发「热门 FAQ 缓存」(提前 25 分钟)
- 09:13 触发「DeepSeek 替代 Qwen」(持续 47 分钟)
- 没触发最严重的「AnythingLLM 兜底」
降级期间数据质量略下降:CSAT 从 4.4 降到 4.2,用户感知不显著。
当天事件复盘#
09:14:Chatwoot Sidekiq OOM#
症状:工单创建变慢,Chatwoot 后台报 Sidekiq 队列积压。
原因:Sidekiq 默认队列处理 N8n 大量 webhook,加之有些 webhook 慢响应。
应急:临时把 Sidekiq 并发从 25 拉到 60,2 分钟恢复。
事后:拆出独立 Sidekiq 进程专门处理 webhook,主进程只处理工单。
13:42:LLM 偶发幻觉#
症状:客服坐席发现 5 条 AI 回复编造了不存在的「优惠码」。
应急:n8n 加了一个简单的「优惠码列表」过滤——AI 回复中的优惠码必须在合法列表里,不在则替换为「请咨询人工」。
事后:把 Prompt 改成「优惠码必须从 {{valid_codes}} 列表选,禁止编造」+ 后置校验。
19:23:Cloudflare Turnstile 误杀#
症状:部分用户反馈聊天框打不开。
原因:Turnstile 的「自动 challenge」对某些移动浏览器太严格。
应急:临时把 Turnstile 切到「invisible」模式。
事后:Turnstile 用户感知方面加更明确的提示。
大促后客户反馈#
抽样调查 500 个客户:
- 68% 表示「AI 客服比预期好」
- 22% 表示「跟以前一样」
- 7% 表示「明显感觉是机器」(主要不满集中在「不会推荐课程」)
- 3% 投诉「响应太快反而觉得敷衍」(罕见但真实)
5 个最重要的工程经验#
- 提前 4 周压测:留足时间发现瓶颈和修复
- 降级而不是熔断:宁可服务质量略降也不要直接挂
- 缓存比扩容性价比高:top-100 热门 FAQ 缓存挡了 60% 的 LLM 调用
- Prompt 防御编程:每个可能编造的字段都加白名单校验
- 演练「人也会出问题」的预案:客服全员收到告警时该做什么、谁拍板降级——预先约定好
与「平时」的成本对比#
| 项 | 平时 | 大促日 |
|---|---|---|
| LLM tokens | $40 | $580(缓存替代后只多 14×) |
| 基础设施扩容 | — | $200(K8s 临时副本) |
| 工程加班 | — | $1,200(2 人 × $300 × 2 天) |
| 大促日单日合计 | — | ~$2,000 |
对比 121,400 会话价值带来的 GMV 增量(保守估 ¥800,000),ROI 约 56×。
下次还要改的#
- 真正「队列式」客服:高峰时让用户排号而不是无止境等回复
- 移动端 push:客户可以「先关闭,回复来了通知我」
- LLM-as-judge 提前 1 周开始预热知识库