当服务器带宽被占满,第一反应别急着加钱升级,先按顺序排查这四类对象:活跃TCP连接、半开连接、突发流量源和本机异常进程,八成的问题在源头就能解决。
你在办公室里上网,视频会议卡成幻灯片的时候,客服那边是不是已经骂声一片了?家里断网你能重启路由器,可机房里的服务器要是带宽被占满,客户那边直接就是白屏和超时,更头疼的是,你花钱问IDC(互联网数据中心)运营商买了100M独享带宽,结果每两周就有一晚“周期性抽风”,查遍了防火墙规则,封了一堆IP,流量监控图还是像心电图一样乱跳,这篇文章不是教你按F5刷新,而是给你一套能实操的排查顺序和回收手段,看完你至少能自己找出七成以上的“内鬼”。
无效连接从哪里来
带宽是花钱买的,但用户访问是真的,没用的连接也是真的,无效连接不都是黑客,相当一部分是你自己系统里那些“占着茅坑不拉屎”的老旧连接。
半开连接与TIME_WAIT的堆积
你和别人握手,手伸出去对方半天不回应,你就僵在那了,TCP协议里的半开连接就是这么回事,客户端发了个请求包,服务器回了确认包,结果客户端那头突然断网了,这个连接就挂在内存里等超时,这种连接既没传数据,也不释放,攒多了就把TCP端口占满了,新请求进不来,而带宽呢?还没到瓶颈呢,连接数先爆了。
每个TCP连接在关闭后,还会进入一个叫TIME_WAIT的状态,持续两分钟,这是协议为了确保最后一个ACK能送达而设的,高并发网站就算业务正常,服务器的TIME_WAIT数量也可能上万,这些连接虽然不再传数据,但依然占用着系统资源,间接拖慢了新连接的握手速度,让你觉得带宽不够用。
本机进程的“私活”与异常外联
有时候业务访问量根本不大,带宽却跑满了,你得怀疑是不是服务器上某个进程在干私活,比如被植入的挖矿程序会持续对外发送数据,某些开源组件有默认的更新服务在后台拉取大体积依赖包,甚至同事在服务器上挂了一个下载任务,这类流量特征很尖锐,通常集中在某几个固定端口上。
带宽被无效连接占满怎么办
这个问题的答案分三步走:先看连接表定位异常,再清掉垃圾连接,最后把防再次发生的策略写进配置里。

服务器带宽跑满排查方法:用命令看穿网卡
别急着进云控制台看监控,先在你自己的Linux机器上敲命令,这是判断问题最直接的路径。
第一步,确认带宽是否真的跑满:
iftop -i eth0 -n -P
这个界面会实时显示每个IP的流量速率,按大写的T键可以排序,看到某个陌生IP持续占用超过70%的带宽,恭喜你找到了嫌疑对象。
第二步,查连接状态分布,判断是正常并发还是连接堆积:
netstat -an | awk '{print $6}' | sort | uniq -c | sort -n
你大概率会看到两种情况,一种是TIME_WAIT数量上万甚至几十万,说明端口资源吃紧,另一种是SYN_RECV特别多,那就要小心流量攻击了,这里的排查关键是看ESTABLISHED数量,如果它本身只有几百,带宽却接近跑满,基本可以断定是流量型攻击,而不是合法用户访问。
第三步,看具体是哪些IP在消费连接或流量:
netstat -ant | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -n
重点关注那些单个IP建立了几百上千条连接的情况,正常浏览器顶多同时开六条左右连接。
回收操作:手动清理与内核参数调优
确定有大量TIME_WAIT堆积后,你当然可以重启服务或者干等它自己超时,更稳妥的做法是调整内核参数,让系统更快回收这些垃圾连接,编辑/etc/sysctl.conf,加入这几行:
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_max_tw_buckets = 10000
注意,网上很多旧教程让你开启tcp_tw_recycle,这里明确提一下,这个参数在Linux 4.12内核版本后已被移除,因为它会引发NAT环境下连接错乱的问题,说完这个坑,执行sysctl -p让参数生效。
如果是SYN_RECV半开连接太多,那是被SYN Flood(同步洪泛攻击)盯上了,可以把net.ipv4.tcp_max_syn_backlog调大,并开启net.ipv4.tcp_syncookies = 1来抵御,配合防火墙规则,限制单个IP的连接创建速率:
iptables -A INPUT -p tcp --syn -m limit --limit 500/s --limit-burst 100 -j ACCEPT

应用层超时也要管
系统层面清了,应用层的连接也可能挂在那儿,拿最常见的Nginx来举例,默认的keepalive_timeout如果设成75秒,那就意味着一个没事故意挂着页面的用户,会占用75秒不让连接断开,你可以适度调短:
keepalive_timeout 20;
client_body_timeout 10;
reset_timedout_connection on;
这几个参数的意思是:20秒没有新请求就断开保持连接,请求体10秒没传完就断开,超时连接直接重置,这样能有效释放被无意义占用的内存和文件描述符。
确认核心嫌疑:对比正常时段的流量图
操作做完,趋势图多半会降下来一大截,如果流量还是满的,那就不是连接的问题,而是确实有大流量在跑,用nethogs eth0可以按进程查看流量占用,看到某个PID在疯狂上传,你再顺着PID去查是哪个服务,处理命令就是kill -9加删掉对应的服务配置文件。
是升级带宽还是先治理:成本与策略
很多老板上来就问机房销售“带宽升级到200M多少钱”,这种问法很容易多花钱,不如先做个测试,看看是峰值瞬间冲高还是持续跑满,如果是瞬间冲高,无论你买多少带宽都可能不够,因为峰值总会超,这时候应当考虑分流而不是扩容。
CDN和裸IP直连哪个更省带宽
静态资源直接由源站IP输出,是最费昂贵带宽的做法,一个2M的图片被访问一百次,就要付出200M的流量成本,使用CDN的节点缓存后,源站只回源一次,你能省下约九成的静态流量,一个冷知识是,许多服务商的总带宽是共享的,你的机器深夜也会被扫描器扫到,产生大量看似来自搜索引擎但实际是漏洞扫描的流量,这部分流量并不因为你的带宽大就消失,反而会持续占用连接数,行业共识认为接入CDN做一层前置防护,比单独扩容源站带宽性价比高得多,尤其是对静态资源占比大的站点而言。
企业带宽升级多少钱:别忽略地域差异
如果你非要走升级路线,各大数据中心的价格差异不小,以中国大陆的BGP带宽为例,同一家运营商,上海机房带宽价格通常会比北方某些二三线城市机房贵大约30%到40%,因为华东区域的网络节点多、延迟要求高,但很多南方企业选择湖南或贵州的机房,价格能低一半,延迟也就多十几毫秒,如果你的用户群体就在江浙沪,那上海机房的低延迟值这个溢价;如果你的业务是面向全国的静态展示站,完全可以选个性价比更高的地域。

长期回收机制:把手动排查变成自动触发
手动查一次不难,难在每次故障都靠人肉盯,如果你有一台刚发生故障的服务器,最该做的是立刻部署一个监控脚本,在带宽占用超过80%并且持续五分钟时自动抓取当时的连接快照。
这个脚本的逻辑不复杂:写入crontab定时检查/proc/net/dev的流量差值,超过阈值就执行ss -s和ss -state all输出到日志,同时用ss -time-wait单独列出这些状态的连接去向,这样下次再有异常,你打开日志就能看到是哪个IP哪个端口在捣乱,排查时间缩短不是一点半点。
另一个思路是设置连接数分级限制,在iptables层面对每条新连接做计数,同一IP并发超过三百,就直接DROP掉新连接。
iptables -A INPUT -p tcp --syn -m connlimit --connlimit-above 300 -j REJECT
这套规则的资源消耗极小,但能从入户门口把绝大多数异常连接挡回去。
排查回收常见疑问与补充
服务器带宽被占满一定是被攻击吗
不一定,日常观察到的情况里,因为日志文件过大被日志采集Agent反复扫上传、数据库备份任务压缩后传输、或者某个同事把测试脚本里的循环写成了死循环,这些内部原因占了较大比例,只有当连接表里出现大量随机源IP且端口高位不固定时,才优先怀疑是DDoS(分布式拒绝服务)攻击。
CDN缓存命中率不高时怎么调整
配置缓存规则时,考虑区分文件类型和参数,命中率低的常见原因是URL带了随机参数,可以通过忽略部分参数或设置针对该路径的强缓存来解决,回源率降下来,源站带宽压力自然小。
带宽升级和优化架构哪个优先
多数场景下先优化架构,把需要传输的内容体积减下来,打开一个网站如果首页要载入三十个JS文件,先从合并请求、压缩图片着手,往往能让同样带宽的并发承载能力翻倍,扩容解决的是水龙头不够大的问题,而优化解决的是管道里全是石头的问题,成本投入和最终效果差别很大。