性能与自我保护
检测管线的单请求成本、全链路压测基线,以及过载卸载、检测失败放行、GC 与内存上限这些自我保护开关怎么调。
「WAF 会不会拖慢我的站点」是接入前最常问的一句。结论先给:检测引擎对每个请求的增量在十几微秒量级,相对反向代理转发本身可以忽略。这一页给出可复现的基线数据,以及过载卸载、检测失败放行这些「自我保护」开关该怎么调。
#检测管线单请求成本
一个正常请求走完「构建上下文 + 归一化 + SQLi/XSS 检测」的微基准(开发机、16 逻辑核、GOGC=200):
| 指标 | 值 | 说明 |
|---|---|---|
| ns/op | 约 13,500(13.5 µs) | 含测试框架构造请求与 recorder 的开销 |
| B/op | 约 10,100 | 每请求分配字节(同样含框架开销) |
| allocs/op | 约 70 | 每请求分配次数 |
检测本身的净成本远小于这个数——测试框架构造请求占了大头。
#全链路压测基线
并发 50、持续 8 秒,经完整数据面(检测 + 反向代理)打到 echo 上游:
| 指标 | 值 |
|---|---|
| 总请求 / 错误 | 257,683 / 0 |
| QPS | 约 32,200 |
| 延迟 p50 | 1.2 ms |
| 延迟 p90 | 2.8 ms |
| 延迟 p99 | 4.8 ms |
| 延迟 max | 6.7 ms |
端到端 p99 < 5 ms(含反代到上游的一跳)。瓶颈在代理转发与回环 I/O,不在检测引擎。
别把基线当承诺值这是开发机本地回环上的回归参照,绝对值随硬件、上游、配置而变。真正做容量规划请在目标硬件、真实上游、开启 Redis / MySQL 的条件下,用 wrk / vegeta / k6 自行压测——这里给的是量级和回归趋势。
#自我保护开关
| 字段 / 控件 | 默认 / 示例 | 说明 |
|---|---|---|
server.max_concurrent | — | 在途请求上限,超出直接返回 503 卸载。防的是过载雪崩——宁可快速拒绝一部分,也不要整体拖垮。 |
detection.fail_open | true | 检测引擎异常时放行。WAF 自身故障不该阻断业务,默认开启。 |
runtime.gogc | 200 | Go GC 触发比例。调高减少 GC 次数、多吃内存;内存紧张时调低。 |
runtime.mem_limit_mib | — | GOMEMLIMIT 软上限,给容器 / 小内存机器设一个天花板,避免 OOM Kill。 |
工程上还有两处默认优化:检测管线用对象池复用请求体缓冲;反向代理复用上游连接池。这两项无需配置。
#影响性能的配置项
- 接口缓存:命中即返回、不回源,是降延迟最有效的一项。见 接口缓存。
- 静态托管快速路径:真实静态文件就地发送、跳过检测管线。见 静态托管与 PHP FastCGI。
- 防篡改 enforce 模式:每请求逐文件哈希校验,有实打实的开销,性能敏感场景按需开。见 静态内容防篡改。
- 请求体检测窗口:只检测请求体前 N 字节,窗口越大越慢。大文件上传接口尤其要留意。见 检测引擎。
- 内核层封禁:把惯犯挡在三层,省掉 TLS 握手与 HTTP 解析,面对持续 CC 更省资源。见 违规累计封禁。
