搜索
首页 > 运维 > linux运维 > 正文

Linux tc命令流量控制使用方法

舞姬之光
发布: 2025-09-22 23:49:01
原创
812人浏览过
tc命令是Linux中用于网络流量控制的强大工具,可对出站流量进行限速、优先级划分和整形。其核心机制基于qdisc(排队规则)、class(类)和filter(过滤器)三大组件。tbf适用于简单限速,htb则支持复杂的分级带宽管理,如为SSH、HTTP分配不同优先级和带宽。常见问题包括误用于入站流量、旧规则残留、过滤器匹配错误及测试方法不当。排查需检查规则状态与统计信息。tc常与iptables协同:iptables在mangle表中通过MARK为目标流量打标记,tc使用fw过滤器根据标记将流量导向特定class进行调度,从而实现精细化QoS策略。

linux tc命令流量控制使用方法

tc
登录后复制
命令是 Linux 系统中一个强大但配置起来也颇为复杂的流量控制工具。简单来说,它就是你操作系统层面用来精细管理网络数据包“排队”和“发送”的“交通警察”。它允许你对出站(甚至部分入站)流量进行限速、优先级设置、流量整形,从而优化网络性能,确保关键应用的服务质量(QoS)。在我看来,掌握
tc
登录后复制
的基本原理和常用配置,对于任何需要进行网络性能调优的系统管理员或开发者来说,都是一项非常有价值的技能,尽管它确实有点学习曲线。

解决方案

使用

tc
登录后复制
命令进行流量控制的核心在于理解其三个主要概念:
qdisc
登录后复制
(queuing discipline,排队规则)、
class
登录后复制
(类) 和
filter
登录后复制
(过滤器)。

  1. qdisc
    登录后复制
    (排队规则):
    这是流量控制的基础。每个网络接口(如
    eth0
    登录后复制
    )都有一个根
    qdisc
    登录后复制
    。所有出站数据包都必须经过这个
    qdisc
    登录后复制
    。你可以选择不同的
    qdisc
    登录后复制
    类型来定义数据包如何被排队和调度。
  2. class
    登录后复制
    (类):
    某些
    qdisc
    登录后复制
    (如
    HTB
    登录后复制
    )是分层的,允许你在一个
    qdisc
    登录后复制
    下创建多个“类”。每个类可以有自己的带宽限制和优先级,并且可以进一步包含子
    qdisc
    登录后复制
    和子类。
  3. filter
    登录后复制
    (过滤器):
    过滤器用于将特定的数据包导向特定的
    class
    登录后复制
    qdisc
    登录后复制
    。你可以根据源/目的 IP、端口、协议等多种条件来匹配数据包。

基本限速示例 (使用

tbf
登录后复制
- Token Bucket Filter):

tbf
登录后复制
是最简单的
qdisc
登录后复制
之一,适用于对整个接口的出站流量进行硬性限速。

# 1. 清除eth0接口上可能存在的旧规则,避免冲突
sudo tc qdisc del dev eth0 root

# 2. 在eth0接口上添加一个tbf qdisc,限制出站速度为100kbit/s,
#    允许突发流量达到10kbit,并设置延迟为70ms(数据包在队列中等待的最长时间)
sudo tc qdisc add dev eth0 root tbf rate 100kbit burst 10kbit latency 70ms

# 3. 验证规则是否生效
sudo tc qdisc show dev eth0
登录后复制

分级限速与优先级示例 (使用

HTB
登录后复制
- Hierarchical Token Bucket):

HTB
登录后复制
tc
登录后复制
中最常用也最强大的
qdisc
登录后复制
之一,它允许你创建复杂的流量分级和优先级策略。

假设我们想将

eth0
登录后复制
的总出站带宽限制在 100Mbps,然后为 SSH 流量(端口 22)分配 50Mbps 的高优先级带宽,为 HTTP 流量(端口 80)分配 20Mbps 的中优先级带宽,其余流量则走默认的低优先级通道。

# 1. 清除eth0接口上的所有现有规则
sudo tc qdisc del dev eth0 root

# 2. 创建一个HTB根qdisc。handle 1: 是这个qdisc的标识符。
#    default 20 表示所有未被特定过滤器匹配的流量都将进入classid 1:20。
sudo tc qdisc add dev eth0 root handle 1: htb default 20

# 3. 创建一个主类 (parent 1:),定义总的可用带宽。
#    classid 1:1 是这个主类的标识符。
#    rate 100mbit 是承诺带宽,ceil 100mbit 是最大可用带宽。
sudo tc class add dev eth0 parent 1: classid 1:1 htb rate 100mbit ceil 100mbit

# 4. 创建子类,分配给不同类型的流量。
#    a. SSH流量类 (高优先级)
#       parent 1:1 表示它是主类1:1的子类。classid 1:10 是其标识符。
#       rate 50mbit 是承诺带宽,ceil 80mbit 是在有空闲时可以突发到的最大带宽。
#       prio 1 表示优先级最高(数字越小优先级越高)。
sudo tc class add dev eth0 parent 1:1 classid 1:10 htb rate 50mbit ceil 80mbit prio 1

#    b. HTTP流量类 (中优先级)
sudo tc class add dev eth0 parent 1:1 classid 1:20 htb rate 20mbit ceil 50mbit prio 2

#    c. 默认流量类 (低优先级,用于所有未匹配的流量)
#       这个类的rate和ceil可以根据实际情况设置,或者让它共享剩余带宽。
sudo tc class add dev eth0 parent 1:1 classid 1:30 htb rate 10mbit ceil 30mbit prio 3

# 5. 使用过滤器将特定流量分类到对应的类。
#    protocol ip 表示匹配IP协议流量。prio 定义过滤器本身的优先级。
#    u32 过滤器允许我们基于IP头部字段进行匹配。
#    match ip dport 22 0xffff 表示匹配目的端口为22的TCP/UDP流量。
#    flowid 1:10 表示将匹配到的流量导向classid 1:10。

#    a. SSH流量 (目的端口22)
sudo tc filter add dev eth0 parent 1: protocol ip prio 1 u32 match ip dport 22 0xffff flowid 1:10

#    b. HTTP流量 (目的端口80)
sudo tc filter add dev eth0 parent 1: protocol ip prio 2 u32 match ip dport 80 0xffff flowid 1:20

# 6. 验证所有规则
sudo tc -s qdisc show dev eth0
sudo tc -s class show dev eth0
sudo tc -s filter show dev eth0

# 7. 删除所有规则
# 当你不再需要这些规则时,记得删除它们。
# sudo tc qdisc del dev eth0 root
登录后复制

这个

HTB
登录后复制
示例虽然看起来复杂,但它正是
tc
登录后复制
强大之处的体现。通过这种方式,你可以为服务器上的不同服务、不同用户或不同应用分配和保障带宽,确保关键业务的流畅运行。

为什么我的
tc
登录后复制
规则似乎没有生效?

这绝对是

tc
登录后复制
新手最常遇到的“坑”之一,甚至我自己也时不时会在这里跌倒。
tc
登录后复制
规则不生效,往往不是命令本身错了(虽然语法错误也常见),而是对
tc
登录后复制
的工作原理或测试环境理解有偏差。

Rytr写作助手
Rytr写作助手

Rytr 是一款AI内容生成和写作助手,可帮助您在短短几秒钟内以极低的成本创建高质量的内容!

Rytr写作助手68
查看详情 Rytr写作助手

一个最核心的误区是:

tc
登录后复制
默认只控制
egress
登录后复制
(出站)流量。 也就是说,你设置的规则,只会影响从你的网卡
eth0
登录后复制
发出去的数据包。如果你想控制 进入
eth0
登录后复制
的数据包(
ingress
登录后复制
流量),情况就复杂多了。虽然
tc
登录后复制
有一个
ingress qdisc
登录后复制
,但它功能有限,主要用于丢弃超速流量,不能像
egress
登录后复制
那样进行复杂的整形和优先级划分。通常,对于入站流量的控制,你需要结合
iptables
登录后复制
进行数据包标记,然后在一个 其他 接口的
egress
登录后复制
端进行整形,或者利用一些更高级、更复杂的内核模块(比如
IMQ
登录后复制
,但它现在已经不推荐使用了)。所以,当你发现规则没生效时,先问问自己:我是在控制出站还是入站流量?

另外,还有几个常见原因:

  • 旧规则残留: 你在添加新规则之前,有没有彻底清除掉
    eth0
    登录后复制
    上可能存在的旧规则?
    sudo tc qdisc del dev eth0 root
    登录后复制
    这一步至关重要。如果存在冲突的规则,新的可能就不会被应用,或者行为不符合预期。
  • 过滤器匹配问题: 你的
    filter
    登录后复制
    规则是否真的匹配到了你想要控制的流量?IP 地址、端口号、协议、甚至
    u32
    登录后复制
    匹配的偏移量和掩码,任何一个细节不对,数据包就可能溜走,进入
    default
    登录后复制
    类或者根本不受控制。我发现很多人在
    u32
    登录后复制
    匹配上容易出错,一个
    0xffff
    登录后复制
    的掩码可能就导致匹配不精确。
  • 测试方法不当: 你是如何测试限速效果的?仅仅是
    ping
    登录后复制
    吗?
    ping
    登录后复制
    的流量很小,可能根本触及不到限速阈值。通常,你需要使用
    iperf3
    登录后复制
    netcat
    登录后复制
    或者实际的大文件下载/上传来产生足够的流量,才能观察到
    tc
    登录后复制
    规则的效果。同时,确保你测试的流量确实是通过你设置
    tc
    登录后复制
    规则的那个接口。
  • 优先级冲突: 如果你设置了多个
    filter
    登录后复制
    ,它们的
    prio
    登录后复制
    值很重要。
    tc
    登录后复制
    会按照
    prio
    登录后复制
    值从小到大(优先级从高到低)的顺序处理过滤器。一个优先级较高的、匹配范围较广的过滤器,可能会在更具体的过滤器之前捕获到流量。
  • 内核模块缺失: 虽然现代 Linux 内核通常都预装了
    tc
    登录后复制
    所需的模块,但如果你的系统是高度定制的,或者非常老旧,可能需要检查
    sch_htb
    登录后复制
    sch_tbf
    登录后复制
    等模块是否已加载 (
    lsmod | grep sch_
    登录后复制
    )。

遇到问题,最有效的排查方式是使用

sudo tc -s qdisc show dev eth0
登录后复制
sudo tc -s class show dev eth0
登录后复制
sudo tc -s filter show dev eth0
登录后复制
命令,它们会显示当前规则的详细状态和统计信息,包括通过每个
qdisc
登录后复制
class
登录后复制
的数据包数量和字节数,这能帮助你判断流量是否真的进入了你预期的队列。

tc
登录后复制
iptables
登录后复制
在流量控制中如何协同工作?

tc
登录后复制
iptables
登录后复制
在 Linux 网络中扮演着不同的角色,但它们可以非常优雅地协同工作,实现更精细、更灵活的流量控制策略。简单来说,
iptables
登录后复制
负责识别和标记数据包,而
tc
登录后复制
则负责根据这些标记调度和整形数据包。

iptables
登录后复制
的强大之处在于它能够基于非常丰富的条件来检查和修改数据包。它可以查看源/目的 IP、端口、协议、TCP 标志位、连接状态,甚至数据包的特定内容。在流量控制的场景下,
iptables
登录后复制
最常用的功能是使用
MARK
登录后复制
CONNMARK
登录后复制
目标,在
mangle
登录后复制
表中为数据包打上一个数字标记。这个标记本身不会改变数据包的内容,但它会随着数据包在内核中传递,可以被其他模块(比如
tc
登录后复制
)读取。

协同工作流程:

  1. iptables
    登录后复制
    标记数据包: 你可以在
    iptables
    登录后复制
    mangle
    登录后复制
    表中定义规则,根据你需要的条件(例如,来自特定 IP 的流量、去往特定端口的流量、特定协议的流量等)为数据包打上一个唯一的数字标记。

    # 示例:标记所有源IP为192.168.1.100的出站流量,标记值为10
    sudo iptables -t mangle -A POSTROUTING -s 192.168.1.100 -j MARK --set-mark 10
    
    # 示例:标记所有目的端口为80(HTTP)的出站TCP流量,标记值为20
    sudo iptables -t mangle -A POSTROUTING -p tcp --dport 80 -j MARK --set-mark 20
    
    # 确保路由后,标记仍然存在。PREROUTING 也可以,但POSTROUTING更靠近tc的egress。
    # 如果要对入站流量进行标记,通常在PREROUTING链进行,但要记住tc只能在出站接口整形。
    登录后复制

    注意:

    MARK
    登录后复制
    目标会给单个数据包打标记。如果你想标记整个连接的所有数据包,可以使用
    CONNMARK
    登录后复制
    ,它会将
    MARK
    登录后复制
    值保存到连接跟踪表中,并应用到该连接的所有后续数据包。

  2. tc
    登录后复制
    根据标记过滤和整形:
    tc
    登录后复制
    的过滤器中,你可以使用
    fw
    登录后复制
    (firewall mark) 过滤器来匹配
    iptables
    登录后复制
    设置的标记,然后将匹配到的数据包导向特定的
    class
    登录后复制
    qdisc
    登录后复制
    进行流量整形。

    # 假设你已经设置了一个HTB根qdisc和主类,例如:
    # sudo tc qdisc add dev eth0 root handle 1: htb default 30
    # sudo tc class add dev eth0 parent 1: classid 1:1 htb rate 100mbit ceil 100mbit
    
    # 创建一个子类1:10,用于处理标记为10的流量
    sudo tc class add dev eth0 parent 1:1 classid 1:10 htb rate 10mbit ceil 20mbit prio 1
    
    # 创建一个子类1:20,用于处理标记为20的流量
    sudo tc class add dev eth0 parent 1:1 classid 1:20 htb rate 5mbit ceil 15mbit prio 2
    
    # 使用fw过滤器匹配iptables的标记
    # prio 1 表示这个过滤器本身的优先级。handle 10 fw 匹配标记值为10的数据包。
    sudo tc filter add dev eth0 parent 1: protocol ip prio 1 handle 10 fw flowid 1:10
    
    # 匹配标记值为20的数据包
    sudo tc filter add dev eth0 parent 1: protocol ip prio 2 handle 20
    登录后复制

以上就是Linux tc命令流量控制使用方法的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2025 //m.sbmmt.com/ All Rights Reserved | php.cn | 湘ICP备2023035733号