视频播放--带宽挤占故障排查与限流方案-Nginx
视频播放–带宽挤占故障排查与限流方案-Nginx
阅读对象:后端 / 运维开发人员
核心目标:搞懂「应用层限流」和「操作系统网卡限流」的本质区别,理解为什么 Nginx 限流治标不治本,什么场景下要用底层流量整形
一、基础环境梳理(先理清拓扑)
1.1 服务器资源分布
| 服务器操作系统 | Web 服务 | 承载业务 |
|---|---|---|
| Linux | Nginx | OA 业务、ERP 业务、AI 中台、视频教学(流量暴增来源) |
| Windows Server | IIS | 文件管理、统一认证、图片管理 |
1.2 网络约束
两台服务器共用一条物理网线,总出口带宽固定 20M
关键点:带宽是共享资源,一旦视频业务跑满整条链路,两台机器所有业务、远程桌面 / SSH 全部都会卡顿。
二、故障现象描述
用户访问【视频教学】并发突增 → Linux 服务器占用几乎全部 20M 带宽
连锁影响:
-
Linux 上 OA、ERP、AI 中台网站访问缓慢
-
Windows Server 上 IIS 部署的统一认证、文件管理、图片管理访问超时
-
两台服务器远程管理连接延迟高、掉线
三、排查思考过程(运维排查思路完整记录)
Step1:先定位流量到底来自哪一台服务器
思考:带宽被占满,第一步不能直接改配置限流,先定位流量来源主机
-
Windows 服务器:使用 GlassWire 进程级流量监控工具,观察出站流量
-
Linux 服务器:使用
nethogs按进程查看流量消耗
排查结果确认:流量峰值全部来自 Linux 服务器的 Nginx 进程,大量 mp4 视频请求
初步判断:mp4 视频文件下载 / 播放请求过大,吃掉全部公网带宽。接下来思考:可以从哪几层做限速?
可选方案分层:
Nginx(应用层)做访问频率、单 IP 速度、并发连接限制
Linux 操作系统内核层(TC 流量控制)对网卡 / 端口硬性带宽封顶
网络设备层面(交换机 / 防火墙)做带宽划分
四、方案 1:Nginx 单 IP 局部限流(第一次尝试)
4.1 设计思路
思考逻辑:限制单个客户端 IP 的请求频率和并发连接,防止一个用户多线程拉视频占满带宽。
使用 nginx limit_conn_zone 按客户端 IP 做连接池;limit_req_zone 限制每秒请求次数。
配置代码片段:
# 以客户端真实IP作为key,开辟共享内存区域
limit_conn_zone $binary_remote_addr zone=mp4_conn:10m;
limit_req_zone $binary_remote_addr zone=mp4_req:10m rate=5r/s ;
4.2 实施效果
执行 nginx -s reload 重载配置后短暂改善;清理缓存后仅稳定约 30 分钟。
当访问量再次冲高,请求不断堆积排队,带宽再次跑满,故障复现。
4.3 失败原因思考(核心知识点)
-
该规则只限制单一个 IP,无法控制所有用户加起来的总带宽
-
大量不同用户同时播放视频,每个 IP 都没有超过限制,但是整体流量叠加依然打满 20M 带宽
-
视频支持断点续传(Range 分片请求),同一个视频会拆成几十条小请求,绕过简单的请求频率限制
结论:单 IP 限流 ≠ 整机出口带宽控制
五、方案 2:Nginx 增加全局共享限流(第二次优化尝试)
5.1 优化思考
上一轮只限制单个用户不行 → 增加全局共享令牌池,针对站点整体限制总并发、总请求速率;
同时增加 limit_rate 单文件下载限速、长缓存策略减少重复请求。
完整配置:
# 单用户限流池
limit_conn_zone $binary_remote_addr zone=mp4_conn:10m;
limit_req_zone $binary_remote_addr zone=mp4_req:10m rate=5r/s ;
# 全局共享限流池(所有访客共用一套配额)
limit_conn_zone $server_name zone=mp4_conn_global:10m;
limit_req_zone $server_name zone=mp4_req_global:10m rate=10r/s;
location ~* \.mp4$ {
# 单客户端限制
limit_conn mp4_conn 5;
limit_req zone=mp4_req burst=8 nodelay;
limit_rate 200k;
limit_rate_after 1m;
expires 2d;
add_header Cache-Control public;
add_header Accept-Ranges bytes;
error_page 503 = @rate_limit;
# 全站视频全局配额
limit_conn mp4_conn_global 15;
limit_req zone=mp4_req_global burst=20 nodelay;
}
5.2 实际效果
配置重载后短期缓解;流量持续上涨一段时间后,请求队列持续积压,带宽再次跑满,卡顿问题重现。
5.3 深度原理复盘(技术科普重点)
-
limit_conn / limit_req管控的是HTTP 连接数、请求个数,不是网卡出站比特流(带宽) -
limit_rate是单连接限速,但大量并发连接叠加之后,总的出口流量依然可以突破预期带宽 -
Nginx 属于应用层软件控制,请求到达 Nginx 之后才做拦截;数据包已经占用了系统网络开销
-
断点续传、多 Range 分片播放会产生大量短连接,很容易耗尽配置中的 burst 令牌池,限流规则提前被击穿
一句话总结:Nginx 限流只能控制 HTTP 业务逻辑,不能真正锁死服务器网卡的最大出口带宽
六、方案 3:Linux TC 网卡内核级流量整形(底层限速方案)
6.1 方案思考
既然应用层无法严格控制整机带宽,我们下沉到操作系统内核网卡层面做流量管控。
使用 Linux TC(Traffic Control)HTB 分层令牌桶队列,直接在网卡 em1 上对 8041 端口出站流量硬性封顶带宽。
执行脚本:
export DEV=em1
# 清除历史旧的流量控制规则
tc qdisc del dev $DEV root
# 创建根队列
tc qdisc add dev $DEV root handle 1:0 htb default 10
# 设置带宽上限:10Mbit,封顶10M,不可突破
tc class add dev $DEV parent 1:0 classid 1:10 htb rate 10mbit ceil 10mbit prio 1
# 过滤源端口8041的流量,绑定到限速队列
tc filter add dev $DEV parent 1:0 protocol ip prio 1 u32 match ip sport 8041 0xffff flowid 1:10
6.2 原理科普给研发理解
-
TC 工作在 Linux 内核协议栈,数据包发送出去之前就被内核限速
-
HTB 队列可以硬性锁定某个业务最大占用带宽,物理网卡流量不会超过设定值
-
20M 总带宽拆分:视频业务封顶 10M,剩下 10M 带宽留给 OA/ERP/AI 中台 + Windows 服务器所有业务
-
优先级机制可以保障非视频业务在带宽紧张时优先通行
6.3 当前待验证点
TC 命令是临时生效,重启服务器规则丢失;需要做成开机自启脚本,配合监控持续观测带宽水位。
七、三层限流技术对比表(科普总结)
| 限流方案 | 工作层级 | 控制对象 | 优点 | 缺点 |
|---|---|---|---|---|
| Nginx limit_conn / limit_req | 应用层 (HTTP) | 请求数、并发连接 | 配置灵活,可以返回 503 提示,区分用户 | 无法严格控制整机带宽,分片下载容易击穿 |
| Nginx limit_rate | 应用层 (文件流) | 单连接下载速度 | 限制单个视频下载速度 | 多并发叠加依然跑满带宽 |
| Linux TC HTB | 操作系统内核网卡层 | 网卡真实出站带宽 (Mbit) | 硬性带宽封顶,从底层保护整条链路 | 控制粒度是端口 / IP,业务友好提示弱,配置复杂 |
八、整体问题根因总结(技术知识点沉淀)
-
共享带宽架构缺陷:多业务、多服务器共用一条 20M 链路,没有带宽隔离,单业务峰值直接影响全部系统
-
应用层限流 ≠ 带宽限流:Nginx 是 Web 服务,只管理 HTTP 请求,管不住网卡真实的比特流
-
视频业务天然属于大流量长连接业务,单纯依靠 Web 层面的请求计数限流效果有限
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐


所有评论(0)