Динамическое деление скорости интернета между пользователями
На днях встала следующая проблема: делить скорость поровну между всеми
пользователями, причем так, чтобы скорость не выделялась на клиентов,
которые на данный момент не пользуются интернетом, а отдавалась всем
остальным, еще чтобы при большом количестве клиентов и узком канале
получить некоторую «буферность» канала.
Внимательно изучив кучку мануалов, пришел к выводу, что без поднятия скрипта на внутреннем языке Router OS никак не обойтись.
Скрипт работает только с VPN клиентами, т.к. не нашел способа работы с отдельными IP.
Итак, поехали!
Пример на трех PPTP пользователей, первичная настройка
Адреса пользователей 192.168.70.10-192.168.70.12
Адрес сервера 192.168.70.1
Добавляем на каждого из пользователей по интерфейсу, имя интерфейса и имя пользователя должны совпадать! / interface pptp-server add name="user1" user="user1" disabled=no
/ interface pptp-server add name="user2" user="user2" disabled=no
/ interface pptp-server add name="user3" user="user3" disabled=no
Mangle, не знаю почему, но во всех примерах специалисты сначала
маркируют соединение, а потом помечают в нем пакеты, может быть я не
совсем понимаю всей глубины мысли, но не вижу в этом особого толка и
помечаю пакеты сразу в общем потоке, т.к. каждое лишнее правило заметно
тормозит систему. Внимание! значение new-packet-mark должно быть «имя
пользователя/сервера» +"_down” и "_up” соответственно.
Следующим шагом необходимо построить дерево в Queue. В нем и будут происходить все ограничения трафика.
/ queue tree add name="Download" parent=global-out limit-at=0
queue=hotspot-default priority=8 max-limit=0 burst-limit=0
burst-threshold=0 burst-time=0s disabled=no
/ queue tree add name="user1_down" parent=Download packet-mark=user1_down disabled=no
/ queue tree add name="user2_down" parent=Download packet-mark=user2_down disabled=no
/ queue tree add name="user3_down" parent=Download packet-mark=user3_down disabled=no
/ queue tree add name="Upload" parent=global-out limit-at=0
queue=hotspot-default priority=8 max-limit=0 burst-limit=0
burst-threshold=0 burst-time=0s disabled=no
/ queue tree add name="user1_up" parent=Upload packet-mark=user1_up disabled=no
/ queue tree add name="user2_up" parent=Upload packet-mark=user2_up disabled=no
/ queue tree add name="user3_up" parent=Upload packet-mark=user3_up disabled=no
Последним шагом будет настройка вычислительной части скрипта и помещения
ее в планировщик системы, с интервалом 10-60 сек. в зависимости от
производительности вашего микротика, чем меньше интервал — тем лучше.
Переменные и некоторые особенности настройки вычислительной части
MaxRateDownload -Ширина канала на всех пользователей (прием)
MaxRateUpload -Ширина канала на всех пользователей (отдача)
ActiveThresholddown -Порог при превышении которого пользователь будет считаться активным (прием)
ActiveThresholdup - Порог при превышении которого пользователь будет считаться активным (отдача)
ParentDownload -Родитель очереди (прием)
ParentUpload - Родитель очереди (отдача)
Следует устанавливать чуть меньше чем ширина вашего канала, дабы
избежать тормозов при активности еще одного пользователя, который до
этого не потреблял интернет.
Эти значения устанавливайте согласно своим потребностям, но исходя из
расчета: кол-во пользователей умноженное на Thresholddown =не дожно
превышать MaxRateDownload иначе ваши пользователи будут всегда не
активными! Естественно users*ActiveThresholdup= не должно превышать
MaxRateUpload. Всегда оставляйте некоторый запас.
Принцип работы скрипта
Скрипт замеряет, с какой скоростью работает клиент и если она превышает
ActiveThresholddown, добавляет его как активного на прием,
так же, увеличивает счетчик, если пользователь подключен к PPTP своей учетной записи.
Далее скрипт производит проверку ActiveThresholdup, если пользователь
превысил эту отметку, то добавляет его как активного на отдачу.
Если количество активных клиентов равно нулю, изменяет его на единицу,
ибо впоследствии произвести математические расчеты, а то что то на ноль
не делится :)
Рассчитывает:
MaxRateDownload делит на количество активных пользователей на прием, выводит скорость на одного пользователя.
MaxRateUpload делит на количество активных пользователей на отдачу, выводит скорость на одного пользователя.
Далее устанавливает лимит всем пользователям в Queue Tree согласно рассчитанной выше.
Далее рассчитывает значение в килобитах и выводит в лог статистику.
Код скрипта
Для разных версий Router OS, нужна своя версия скрипта. Это связано с
тем, что внутренний синтаксис языка постепенно эволюционирует и тем
самым не всегда радует пользователей.
######################
:foreach i in=[/ppp active find] do={ :set userX [/ppp active get $i name];
:global connected ($connected+1);
/interface monitor-traffic [/interface find name=$userX] once do {:if
($received-bits-per-second>=$ActiveThresholddown) do { :set
onlineclientsdown ($onlineclientsdown+1);}} };
:foreach ii in=[/ppp active find] do={ :set userX [/ppp active get $ii name];
/interface monitor-traffic [/interface find name=$userX] once do {:if
($sent-bits-per-second>=$ActiveThresholdup) do { :set onlineclientsup
($onlineclientsup+1);}} };
:if ($onlineclientsdown = 0) do {:set onlineclientsdown (1)};
:if ($onlineclientsup= 0) do {:set onlineclientsup (1)};
:foreach z in=[/ppp active find] do={ :set userX [/ppp active get $z name];
/queue tree set [/queue tree find name=($userX . "_down")]
parent=$ParentDownload packet-mark=($userX . "_down")
queue=hotspot-default priority=8 max-limit=$ratelimitdown
/queue tree set [/queue tree find name=($userX . "_up")]
parent=$ParentUpload packet-mark=($userX . "_up") queue=hotspot-default
priority=8 max-limit=$ratelimitup};
######################
######################
:foreach i in=[/ppp active find] do={ :set userX [/ppp active get $i name];
:global connected ($connected+1);
/interface monitor-traffic [/interface find name=$userX] once do {:if
($"received-bits-per-second">=$ActiveThresholddown) do { :set
onlineclientsdown ($onlineclientsdown+1);}} };
:foreach ii in=[/ppp active find] do={ :set userX [/ppp active get $ii name];
/interface monitor-traffic [/interface find name=$userX] once do {:if
($"sent-bits-per-second">=$ActiveThresholdup) do { :set
onlineclientsup ($onlineclientsup+1);}} };
:if ($onlineclientsdown = 0) do {:set onlineclientsdown (1)};
:if ($onlineclientsup= 0) do {:set onlineclientsup (1)};
:foreach z in=[/ppp active find] do={ :set userX [/ppp active get $z name];
/queue tree set [/queue tree find name=($userX . "_down")]
parent=$ParentDownload packet-mark=($userX . "_down")
queue=hotspot-default priority=8 max-limit=$ratelimitdown
/queue tree set [/queue tree find name=($userX . "_up")]
parent=$ParentUpload packet-mark=($userX . "_up") queue=hotspot-default
priority=8 max-limit=$ratelimitup};
######################
###################### :foreach i in=[/ppp active find] do={ :set userX [/ppp active get $i name];
:global connected ($connected+1);
/interface monitor-traffic [/interface find name=$userX] once do {:if
($"rx-bits-per-second">=$ActiveThresholddown) do { :set
onlineclientsdown ($onlineclientsdown+1);}} };
:foreach ii in=[/ppp active find] do={ :set userX [/ppp active get $ii name];
/interface monitor-traffic [/interface find name=$userX] once do {:if
($"tx-bits-per-second">=$ActiveThresholdup) do { :set onlineclientsup
($onlineclientsup+1);}} };
:if ($onlineclientsdown = 0) do {:set onlineclientsdown (1)};
:if ($onlineclientsup= 0) do {:set onlineclientsup (1)};
:foreach z in=[/ppp active find] do={ :set userX [/ppp active get $z name];
/queue tree set [/queue tree find name=($userX . "_down")]
parent=$ParentDownload packet-mark=($userX . "_down")
queue=hotspot-default priority=8 max-limit=$ratelimitdown
/queue tree set [/queue tree find name=($userX . "_up")]
parent=$ParentUpload packet-mark=($userX . "_up") queue=hotspot-default
priority=8 max-limit=$ratelimitup};
######################