EasyTier 组网带宽限制与连接稳定性优化实践
问题背景
在 EasyTier 组网场景中,当某个节点占用高带宽时,会导致子网内其他节点与该节点的连接出现阻塞甚至断连的问题。这是一个典型的 bufferbloat 和队列管理问题。
问题现象
高带宽占用节点(如进行大文件传输、视频流等)会影响同一子网内其他节点的连接稳定性
其他节点与该高带宽节点之间的连接会出现延迟增加、丢包、甚至断连
网络吞吐量受影响,整体用户体验下降
解决方案验证
通过 iperf3 进行带宽测试验证:
# 不限制带宽时:连接阻塞、断连问题复现
iperf3 -c <target> -t 60
# 限制带宽后:问题解决,连接稳定
tc qdisc add dev tun0 root cake bandwidth 40mbit
iperf3 -c <target> -t 60
验证结论: 使用 tc qdisc cake 进行带宽限制是有效的解决手段。
本文档记录如何在系统启动时自动执行流量控制命令:
/usr/sbin/tc qdisc add dev tun0 root cake bandwidth 40mbit
并在服务停止时自动清除:
/usr/sbin/tc qdisc del dev tun0 root
这个配置在 EasyTier 组网场景下经过验证,能有效解决高带宽占用导致的连接阻塞问题。
核心概念
tc(Traffic Control)
tc 是 Linux 提供的用户空间命令行工具,用于配置内核网络协议栈的流量控制机制。它能对网络接口的出口流量进行整形、调度、优先级分类、过滤、丢弃等操作。
主要用途:
限速(设置最大带宽)
公平队列,防止单个连接霸占全部带宽
差分服务(对不同业务流提供不同优先级)
模拟延迟、丢包(测试用途)
qdisc(Queuing Discipline)
qdisc 是 traffic control 的基本构件,可以理解成"数据包在发送之前所经历的排队策略"。每个网络接口都有至少一个 qdisc,负责管理出口数据包:何时发送、按什么顺序发送、何时丢弃。
重要概念:
root qdisc:每个接口只能有一个根 qdisc,通过
tc qdisc add dev tun0 root附加无类 qdisc(classless):只对数据包整体起作用,如 pfifo_fast、fq_codel、cake
有类 qdisc(classful):内部可以包含多个子类,如 HTB、PRIO
CAKE(Common Applications Kept Enhanced)
CAKE 是一个现代、智能、高度集成的排队规则,由 OpenWrt 社区和 Bufferbloat 项目主导开发,旨在解决家庭/边缘网络中的 bufferbloat(缓冲区膨胀)问题。
核心能力:
集成整形与调度:直接配置带宽限制(bandwidth 参数),无需额外的整形器
主动队列管理(AQM):使用改进版 Codel 算法,在队列堆积前主动丢包/标记,大幅降低延迟
公平队列:在主机之间、流之间进行公平调度,防止单一下载占满带宽
差分服务(DiffServ)处理:自动识别 DSCP 标记,优先发送高优先级流量
常用参数:
bandwidth:设置带宽限制nat:自动处理 NAT 场景下的公平性wash:清除 DSCP 标记,避免干扰diffserv3/diffserv4:选择差分服务模式ack-filter:优化 TCP ACK 处理
典型用法:
tc qdisc add dev eth0 root cake bandwidth 100mbit
tc qdisc add dev tun0 root cake bandwidth 40mbit nat
一、systemd Linux 平台解决方案
1. 创建 systemd 服务文件
创建 /etc/systemd/system/tc-cake-tun0.service:
[Unit]
Description=CAKE qdisc on tun0 (40mbit)
After=network-online.target docker.service sys-subsystem-net-devices-tun0.device
Wants=network-online.target docker.service
Requires=sys-subsystem-net-devices-tun0.device
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/sbin/tc qdisc add dev tun0 root cake bandwidth 40mbit
ExecStop=/usr/sbin/tc qdisc del dev tun0 root
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
关键配置说明:
Type=oneshot:适用于执行一次性命令就退出的服务RemainAfterExit=yes:让 systemd 认为服务在命令退出后仍然"活动",停止时才会执行 ExecStopAfter=docker.service:确保 Docker 引擎启动完成Requires=sys-subsystem-net-devices-tun0.device:等待 tun0 设备出现后再启动
2. 启用和启动服务
sudo systemctl daemon-reload
sudo systemctl enable tc-cake-tun0.service
sudo systemctl start tc-cake-tun0.service
3. 验证和测试
# 查看 qdisc 是否存在
tc qdisc show dev tun0
# 查看服务状态
systemctl status tc-cake-tun0.service
# 测试停止与清除
sudo systemctl stop tc-cake-tun0.service
tc qdisc show dev tun0
# 重新启动
sudo systemctl start tc-cake-tun0.service
二、iStoreOS(OpenWrt)平台解决方案
iStoreOS 基于 OpenWrt,没有 systemd,使用 procd 作为服务管理器,配置方式完全不同。
使用 SQM QoS 图形界面(推荐)
这是最简单、最稳定的方式:
登录 LuCI → 网络 → SQM QoS
选择接口 tun0
选择队列规则
cake或piece_of_cake.qos填写带宽 40000 kbit/s
可选:开启 nat、wash 等选项
SQM 队列脚本说明:
脚本名称 |
说明 |
|---|---|
|
最简单配置:直接使用 cake 替代 HTB 和 fq_codel |
|
使用 cake 的 diffserv profile 实现分层优先级 |
|
HTB 限速 + cake 队列 |
|
三层优先级方案(默认) |
|
TBF 限速 + cake 队列 |
最佳实践: 相比用tc的方案,在 iStoreOS 上优先使用 LuCI 的 SQM QoS 界面,完全不需要接触命令行。
三、Windows 平台解决方案
Windows 没有原生内置类似 Linux tc 的接口级流量整形工具,需要根据场景选择替代方案。
注:暂时还没有测试
第三方网络限速工具
使用 NetLimiter、cFosSpeed 等工具。
以 NetLimiter 为例:
创建开机启动脚本 start-limit.bat:
"C:\Program Files\NetLimiter 4\nlclientapp.exe" /limit "Ethernet 3" out 40 mbit
创建停止脚本 stop-limit.bat:
"C:\Program Files\NetLimiter 4\nlclientapp.exe" /dellimit "Ethernet 3" out
将快捷方式放入启动文件夹(shell:startup)或通过任务计划程序设置自动运行。
PowerShell QoS 策略(功能有限)
# 添加 QoS 策略
New-NetQosPolicy -Name "LimitVPNOut" -ThrottleRateActionBitsPerSecond 40MB `
-IPProtocol Any -PolicyStore ActiveStore
# 删除策略
Remove-NetQosPolicy -Name "LimitVPNOut"
严重限制:
影响所有出站流量,不区分接口
需要手动启停
无法自动跟随接口状态
不推荐使用,除非是临时测试环境。
EasyTier 组网最佳实践
1. 带宽设置建议
基于 iperf3 测试验证,推荐的带宽限制配置:
# 对于 40Mbps 物理链路,建议限制为 30-35Mbps
tc qdisc add dev tun0 root cake bandwidth 30mbit
# 对于 100Mbps 物理链路,建议限制为 80-90Mbps
tc qdisc add dev tun0 root cake bandwidth 80mbit
# 启用 NAT 优化(如果节点在 NAT 后面)
tc qdisc add dev tun0 root cake bandwidth 40mbit nat
设置原则:
留出 10-20% 的安全余量,避免队列拥塞
考虑物理链路的实际可用带宽(扣除其他流量)
在对称链路上可以双向限制,非对称链路需分别设置
2. 监控和验证
定期测试连接稳定性:
# 持续监控连接状态
watch -n 1 'tc qdisc show dev tun0'
# 测试带宽和延迟
iperf3 -c <target_node> -t 30
# 测试连接稳定性(长时间)
iperf3 -c <target_node> -t 300
3. 故障排查
如果出现连接问题,按以下步骤排查:
检查 qdisc 是否生效
tc qdisc show dev tun0
检查服务状态
systemctl status tc-cake-tun0.service journalctl -u tc-cake-tun0.service -n 50
检查带宽设置是否合理
调整 bandwidth 参数,避免过度限制或限制不足
使用
iperf3测试不同带宽设置下的表现
检查 EasyTier 节点状态
确认节点是否正常连接
查看节点日志,排查其他可能的问题
4. 部署建议
生产环境部署:
先在测试环境验证配置效果
使用 systemd service 或 hotplug 确保配置持久化
设置监控告警,及时发现配置失效
定期备份配置文件
多节点部署:
在所有高带宽节点上应用相同策略
在中心节点或网关节点统一管理流量控制
考虑使用配置管理工具(如 Ansible)批量部署
通用最佳实践建议
优先使用平台原生方案:
Linux: systemd service
OpenWrt/iStoreOS: SQM QoS
OpenVPN: 内置 shaper
在网关侧统一管理:EasyTier 组网中,建议在中心节点或高带宽节点上进行流量整形,而不是在每个客户端单独配置。
关注设备可用性:确保服务启动时目标网络接口(tun0)已存在,使用
.device单元或 hotplug 事件机制。错误处理:配置失败不应阻塞系统启动,但要保留日志便于排查问题。
测试验证:使用
iperf3验证配置效果,确保高带宽场景下连接稳定性。
技术背景:为什么 CAKE 能解决问题
EasyTier 组网中的连接阻塞问题本质上是一个 bufferbloat 问题:
问题根源
当某个节点占用高带宽时,网络接口的发送队列会迅速堆积
大量数据包在队列中等待,导致延迟急剧增加
TCP 连接的超时重传机制触发,导致连接断连
其他节点的数据包在队列中排不上队,被"饿死"
CAKE 的解决机制
主动队列管理(AQM):在队列堆积前主动丢包/标记,向发送方发出拥塞信号
公平队列:确保不同连接/流之间公平分享带宽,防止单个连接占满全部带宽
带宽整形:严格控制发送速率不超过设定值,从源头避免队列堆积
低延迟优化:即使在高负载情况下,也能保持较低的延迟
这就是为什么通过 iperf3 验证,使用 CAKE 限制带宽后,EasyTier 连接稳定性得到显著改善的原因。