遇到这种情况,首要任务不是调整数据库参数,而是先切断或清洗攻击流量,否则单纯增加数据库连接数只会加重服务器负担。
先说结论:优先在流量入口层拦截攻击,再限制数据库最大连接数防止雪崩,最后优化应用层重试机制。
- 先确认:通过监控确认是流量攻击导致的连接堆积,而非慢查询或代码死锁。
- 先处理:接入高防 CDN 或 WAF 清洗流量,临时调低数据库 max_connections 保护实例不宕机。注意:攻击期间严禁随意重启数据库,可能导致服务无法启动。
- 再验证:观察数据库活跃连接数回落,且业务报错频率显著降低。
命令速用版
如果数据库还能登录,先查看当前连接状态和来源:
mysql -u root -p -e "SHOW PROCESSLIST;" | wc -l
netstat -an | grep :3306 | grep ESTABLISHED | wc -l如果服务已无响应,可能需要重启服务释放资源(警告:仅在实例完全无响应且无法通过其他方式恢复时尝试,并做好业务中断准备):
systemctl restart mysqld
systemctl restart nginx为什么会这样
DDoS 攻击会产生大量并发请求,Web 服务器为了处理这些请求,会向数据库发起大量连接。当并发数超过数据库配置的 max_connections 上限,或者超过服务器硬件能处理的线程极限时,新的连接请求就会进入等待队列。一旦等待时间超过应用设置的 timeout 阈值,就会报连接超时错误。此时数据库本身可能并没有宕机,只是“忙不过来”。
分步处理
1. 流量层清洗(最优先)
不要试图在源站服务器上硬抗流量。如果正在遭受攻击,立即将域名解析切换到带有 DDoS 防护能力的 CDN 或 WAF 服务。隐藏源站 IP,让攻击流量打在防护节点上。
2. 限制数据库连接
登录数据库,临时调低最大连接数,防止数据库进程因资源耗尽而崩溃。例如设置为正常值的 50%-80%,保留一部分资源给管理连接。
-- 临时调整(重启失效,需 root 权限)
SET GLOBAL max_connections = 500;
-- 永久调整需修改配置文件 /etc/my.cnf
-- [mysqld]
-- max_connections = 5003. 优化 Web 服务器配置
在 Nginx 等反向代理层限制单个 IP 的请求频率,减少无效请求到达后端。注意配置位置:
# nginx.conf http 块中
http {
limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s;
}
# server 或 location 块中
server {
location / {
limit_req zone=one burst=20 nodelay;
}
}4. 检查应用层重试
检查代码中是否有无限重试机制。如果数据库超时,应用层不应立即高频重试,否则会造成“重试风暴”,加剧数据库负担。
5. 防火墙白名单配置(源站防护)
确保数据库端口只允许 CDN 回源 IP 或内网访问,防止攻击者绕过 CDN 直连源站。查询云厂商文档获取 CDN 回源 IP 段。
# iptables 示例:只允许特定 IP 段访问 3306
iptables -A INPUT -p tcp `--dport` 3306 -s CDN_IP_SEGMENT -j ACCEPT
iptables -A INPUT -p tcp `--dport` 3306 -j DROP怎么验证是否生效
1. 查看数据库监控面板,活跃连接数(Active Connections)是否稳定在设定阈值以下。
2. 查看 Web 服务器错误日志,确认"Connection timed out"相关的报错频率是否下降。
3. 使用 SHOW STATUS LIKE 'Threads_connected'; 观察连接数波动情况。
常见坑
1. 盲目调大 max_connections: 在遭受攻击时,调大连接数会让数据库尝试处理更多请求,导致 CPU 和内存瞬间飙升,可能直接导致实例宕机,反而彻底不可用。
2. 忽略慢查询: 有时候攻击是针对特定接口,触发慢查询,占用了连接线程。需要结合慢查询日志分析。
3. 源站 IP 泄露: 如果攻击者知道你的源站 IP,他们会绕过 CDN 直接攻击 IP。务必确保防火墙只允许 CDN 节点 IP 访问数据库端口。
4. 攻击期重启风险: 攻击高峰期重启数据库可能导致服务无法启动或被瞬间再次打挂,非必要不重启。
5. 连接数限制过严: 临时调低连接数可能导致正常用户也被拒绝服务,需结合监控动态调整。