linux服务器限速仅对出向流量生效,必须在真实网卡(如eth0)上用root权限配置;限速前需确认网卡up状态、清理已有tc规则,并避免在lo或虚拟接口操作。

Linux服务器限速只对出向(egress)流量生效,tc 不是“堵”带宽,而是调度发包行为;直接在物理网卡(如 eth0)上配置,lo 或虚拟接口无效,且必须用 root 权限。
限速前必须确认的三件事
很多限速失败,根本不是命令写错,而是环境没理清:
- 用
ip link show确认目标网卡名(比如ens33)处于UP状态,且不是lo或 Docker 的vethxxx(除非你明确要控容器) - 运行
tc qdisc show dev eth0—— 如果有输出,说明已有规则,不清理就加新规则会冲突或被忽略 - 所有
tc命令必须加sudo,普通用户执行会静默失败或报 “Permission denied”
tbf 是最简限速的首选,但 burst 和 latency 容易设错
tbf 适合全局限速(比如给整台服务器出口设天花板),原理是令牌桶:以 rate 速率产令牌,每个包需消耗令牌才能发。它不分类、不匹配,够稳也够直白。
正确示例(限制 eth0 出向为 5Mbps):sudo tc qdisc add dev eth0 root tbf rate 5mbit burst 64kb latency 70ms
-
rate单位严格区分大小写:mbit(兆比特)≠mbps(非标准写法,部分内核会拒识) -
burst太小(如1kb)会导致小包(如 SSH、DNS)频繁排队丢弃;太大(如10mb)会让限速形同虚设;经验上设为rate / 10左右较平衡(5mbit → 64kb 合理) -
latency不是网络延迟,而是包在队列里最长能等多久;设太小(10ms)易丢包,太大(2s)会让突发流量“憋太久”,影响交互体验
按 IP 或端口限速必须用 htb + filter,且 match 方向极易搞反
想只限某客户端上传(比如限制 192.168.1.100 的出向流量),不能用 tbf,得用分层结构 htb 配合 u32 过滤器。关键陷阱在 match ip src 的含义:
- 在
egress(出向)规则中,match ip src 192.168.1.100匹配的是“本机作为服务端、向外发送给该 IP 的响应包”——即该 IP 是目的端,不是源端 - 真正想限“来自
192.168.1.100的请求导致本机上传”,应匹配目的 IP:match ip dst 192.168.1.100(因为请求进来了,本机回包才发出去) - 若要限某端口(如只限 HTTP 回包),过滤器写成:
match ip dport 80 0xffff(注意十六进制掩码0xffff)
典型流程(限 192.168.1.100 的响应流量为 2mbit):sudo tc qdisc add dev eth0 root handle 1: htb default 30sudo tc class add dev eth0 parent 1: classid 1:1 htb rate 100mbitsudo tc class add dev eth0 parent 1:1 classid 1:10 htb rate 2mbit ceil 2mbitsudo tc filter add dev eth0 parent 1: protocol ip u32 match ip dst 192.168.1.100 flowid 1:10
延迟/丢包等弱网模拟要用 netem,别和限速混在一起
限速(tbf/htb)和网络异常(延迟、丢包)是两类需求,netem 是专用模块,不能和 tbf 共存于同一个 root qdisc 下——后加的会覆盖前者。
- 要同时限速 + 加延迟,必须嵌套:
htb作根,再在子类下挂netem(例如tc qdisc add dev eth0 parent 1:10 handle 10: netem delay 100ms loss 2%) -
netem默认只作用于egress;若要控制下载(ingress),必须配合ifb虚拟设备,先重定向再整形,步骤多、易出错,不建议新手尝试 - 验证是否生效,别只看
tc qdisc show,用iperf -c实测上传,或ping -c 5看延迟变化
真正容易被忽略的点是:限速效果受 TCP 拥塞控制影响极大,短连接(如 HTTP)可能看不出明显压制,而长连接(如 rsync、视频流)才稳定体现;另外,tc 规则不持久,重启即失效,需写入启动脚本或 systemd service 才能长期生效。











