Это выполнимо в Linux с iptables
и tc
. Вы настраиваете iptables для MARK
пакетов в соединении, где было передано некоторое количество байтов. Затем вы используете tc
эти помеченные пакеты в классе в порядке очереди, чтобы ограничить пропускную способность.
Одна сложная часть заключается в ограничении соединения как для загрузки, так и для загрузки. tc
не поддерживает формирование трафика входа. Вы можете обойти это, формируя выход на интерфейсе, обращенном к вашему веб-серверу (который будет формировать загрузку на ваш веб-сервер), и формируя выход на интерфейсе, обращенном к вашему вышестоящему провайдеру (который будет формировать загрузку с вашего веб-сервера). Вы на самом деле не формируете входной (загрузочный) трафик, так как не можете контролировать скорость отправки данных вышестоящим провайдером. Но формирование интерфейса, обращенного к вашему веб-серверу, приведет к тому, что пакеты будут отброшены, а загрузчик сократит свое окно TCP, чтобы приспособиться к ограничению пропускной способности.
Пример: (предполагается, что это на маршрутизаторе на основе Linux, где интерфейс веб-сервера обращен, eth0
а восходящий - eth1
)
# mark the packets for connections over 4MB being forwarded out eth1
# (uploads from webserver)
iptables -t mangle -A FORWARD -p tcp -o eth1 -m connbytes --connbytes 4194304: --connbytes-dir both --connbytes-mode bytes -j MARK --set-mark 50
# mark the packets for connections over 4MB being forwarded out eth0
# (downloads to webserver)
iptables -t mangle -A FORWARD -p tcp -o eth0 -m connbytes --connbytes 4194304: --connbytes-dir both --connbytes-mode bytes -j MARK --set-mark 50
# Setup queuing discipline for server-download traffic
tc qdisc add dev eth0 root handle 1: htb
tc class add dev eth0 parent 1: classid 1:50 htb rate 50mbit
# Setup queuing discipline for server-upload traffic
tc qdisc add dev eth1 root handle 1: htb
tc class add dev eth1 parent 1: classid 1:50 htb rate 50mbit
# set the tc filters to catch the marked packets and direct them appropriately
tc filter add dev eth0 parent 1:0 protocol ip handle 50 fw flowid 1:50
tc filter add dev eth1 parent 1:0 protocol ip handle 50 fw flowid 1:50
Если вы хотите сделать это на самом веб-сервере, а не на маршрутизаторе Linux, вы все равно можете использовать части загрузки вышеупомянутого материала. Одним из примечательных изменений вы бы заменить FOWARD
с OUTPUT
. Для загрузки вам необходимо настроить дисциплину очередей, используя устройство «Промежуточный функциональный блок», или ifb
. Короче говоря, он использует виртуальный интерфейс, так что вы можете рассматривать входящий трафик как выходной и формировать его оттуда с помощью tc
. Более подробную информацию о том, как настроить, ifb
можно найти здесь: /server/350023/tc-ingress-policing-and-ifb-mirroring.
Обратите внимание, что этот тип материала требует большой настройки для масштабирования. Непосредственная проблема заключается в том connbytes
, что conntrack
модуль зависит от масштабируемых стен с большим количеством соединений. Я бы порекомендовал тяжелое нагрузочное тестирование.
Еще одна оговорка - это то, что это вообще не работает для UDP, так как оно не имеет состояния. Есть и другие способы решения этой проблемы, но похоже, что ваши требования касаются только TCP.
Кроме того, чтобы отменить все вышеперечисленное, сделайте следующее:
# Flush the mangle FORWARD chain (don't run this if you have other stuff in there)
iptables -t mangle -F FORWARD
# Delete the queuing disciplines
tc qdisc del dev eth0 root
tc qdisc del dev eth1 root