
那是一个普通工作日的早上,
监控突然炸了,电话预警响个不停,机器人通知也一个劲儿地弹消息。
服务没挂,
网络也正常,
但服务器 CPU 直接干到了 100%!
服务时通时不通,
用户疯狂反馈“加载失败”,
反正——就是用不了。
网络错误:timeout
还没定位完,开发童鞋就来问:“是不是你又把服务弄挂了?” 我:?????
我手都没碰服务器,监控刚响我就在查了!
登录服务器检查有没有异常
netstat -an | grep ESTABLISHED | wc -l发现系统存在大量网络连接,明显不正常。
查看nginx日志
awk '{print $1}' access.log | sort | uniq -c | sort -nr | head看到好几多IP短时间内发起了过万次请求。 第一反应被恶意攻击了,虽然处理起来不复杂,但足够让没准备的人喝一壶的。
我干了啥?
先让服务恢复
location /aaa-api/ {
deny 异常IP;
# 其他配置...
}但这只是临时解法—— 不能每次都靠手动封 IP,太被动了。
http 块里加:
# 限制每个 IP 的并发连接数
limit_conn_zone $binary_remote_addr zone=a2:10m;
# 限制每个 IP 的请求频率(每秒最多 5 次)
limit_req_zone $binary_remote_addr zone=a1:10m rate=5r/s;在 location 里配置:
location /aaa-api/ {
# 允许突发 30 次,超出直接拒绝
limit_req zone=a1 burst=30 nodelay;
......................
# 其他配置...
}$binary_remote_addr # 按客户端 IP 统计zone=conn:10m # 分配 10MB 内存存储连接状态rate # 每秒处理请求数burst # 允许的突发请求数结果:
限流一上,前几十个请求正常响应,超出的会报错
再看服务器 一点压力没有,稳如老狗
我理解Nginx 判断是否超限的依据是:
请求频率 >
rate + burst
例如:
rate=5r/s
burst=30
这意味着:
5 + 30 = 35 个请求所以:如果一次性发起 50 个并发请求,前 35 个可能被处理或排队,后 面的就会报错

后面计划写个自动化脚本,自动分析日志,识别异常访问 IP 发送通知给我并实时拉黑,实现半自动化防御
仅此记录一下,下次再遇到不用慌。
如果你有更好的法子,求教!