您可能正在遭受缓冲膨胀的困扰,并且您需要AQM(活动队列管理)。我已经为Linux编写了一个脚本,这使得这很容易:
#!/bin/bash
# Traffic shaping script (AQM, fq_codel+tbf)
# Copyright 2018 Mikko Rantalainen <mikko.rantalainen@gmail.com>
# License: MIT (X11)
# Usage:
# 21/0.8 Mbps connection (ADSL2): DOWNLINK_RATE=21.7Mbit UPLINK_RATE=0.8Mbit TBF_LATENCY=500ms bin/traffic-shaping start
# 100/100 Mbps connection: ./traffic-shaping
# 1/1 GBps connection: DOWNLINK_RATE=1Gbit UPLINK_RATE=1Gbit TBF_LATENCY=10ms bin/traffic-shaping start
# Note that using low TBF_LATENCY will require powerful CPU.
#
set -e
DEV="${DEV:=$(ip route | grep "^default " | grep -Po "(?<=dev )[^ ]+")}"
# ingress:
DOWNLINK_RATE="${DOWNLINK_RATE:=104000kbit}" # or e.g. "21.5Mbit"
# egress:
UPLINK_RATE="${UPLINK_RATE:=105000kbit}"
CODEL_INTERVAL="${CODEL_INTERVAL:=100ms}" # usually 100ms, high speed links with low latency may need lower values
CODEL_TARGET="${CODEL_TARGET:=5ms}" # unit "us" is also available, usually 5%-10% of CODEL_INTERVAL
CODEL_LIMIT="${CODEL_LIMIT:=1001}" # decrease to reduce latency, too low values will limit throughput
CODEL_FLOWS="${CODEL_FLOWS:=1024}"
# set burst as high as possible without causing dropped packets at the start of the connections
DOWNLINK_BURST="${DOWNLINK_BURST:=6500}"
UPLINK_BURST="${UPLINK_BURST:=6500}"
TBF_LATENCY="${TBF_LATENCY:=14ms}" # set to lower latency to improve control over bandwidth limiting, UPLINK_BURST bytes must be able to be sent in this time
IFB="$DEV.ingress"
INITCWND="${INITCWND:=20}"
INITRWND="${INITRWND:=20}"
configure_shaping()
{
# EGRESS (outgoing traffic, "uploads"):
# setup bandwidth limiting:
tc qdisc add dev "$DEV" root handle 1: tbf rate "$UPLINK_RATE" burst "$UPLINK_BURST" latency "$TBF_LATENCY"
# setup fq_codel for bandwidth shaping
tc qdisc add dev "$DEV" parent 1: fq_codel limit "$CODEL_LIMIT" target "$CODEL_TARGET" interval "$CODEL_INTERVAL" flows "$CODEL_FLOWS" noecn
# INGRESS (incoming traffic, "downloads"):
# setup bandwidth limiting (ingress limiting needs IFB or Intermediate Functional Block, see https://wiki.linuxfoundation.org/networking/ifb):
tc qdisc add dev "$DEV" handle ffff: ingress
ip link add name "$IFB" type ifb
tc qdisc add dev "$IFB" root handle 1: tbf rate "$DOWNLINK_RATE" burst "$DOWNLINK_BURST" latency "$TBF_LATENCY"
# setup fq_codel for bandwidth shaping
tc qdisc add dev "$IFB" parent 1: fq_codel limit "$CODEL_LIMIT" target "$CODEL_TARGET" interval "$CODEL_INTERVAL" flows "$CODEL_FLOWS" ecn
ip link set dev "$IFB" up
# connect ingress filtering to actual WAN device
tc filter add dev "$DEV" parent ffff: protocol all prio 10 u32 match u32 0 0 flowid 1:1 action mirred egress redirect dev "$IFB"
# configure initcwnd and initrwnd
ip route change $(ip route | grep ^default) initcwnd "$INITCWND" initrwnd "$INITRWND"
}
remove_shaping()
{
tc qdisc list | grep -q "ingress" && tc qdisc del dev "$DEV" ingress || true
tc qdisc list | grep -q "codel" && tc qdisc del dev "$DEV" root || true
ip link show | grep -q "$IFB" && ip link del "$IFB" || true
}
status()
{
echo "─── queue discipline configuration: ──────────────────"
tc qdisc list
echo " TIP: use e.g. 'sudo tc qdisc del dev $DEV ingress' to remove ingress filtering"
echo " TIP: use e.g. 'sudo tc qdisc del dev $DEV root' to remove egress filtering"
echo "─── ip link show: ────────────────────────────────────"
ip link show
echo " TIP: use e.g. 'sudo ip link del $IFB' to remove ingress device"
}
color_status()
{
status | grep --color=auto -E "^|$DEV|$IFB|rate [^ ]+"
}
# handle parameters
ACTION="$1"
shift || true
while [ ! -z "$1" ]
do
case "$1" in
-v|--verbose)
echo "Device: $DEV"
echo "Downlink rate (ingress): $DOWNLINK_RATE"
echo "Uplink rate (egress): $UPLINK_RATE"
set -x
;;
*)
if [ ! -z "$2" ]; then
echo "Unknown parameter: '$2'" 1>&2
exit 1
fi
;;
esac
shift
done
case "$ACTION" in
start)
remove_shaping
configure_shaping
;;
stop)
remove_shaping
;;
status)
color_status
;;
restart)
remove_shaping
configure_shaping
;;
*)
echo "Unknown action: $1" 1>&2
echo "Usage: $0 <start|stop|restart|status> [--verbose|-v]" 1>&2
exit 1
esac
您只需将脚本另存为traffic-shaping
并chmod a+x
以root身份运行(显然,在阅读源代码之后)。
对于您的用例,我建议
DOWNLINK_RATE=5.0Mbit UPLINK_RATE=5.0Mbit TBF_LATENCY=500ms ./traffic-shaping start