大促当天流量翻十倍,防护阈值和白名单要是没提前动,结果不是误封真实用户,就是放跑混在洪峰里的攻击。本文用 10 个问答讲清大促前的准备时间表、报备要写什么、阈值怎么算、压测流量怎么放行与回收。
Q:为什么大促期间 CC 防护最容易出事?
- 因为两个方向的错误会同时发生,而且互相掩护。
- 一边是阈值按平峰配的:日常 50 QPS 就限流,活动一来正常用户先被 429,客服电话当天就炸。
- 另一边是为了不误封把规则调到形同虚设:攻击正好混在洪峰里,你分不清哪个是抢购的真人、哪个是刷接口的脚本,等于给攻击者开了窗口。
- 根子在于大促流量的特征和 CC 攻击高度重叠:短时高并发、路径高度集中、大量新 IP。这三点既是活动特征,也是攻击特征。
- 所以核心不是”把阈值调大”,而是分层:最贵的接口单独隔离限流,可缓存的页面全推到边缘,让洪峰到不了源站。
Q:提前多久开始准备?时间表怎么排?
- 按 T-14 倒排,每个节点只做一件事,别堆到前一天:
- T-14 压测:压出活动页面的真实 QPS 上限。取 CPU 打到 70% 时的 QPS,不要压到报错为止,那个数没有余量。
- T-7 报备:把活动时间、预估峰值、主要入口路径、源站变更,正式提交给 CDN/WAF/高防供应商,拿到工单号。
- T-3 配置:阈值、白名单、缓存规则改完并灰度上线。静态资源预热,别等开抢才回源。
- T-1 冻结:停止结构性变更,只保留回滚能力。值班表和升级路径确认到人。
- 当天:只调参数,不改结构。改配置结构是事故高发动作。
- T+1 回收:临时策略按顺序撤,别留着过年。
Q:向防护供应商报备,具体要写清哪些内容?
- 报备不是打个招呼,是让对方的值班同学能在凌晨三点看懂你要什么。七项缺一不可:
- 活动起止时间:精确到分钟,标明时区。跨零点的活动最容易出问题。
- 预估峰值:QPS、带宽(Mbps)、独立 IP 数,给区间不给单点。
- 主要入口路径:列表页、详情页、下单接口、秒杀接口,逐条列出。这是对方配规则的基础。
- 源站可承受上限:超过之后希望怎么处理,是限速、排队还是返回活动结束页。你给指令,对方照做。
- 紧急联系人:手机号,不要只留工单系统。工单在攻击中是慢的。
- 白名单 IP 段:压测机、拨测节点、办公出口,逐条注明用途和到期时间。
- 临时放宽项:写明规则 ID、放宽幅度、到期时间。只写”放宽 CC 防护”是最容易被拒的表述。
Q:阈值到底怎么上调?有没有可用的算法?
- 有,用两段式计算,两头都要卡住:
- 日常阈值 = 压测 QPS 上限 × 0.7,留 30% 余量给突发。
- 活动阈值 = 活动预估峰值 × 1.3,但不得超过源站上限 × 0.85。前者防误封,后者防打穿。
- 最容易犯的错是只调边缘不调源站:CDN 放过来了,源站自己的
limit_req还是平峰配置,结果边缘显示 200,用户那边 503。 - 边缘和源站要同时动,并且源站桶要比边缘松一档,让边缘先拦,源站兜底。
# 活动接口单独开桶,与全站限流隔离
limit_req_zone $binary_remote_addr zone=act_api:20m rate=30r/s;
limit_conn_zone $binary_remote_addr zone=act_conn:10m;
location = /api/seckill {
limit_req zone=act_api burst=60 nodelay;
limit_conn act_conn 20;
limit_req_status 429;
limit_conn_status 429;
proxy_read_timeout 10s; # 活动接口不要长等,快速失败比拖死好
}
location / {
limit_req zone=global_api burst=20 nodelay;
}
Q:压测流量怎么放行,又不留后门?
- 核心原则:白名单只放”人”,不放”路径”。全站对一个 IP 段放行,等于把限流关掉一半。
- 三个条件同时满足才认:专属 UA + 自定义头签名(HMAC + 时间戳,5 分钟过期)+ 来源 IP 段。
- 规则要带到期日,文件命名就用日期,再用 cron 自动清理。靠人记着删的白名单,最后都会变成永久后门。
# 压测放行:UA + 签名头双条件
map "$http_user_agent|$http_x_loadtest_sig" $is_loadtest {
default 0;
"~*LoadTestBot/1\.0\|[a-f0-9]{32}" 1;
}
map $is_loadtest $limit_key {
0 $binary_remote_addr;
1 "";
}
server {
# limit_key 为空时不进桶,即豁免限流
limit_req zone=global_api burst=20 nodelay;
limit_conn act_conn 20;
}
# 每日 03:00 清理过期白名单并校验配置
0 3 * * * find /etc/nginx/conf.d/whitelist -name '*.conf' -mtime +7 -delete \
&& nginx -t && nginx -s reload
- 压测结束后当天就撤,不要等”活动结束一起清”。压测机半年后可能已经换主人了。
Q:活动页面怎么配才抗得住洪峰?
- 思路一句话:让能缓存的都不回源,让必须回源的都便宜。
- 列表页、详情页做整页缓存(CDN 边缘 + nginx 本地两级),TTL 短一点没关系,关键是命中率要顶住。
- 价格和库存这类动态数据用接口单独拉,走片段缓存或短 TTL,不要因为一个库存数字让整页不缓存。
- 下单和秒杀接口不能缓存,只能”限流 + 排队 + 令牌”,并且要能快速失败,别让它拖住连接。
- 静态资源独立 location,绕开 PHP,顺手把日志关掉,减少 IO。
location ~* \.(js|css|jpg|jpeg|png|webp|woff2|svg)$ {
expires 7d;
add_header Cache-Control "public, immutable";
access_log off;
open_file_cache max=10000 inactive=60s;
}
Q:临时白名单会不会变成绕过口子?
- 会,而且这是活动期最常见的安全债。判断标准很简单:这条规则有没有到期时间、有没有责任人。
- 每条临时豁免必须绑三样:IP + 路径 + 时间窗。只写 IP 的豁免,在攻击者拿到这个 IP(比如复用的云主机、被入侵的办公出口)时就是一条后门。
- 统一放在单独目录、单独 include,活动结束直接删目录再 reload,比在几十条规则里找要可靠得多。
- 常见情况:去年活动加的白名单没人撤,今年还在生效,而那个 IP 早换了用途。定期
grep一遍allow和map,比出事后再查快。
Q:活动期间盯哪几个数?看板怎么摆?
- 业务指标放最上面,技术指标放下面。老板只看前四个,运维看后四个:
- 下单成功率、支付转化率:真指标,掉了就是真出事,不用解释。
- 429/403 比例:超过 1% 说明阈值偏紧,正在误封真人;低于 0.05% 且攻击特征明显,说明阈值太松。
- P95 + 源站 CPU:先看 CPU 再看 QPS。QPS 涨 CPU 没涨说明缓存生效;CPU 先满说明缓存穿了。
- 缓存命中率:掉 10 个百分点就要查回源,洪峰期缓存击穿比攻击更致命。
- 单 IP 请求分布 Top10:活动期正常用户的分布是长尾的,如果 Top10 突然变得很均匀、量都很大,那就是攻击。
Q:真攻击和真洪峰同时来,怎么分、怎么处置?
- 分三条看,五分钟内能定性:
- 路径分布:洪峰符合活动设计(列表页 → 详情页 → 下单),攻击只打最贵的那一个接口,前后不连贯。
- 资源加载:真人会拉 js/css/图片,Referer 正常;脚本通常只请求接口,静态资源占比极低,Referer 为空。
- 转化数据:洪峰的转化率落在预期区间,攻击的请求转化率为 0,而且下单参数高度雷同。
- 处置原则一条:先保下单链路。其余接口(评论、推荐、搜索)一律降级到静态页,把资源让给主链路。
- 别在这个时候做大范围封 IP。洪峰期的误封代价是真实的GMV,宁可限速也不要硬封。
Q:活动结束后怎么收尾?
- 按”从内到外”回收,每步间隔 24 小时,边收边看指标:
- 第一步撤压测白名单和临时豁免,这两类最危险,先撤。
- 第二步把活动接口的独立桶降档回日常值,观察 429 比例有没有异常上升。
- 第三步把边缘的 CC 阈值降回基线,同时确认源站桶也一起降。
- 最后出一页复盘,只写四个数:峰值 QPS、拦截量、误封量、最大处置耗时。下次活动直接拿这页当输入。
- 活动期日志保留 30 天。真要追刷单、追恶意竞争,证据全在这段时间的日志里。