我有一个 Linux 下的路由器/网关,我想添加一些 QoS 来为特定流保留带宽。这可以通过 iptables/netfilter 和 tc 来实现,但所有示例都基于您事先知道可用总带宽这一事实。
问题是,我的 WAN 是移动 3G 连接,性能不稳定。第 1 天,我的网速可以达到 5 Mbps,而第 2 天下雨时,网速会降至 2 Mbps。我如何保证我的流量 1 始终具有 100Kbps 的低延迟?
我想到了一个复杂的解决方案,使用每日或每小时的脚本来检查带宽并动态创建和应用 QoS 脚本,但这对我来说不是一个好的解决方案。
答案1
您应该能够使用 hfsc 调度程序实现您的目标。您将能够保留一部分带宽,并通过“实时”提供低延迟保证,其他类别将按比例使用“链接共享”填充剩余的带宽。
这里重要的是使用实时而不是链接共享,因为实时为了确保能够在最后一毫秒发送数据包,能够阻止其他类发送数据包。
为了实现您的目标,您需要在根类上设置一个较高的上限(可能为 10MB),但在叶类上不设置 ul。由于 hfsc linkshare 在所有“ls”类之间共享带宽的方式,它们将共享可用带宽,如果 m2 值更多,则超过 m2 值。
例如,您可以使用这种设置:
# dns, ntp, teamspeak
iptables -t mangle -A POSTROUTING -o eth0 -p udp -m multiport --dports 53,123,9987 -j CLASSIFY --set-class 1:100
# Default tcp
iptables -t mangle -A POSTROUTING -o eth0 -p tcp -j CLASSIFY --set-class 1:200
# Default udp
iptables -t mangle -A POSTROUTING -o eth0 -p udp -j CLASSIFY --set-class 1:300
# ROOT QDISC - default goes on class 100 because it's probably arp gratuitous or whois since all ip traffic is already classified
tc qdisc add dev eth0 root handle 1:0 hfsc default 100
# ROOT CLASS - Interface eth0, noeud parent de la branche : 1:0, id de la branche : 1:10
tc class add dev eth0 parent 1:0 classid 1:10 hfsc ls m2 10000kbit ul m2 10000kbit
# CLASS 100 - VOIP, DNS, NTP
tc class add dev eth0 parent 1:10 classid 1:100 hfsc sc m1 400kbit d 10ms m2 100kbit
# QDISC
tc qdisc add dev eth0 parent 1:100 handle 110: fq_codel quantum 300 noecn # fq_codel requires to change the quantum for low bandwitdth
# CLASS 200 - some tcp
tc class add dev eth0 parent 1:10 classid 1:200 hfsc ls m1 80kbit d 10ms m2 80kbit
# QDISC - some tcp
tc qdisc add dev eth0 parent 1:200 handle 210: fq_codel
# CLASS 300 - some udp
tc class add dev eth0 parent 1:10 classid 1:300 hfsc ls m1 20kbit d 10ms m2 20kbit # ratio tcp / udp will then be 4:1
# QDISC - some udp
tc qdisc add dev eth0 parent 1:300 handle 310: fq_codel quantum 300 noecn
可能需要根据您的需要更改值,尤其是在 100 类中,尽管我尝试编写这些数字以适合您的 3G。