如何在Linux系统中限制程序的网络带宽?
嘿,要给a.out这类单个进程限制20 Mbps的带宽,有几个靠谱的方案,我按易用性和灵活性给你分情况说明:
方法一:用trickle快速实现(适合大多数场景)
trickle是个轻量级工具,通过LD_PRELOAD机制拦截进程的socket调用,从而控制它的网络流量,优点是简单上手,不需要复杂配置。
步骤:
安装trickle
不同发行版的安装命令:- Debian/Ubuntu系:
sudo apt update && sudo apt install trickle - RHEL/CentOS系:
sudo yum install trickle(如果官方源没有,可从源码编译安装)
- Debian/Ubuntu系:
启动程序时直接限制带宽
因为trickle需要在进程启动时加载拦截库,所以直接用它启动a.out:trickle -s -d 2560 -u 2560 ./a.out参数解释:
-s:启用独立模式,避免和trickle守护进程交互-d:限制下载带宽,单位是KB/s(20 Mbps = 20*128 = 2560 KB/s)-u:限制上传带宽,同样设为2560 KB/s对应20 Mbps
⚠️ 注意:trickle只支持动态编译的程序,如果a.out是静态编译的,这个方法就失效了。
方法二:用tc + cgroup(灵活强大,支持已运行进程)
如果trickle满足不了你的需求(比如要限制已经在运行的a.out,或者静态编译的程序),可以用Linux内核自带的tc(流量控制)结合cgroup(控制组)来实现,这个方案功能更全面,但配置稍复杂。
步骤(假设网卡是eth0,请根据实际情况替换):
创建并配置cgroup
首先创建一个专门的cgroup组:sudo mkdir /sys/fs/cgroup/net_cls/my_aout_group给这个组分配一个唯一的class ID(格式为
0xAAAABBB,这里用0x100001):sudo echo 0x100001 > /sys/fs/cgroup/net_cls/my_aout_group/net_cls.classid用tc配置流量规则
- 先给网卡添加根队列规则:
sudo tc qdisc add dev eth0 root handle 1: htb - 创建一个带宽限制为20 Mbps的流量类:
sudo tc class add dev eth0 parent 1: classid 1:1 htb rate 20mbit - 添加过滤器,把cgroup的流量导向这个限制类:
sudo tc filter add dev eth0 protocol ip parent 1: prio 1 handle 1 fw flowid 1:1
- 先给网卡添加根队列规则:
把目标进程加入cgroup
如果a.out已经在运行,先获取它的PID:PID=$(pidof a.out)然后把PID加入我们创建的cgroup:
sudo echo $PID > /sys/fs/cgroup/net_cls/my_aout_group/cgroup.procs如果是新启动进程,也可以直接在cgroup环境下启动:
sudo cgexec -g net_cls:my_aout_group ./a.out
方法三:用wondershaper(简化tc操作)
如果你觉得tc的命令太繁琐,可以用wondershaper这个脚本工具,它封装了tc的复杂逻辑。不过它主要针对网卡,若只想限制单个进程,仍需结合cgroup使用,步骤和方法二类似,只是用wondershaper配置tc规则:
sudo wondershaper eth0 20480 20480
⚠️ 注意:不同版本的wondershaper参数单位可能不同(KB/s或Kbps),建议先通过man wondershaper确认后再配置。
测试验证
配置完后,可以用iperf或下载大文件验证带宽是否符合预期,比如:
curl -O http://mirrors.kernel.org/ubuntu/dists/jammy/main/installer-amd64/current/legacy-images/netboot/mini.iso
同时用iftop或nload工具实时查看流量情况。
内容的提问来源于stack exchange,提问作者HuangJie




