429 too many requests 是 ddos 应急时最该快速看到的响应码——它意味着限流已生效;需分层防护、绑定真实标识(如 api_key)、用 redis+lua 原子限流、科学配置连接池与超时,否则配置再全也白搭。

429 Too Many Requests 是 DDoS 应急时最该快速看到的响应码——它意味着限流已生效,而不是数据库在报 MySQL server has gone away 或 PHP 进程在疯狂 fork。
应急不是加个中间件就完事,而是分层卡住:先拦住无效请求,再防住连接耗尽,最后保住数据库不雪崩。
PHP 层限流必须绑定真实标识,不能只靠 IP
攻击者用代理池或 botnet 时,$_SERVER['REMOTE_ADDR'] 会失效。直接按 IP 限流等于形同虚设。
- 优先取
X-Forwarded-For头(但需 Nginx/HAProxy 显式信任上游);更稳妥的是结合user_id(登录态)或api_key(调用方凭证)做标识 - Yii 框架用
yii\filters\RateLimiter时,重写getRateLimit()和loadAllowance()方法,把 key 构造成api_key:hour而非ip:minute - 存储后端必须用 Redis,且 Lua 脚本原子执行(避免并发计数错乱),示例 key:
rate:abc123:2026073010 - 阈值别拍脑袋:若单接口峰值 QPS 是 200,设为 300 并启用滑动窗口(不是固定窗口),否则整点瞬间会突刺打穿
数据库连接池配置错误比没配更危险
PHP 本身没有原生连接池,所谓“配池子”,实际是三种互斥路径:持久连接、ProxySQL、Swoole 协程池。混用会叠加故障。
- 用
PDO::ATTR_PERSISTENT => true时,事务未提交或临时表残留会污染下一个请求——线上偶发数据错乱,八成是这个原因 - ProxySQL 是唯一能真正控连接总数的方案:PHP 改连
localhost:6033,然后在 ProxySQL 里设max_connections=150,并查stats_mysql_connection_pool表监控ConnUsed是否长期 >90% - Swoole 协程池只适用于常驻进程场景(如
Swoole\Http\Server),且必须用Swoole\Coroutine\MySQL客户端,PDO或mysqli在协程里会阻塞 - 连接池最大数不能硬写 200:按公式算——
(CPU 核心数 × 2 + 磁盘数) × 系数,读多写少用 2.5,写密集用 1.2;再乘以安全系数 0.7
连接等待超时必须设成可感知的数值
连接池里 max-wait 设成 30 秒?那用户等满 30 秒才收到 500,根本不是应急,是拖延。
- 建议设为
3000(3 秒),超时直接返回503 Service Unavailable,前端可自动降级或切备用通道 - 如果监控发现平均等待时间持续 >100ms,说明连接数已不足,不是调大
max-wait,而是要扩容或优化慢查询 - 别依赖
wait_timeout做兜底:MySQL 的wait_timeout默认 8 小时,它只管空闲连接断开,不管你在排队等连接
ConnActive 长期满载却没人看监控,或是限流 key 用了不可信的 REMOTE_ADDR 导致放行了全部攻击流量。这些点不盯死,配得再全也白搭。php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











