半夜报警带宽打满?这3个救命招数我用了五年

那时我还年轻,把手机铃声设置成最刺耳的“核警报”音效,生怕漏掉任何一个监控报警。

哪怕现在回想起来,那种凌晨3点被震醒,看到监控群里赫然写着 “出口带宽占用率:100%” 的绝望感,依然能让我指尖发麻。那时的第一反应往往是懵的:是被DDoS攻击了?还是代码写了死循环?或者是运营搞了什么大动作没通知我?

我曾经以为,只要服务器配置够高、带宽买得够大,就能高枕无忧。直到我在2019年的那次大促中,眼睁睁看着升级了三倍的带宽依然在两分钟内被吞噬殆尽,才明白了一个道理:带宽永远是稀缺资源,靠“硬抗”不仅费钱,而且无效。

如果你现在也正对着那条“心跳停止”般的平直线条焦虑,请深呼吸,喝口水。这不是世界末日,我们都有过这样的时刻。这里有三个我这几年反复验证过的应急与复盘经验,希望能陪你度过这个难关。

谁在“偷吃”你的带宽?别猜,去抓现行

当你发现带宽打满,SSH登录都卡顿时,千万别急着重启服务器。重启也许能缓解这一分钟,但五分钟后噩梦通常会卷土重来。我们需要的是像侦探一样,揪出那个“流量大户”。

记得有次帮一家电商客户排查,他们的带宽突然从50Mbps飙升到500Mbps。老板急得在电话里吼,怀疑是竞争对手搞DDoS。

我强迫自己冷静下来,虽然SSH操作很卡,但我还是敲下了 iftop

经验之谈:如果服务器卡到无法安装软件,请务必提前在镜像里装好 iftopnethogs 这类工具。这就像灭火器,平时占地方,用时救大命。

屏幕上瞬间跳动的数据让我大跌眼镜:没有任何外部攻击IP,流量全是一个内部备份脚本跑出来的。 原来是新来的运维小哥把备份时间设错了,几百G的日志文件正在疯狂往备用机房传输,直接挤占了业务出口带宽。

那一刻的教训是惨痛的: 我们总习惯把锅甩给“黑客”,却往往忽略了“内鬼”或“配置漂移”。

如果你能登录服务器,立刻执行以下操作查看实时流量:

# 查看网卡流量实时状况,按带宽占用排序
iftop -P -N -n

如果发现某个IP异常高,再配合Nginx日志确认由于什么请求导致:

# 实时分析Nginx日志,找出请求流量最大的前10个IP
tail -n 10000 /var/log/nginx/access.log | awk '{print $1}' | sort | uniq -c | sort -nr | head -n 10

配图

看到结果的那一刻,焦虑感通常会消退一半,因为未知才是恐惧的根源。

止血第一,治疗第二:该“砍”就得“砍”

找到了元凶,接下来就是最艰难的决策时刻:止血

很多技术同学(包括曾经的我)在这时候容易陷入“完美主义”陷阱,试图通过优化代码、调整内核参数来优雅地解决问题。但在此刻,业务可用性高于一切

那是2020年的一个周五下午,我正准备收拾东西过周末,一家做短视频资讯的客户突然炸锅了。某个爬虫团队发现了他们未鉴权的视频接口,几千个肉鸡IP疯狂下载视频文件,带宽瞬间打满,正常用户连图片都刷不出来。

由于IP极其分散,传统的封IP效率极低。看着用户群里的谩骂,我做了一个违背“技术优雅”的决定:直接在反向代理层,临时把所有视频请求返回404或者降级为一张静态占位图。

虽然这意味着那一小时内,用户看不了视频,但至少App的文字内容、图片加载恢复了正常,核心功能保住了。

“在急诊室,医生会先止血,再考虑缝合得漂不漂亮。”

操作建议: 如果确认是恶意爬虫或非核心业务占用了带宽,不要犹豫:

  1. 封锁入口:利用安全组(Security Group)或 iptables 直接丢弃特定端口或IP段的包。
  2. 服务降级:在Nginx层直接对大文件请求返回 503 或 404,或者限速。
# Nginx 紧急限速配置示例
location /download/ {
    limit_rate 100k; # 限制每个连接的速度
    limit_conn addr 1; # 限制并发连接数
}

那一晚,虽然我们损失了部分视频播放量,但没有造成全站瘫痪。事后复盘,老板反而感谢了我的果断。

哪怕再小的图片,也请搬出服务器

这是我这五年里最深刻的感悟,也是想送给所有架构师的一句话:服务器是用来计算的,不是用来发文件的。

早期做项目,为了图省事,我习惯把用户上传的头像、Banner图直接存在服务器本地磁盘,让Nginx直接吐出去。随着用户量增长,这个隐患就像定时炸弹。

配图

有一次,一个简单的H5营销页面火了。页面只有一张背景图,大小是2MB。看似不大,但当并发达到1000QPS时,需要的带宽是 2MB * 1000 * 8 = 16Gbps。 这根本不是普通云服务器能承受的量级。哪怕我们扩容了服务器,CPU闲得发慌,带宽却早已窒息。

从那以后,我有了一个雷打不动的习惯:无论项目多小,静态资源(图片、JS、CSS、视频)一律上对象存储(OSS/S3)+ CDN。

这不仅是性能问题,更是成本问题。CDN的流量费比服务器带宽便宜太多,而且它天然能抗流量洪峰。

怎么落地? 如果你的旧系统还在本地存文件,不用推倒重来,可以采用“回源”策略:

  1. 配置CDN域名指向你的服务器;
  2. 代码里把图片链接替换为CDN域名;
  3. 用户访问CDN -> CDN没缓存 -> 回源抓取服务器文件 -> CDN缓存住。

当你把90%的流量卸载给CDN后,你会发现,哪怕服务器带宽只有5Mbps,跑起来也像飞一样轻盈。


写在最后:给未来的自己留个锦囊

技术这条路,就是在不断的“填坑”中成长的。现在的焦虑和手忙脚乱,终将成为你简历上最亮眼的一笔“高并发实战经验”。

我不希望你再次半夜惊醒,所以分享一个我常用的Nginx日志快速分析脚本模板,建议你保存在笔记里,或者做成服务器上的别名命令(alias):

急救排查三板斧(复制即用):

  1. 看谁在连你(查当前并发最多的IP):
    netstat -ntu | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -nr | head -n 10
    
  2. 看谁流量大(查日志里传输字节数最大的请求):
    # 假设日志格式最后一列是body_bytes_sent
    cat access.log | awk '{print $10 " " $1}' | sort -nr | head -n 10
    
  3. 一键封锁(慎用,针对单点恶意IP):
    iptables -I INPUT -s <恶意IP> -j DROP
    

接下来的行动建议:

  • 明天上班第一件事:检查你的静态资源,是不是还在走服务器带宽?如果是,提个工单计划迁到CDN吧。
  • 本周内:在服务器安装好 iftopdstat 等监控工具,别等出事了再临时 yum install
  • 心态上:接受故障的发生。服务器带宽打满,说明业务在增长(或者是被关注),这是“幸福的烦恼”。

哪怕天塌下来,服务器还能重启,生活也还得继续。今晚,愿你的监控曲线平稳如水,好梦。