Mikrotik Router OS、動的速度分割用スクリプト(バージョン2)

Mikrotik Router OS、動的速度分割用スクリプト(バージョン2)





これは2番目のバージョンで、最初のバージョンはこちらです。



先日、次の問題が発生しました:すべてのユーザー間で速度を均等に分割し、現在インターネットを使用していないクライアントに速度を割り当てず、他のすべてのユーザーに速度を割り当てたため、多数のクライアントと狭いチャネルでいくつかの「バッファリング」が発生しましたチャンネル。



過去の経験に基づいて、過去の欠点をなくすために完全に新しいスクリプトが作成され、現在のニーズに合わせて完成されました。



新しいバージョンでは、ユーザーの場所の点ではるかに簡単になりました。ユーザーがどのように接続したかは関係ありません。主なことは、ユーザーがIPアドレスを持っていることです。



それでは行きましょう...



3人のユーザーの例。


ユーザーアドレス192.168.5.100-192.168.5.102



リストに3人のユーザーを追加しますが、実際に存在するユーザーのみを追加します。 使用していない場合、範囲全体を採点する必要はありません。なぜなら、 余分なレコードはすべてパフォーマンスに大きく影響します。



/ip firewall address-list add list="users" address=192.168.5.100

/ip firewall address-list add list="users" address=192.168.5.101

/ip firewall address-list add list="users" address=192.168.5.102









リストを手動で追加しないために、範囲を追加するプロセスを高速化する小さなサイクルがスローされました。 このようなスクリプトを1回実行すると、上記で行ったことと同じことが行われます。



#Settings

######################################################

:local start ("100");

:local stop ("102");

:local net ("192.168.5.");

######################################################



######################################################

:global count ($start);

:for count from=$start to=$stop step=1 do={

/ip firewall address-list add list="users" address=( $net . $count);};

######################################################



######################################################

# (C) Inlarion icq 429-587 mikrotik.axiom-pro.ru Copyright!

######################################################









2番目のステップは、/ queueおよび/ ip firewall mangleにエントリを追加することです。これも、管理者を手動でエントリを追加するルーチンから解放します。 人的要因は眠っていません。小さなスクリプトがスケッチされています。 / ip firewall address-list list = "users"のエントリを追加または削除するたびにこのスクリプトを実行する必要があります。その主なタスクは、新しいエントリを追加し、不要な古いエントリを削除することです。削除するのを忘れました。 スクリプトが終了すると、追加および削除されたレコードの数に関する情報がシステムログに記録されます。



#Settings

######################################################

:local DownloadParent ("Download");

:local UploadParent ("Upload");

######################################################



#Internal Var

######################################################

:local i;

:local z;

:local userX;

:local enum (" ");

:local mark;

:local qrd;

:local qru;

:local mrd;

:local mru;

:local qrdadd;

:local qruadd;

:local mrdadd;

:local mruadd;

:set qrd (0);

:set qru (0);

:set mrd (0);

:set mru (0);

:set qrdadd (0);

:set qruadd (0);

:set mrdadd (0);

:set mruadd (0);

######################################################



######################################################

:log warning ("Rules Manager Started!");



:if ([/queue type find name="dshaper_down"] = "") do={ /queue type add name="dshaper_down" kind="pcq" pcq-classifier=dst-address pcq-rate=0 pcq-limit=50 pcq-total-limit=2000;};



:if ([/queue type find name="dshaper_up"] = "") do={ /queue type add name="dshaper_up" kind="pcq" pcq-classifier=src-address pcq-rate=0 pcq-limit=50 pcq-total-limit=2000;};



:if ([/queue tree find name=$DownloadParent] = "") do={ /queue tree add name=$DownloadParent parent="global-out" queue="dshaper_down" priority=8;};

:if ([/queue tree find name=$UploadParent] = "") do={ /queue tree add name=$UploadParent parent="global-out" queue="dshaper_up" priority=8;};



:foreach i in=[/ip firewall address-list find list="users"] do={ :set userX [/ip firewall address-list get $i address];



:if ([/queue tree find name=($userX . "_down")] = "") do={ /queue tree add name=($userX . "_down") parent=$DownloadParent queue="dshaper_down" packet-mark=($userX . "_down") priority=8; :set qrdadd ($qrdadd+1); };

:if ([/queue tree find name=($userX . "_up")] = "") do={ /queue tree add name=($userX . "_up") parent=$UploadParent queue="dshaper_up" packet-mark=($userX . "_up") priority=8; :set qruadd ($qruadd+1);};



:set enum (" ");

:set enum ([/ip firewall mangle find comment=($userX . "_up")]);

:if ($enum = "") do={ /ip firewall mangle add chain=forward src-address=$userX dst-address=0.0.0.0/0 action=mark-packet new-packet-mark=($userX . "_up") comment=($userX . "_up") disabled=no passthrough=yes; :set mruadd ($mruadd+1);

};



:set enum (" ");

:set enum ([/ip firewall mangle find comment=($userX . "_down")]);

:if ($enum = "") do={ /ip firewall mangle add chain=forward src-address=0.0.0.0/0 dst-address=$userX action=mark-packet new-packet-mark=($userX . "_down") comment=($userX . "_down") disabled=no passthrough=yes; :set mrdadd ($mrdadd+1);

};



};



:foreach z in=[/queue tree find parent=$DownloadParent] do={

:set mark [/queue tree get $z name];

:if ($mark !="") do={

:set mark ([:tostr $mark]);

:set mark ([:pick $mark 0 ([:len $mark]-5)]);

:if ([/ip firewall address-list find address=$mark] = "") do={/queue tree remove [/queue tree find name=($mark . "_down")]; :set qrd ($qrd+1); };};};



:foreach z in=[/queue tree find parent=$UploadParent] do={

:set mark [/queue tree get $z name];

:if ($mark !="") do={

:set mark ([:tostr $mark]);

:set mark ([:pick $mark 0 ([:len $mark]-3)]);

:if ([/ip firewall address-list find address=$mark] = "") do={/queue tree remove [/queue tree find name=($mark . "_up")]; :set qru ($qru+1); };};};



:foreach z in=[/ip firewall mangle find src-address="0.0.0.0/0" action="mark-packet" chain="forward"] do={

:set mark [/ ip firewall mangle get $z comment];

:if ($mark !="") do={

:set mark ([:tostr $mark]);

:set mark ([:pick $mark 0 ([:len $mark]-5)]);

:if ([/ip firewall address-list find address=$mark] = "") do={

:if ([/ip firewall mangle find comment=($mark . "_down")] != "") do={/ip firewall mangle remove [/ip firewall mangle find comment=($mark . "_down")]; :set mrd ($mrd+1); }}}}



:foreach z in=[/ip firewall mangle find dst-address="0.0.0.0/0" action="mark-packet" chain="forward"] do={

:set mark [/ ip firewall mangle get $z comment];

:if ($mark !="") do={

:set mark ([:tostr $mark]);

:set mark ([:pick $mark 0 ([:len $mark]-3)]);

:if ([/ip firewall address-list find address=$mark] = "") do={

:if ([/ip firewall mangle find comment=($mark . "_up")] != "") do={/ip firewall mangle remove [/ ip firewall mangle find comment=($mark . "_up")]; :set mru ($mru+1); }}}}

######################################################



######################################################

:log info ("------------------------------------------");

:log warning ("Rules Manager:");

:log info ("Queue Tree Download Records Added: " . $qrdadd);

:log info ("Queue Tree Upload Records Added: " . $qruadd);

:log info ("Mangle Download Records Added: " . $mrdadd);

:log info ("Mangle Upload Records Added: " . $mruadd);

:log info ("Queue Tree Download Records Deleted: " . $qrd);

:log info ("Queue Tree Upload Records Deleted: " . $qru);

:log info ("Mangle Download Records Deleted: " . $mrd);

:log info ("Mangle Upload Records Deleted: " . $mru);

:log info ("------------------------------------------");

######################################################



######################################################

# (C) Inlarion icq 429-587 mikrotik.axiom-pro.ru Copyright!

######################################################









回路の計算部分と実行部分のスクリプト




スクリプトの原理。




このスクリプトは、夜間サポートが有効かどうかを判断し、現在の時刻を確認し、時間範囲に従ってチャネル帯域幅を選択します。

このスクリプトは、クライアントの動作速度を測定し、ActiveThresholddownを超えると、受信時にアクティブなクライアントとして追加されます。

また、アクティブなクライアントのカウンターを増やします。

次に、ActiveThresholdupをチェックし、ユーザーがこのマークを超えている場合は、戻り時にアクティブとして追加します。

また、返品時のアクティブな顧客のカウンターを増やします。



計算:

MaxRateDownloadは、受信するアクティブなユーザーの数で割り、ユーザーごとの速度を表示します。

MaxRateUploadは、リターンごとのアクティブユーザーの数で除算し、ユーザーごとの速度を表示します。



次に、上記で計算されたスキームに従って、キューツリーのすべてのユーザーに制限を設定します。



次に、キロビット単位で値を計算し、ログに統計を表示します。



冒頭のスクリプトの変数:




MaxRateDownload-すべてのユーザーのチャネル幅(受信)ビット/秒

MaxRateUpload-すべてのユーザーのチャネル幅(リターン)ビット/秒

MaxRateDownloadNight-すべてのユーザーの夜間のチャネル幅(受信)ビット/秒

MaxRateUploadNight-夜間のすべてのユーザーのチャネル幅(戻り)ビット/秒



ActiveThresholddown-超過した場合のしきい値。ユーザーはアクティブ(受信)ビット/秒と見なされます。

ActiveThresholdup-超過した場合のしきい値。ユーザーはアクティブ(リターン)ビット/秒と見なされます。



usenighttime-値「yes」および「no」を受け入れることができ、スクリプトが異なるチャネル幅を使用できるようにします。 夜料金に応じて。

nighttimestart-スクリプトに夜間料金の開始を通知します。

nighttimestop-スクリプトに夜間料金の終了を通知します。



#Settings

######################################################

:local MaxRateDownload ("15000000");

:local MaxRateUpload ("15000000");

:local MaxRateDownloadNight ("20000000");

:local MaxRateUploadNight ("20000000");



:local ActiveThresholddown ("15000");

:local ActiveThresholdup ("15000");



:local usenighttime ("yes");

:local nighttimestart ("02:00");

:local nighttimestop ("08:00");

######################################################



#Internal Var

######################################################

:local z;

:local i;

:local ii;

:local userX;

:local timedelay (0);

:local startmin;

:local startsec;

:local stopmin;

:local stopsec;

:local scripttimedelay (0);

:local scriptstartmin;

:local scriptstartsec;

:local scriptstopmin;

:local scriptstopsec;

:local userscount ("0");

:local userstmp ("");

:local firstdowntmp ("");

:local firstuptmp ("");

:local twodowntmp ("");

:local twouptmp ("");

:local activedownuserstmp ("");

:local activeupuserstmp ("");

:local activedowncount ("0");

:local activeupcount ("0");

######################################################



######################################################

:set scriptstartmin ([: pick [/system clock get time] 3 5]);

:set scriptstartsec ([: pick [/system clock get time] 6 8]);



:if ($usenighttime = "yes") do={

:set nighttimestart ([: pick $nighttimestart 0 2] . [: pick $nighttimestart 3 5]);

:set nighttimestop ([: pick $nighttimestop 0 2] . [: pick $nighttimestop 3 5]);

:local currenthours ([: pick [/system clock get time] 0 2]);

:local currenttime ([: pick [/system clock get time] 0 2] . [: pick [/system clock get time] 3 5] );

:local acttime ("day");

:local starttime ("day");

:if ($currenthours < 10) do={ :set acttime ("night"); };

:if ( [: pick $nighttimestart 0 2] < 10) do={ :set starttime ("night"); };

:local night ("no");



:if ($starttime = "night") do={

:if ( $currenttime > $nighttimestart && $currenttime < $nighttimestop) do={ :set night ("yes"); };

};

:if ($starttime = "day") do={

:if ( $acttime = "day") do={

:if ( $currenttime >= $nighttimestart) do={ :set night ("yes"); };

};

:if ( $acttime = "night") do={

:if ( $currenttime < $nighttimestop ) do={ :set night ("yes"); };

};};



:if ($night = "yes") do={

:set MaxRateDownload ($MaxRateDownloadNight);

:set MaxRateUpload ($MaxRateUploadNight);

};

};



:set ActiveThresholddown ($ActiveThresholddown / 8);

:set ActiveThresholdup ($ActiveThresholdup / 8);



:foreach i in=[/ip firewall address-list find list="users"] do={ :set userX [/ip firewall address-list get $i address];

:set userscount ($userscount+1);

:set userstmp ($userstmp . $userX . ",");

};



:local users [:toarray $userstmp];



:set startmin ([: pick [/system clock get time] 3 5]);

:set startsec ([: pick [/system clock get time] 6 8]);



:global dcount ("1");

:for dcount from=1 to=$userscount step=1 do={

:set firstdowntmp ($firstdowntmp . [/ip firewall mangle get [/ip firewall mangle find comment=[:pick $users ($dcount-1)] . "_down"] bytes] . ",");

:set firstuptmp ($firstuptmp . [/ip firewall mangle get [/ip firewall mangle find comment=[:pick $users ($dcount-1)] . "_up"] bytes] . ",");

};



:set stopmin ([: pick [/system clock get time] 3 5]);

:set stopsec ([: pick [/system clock get time] 6 8]);



:global dcount ("1");

:for dcount from=1 to=$userscount step=1 do={

:set twodowntmp ($twodowntmp . [/ip firewall mangle get [/ip firewall mangle find comment=[:pick $users ($dcount-1)] . "_down"] bytes] . ",");

:set twouptmp ($twouptmp . [/ip firewall mangle get [/ip firewall mangle find comment=[:pick $users ($dcount-1)] . "_up"] bytes] . ",");

};



:if ( $stopmin > $startmin) do={

:set timedelay (($stopmin-$startmin) * 60);

};

:set timedelay (($timedelay+$stopsec)-$startsec);



:local firstdown [:toarray $firstdowntmp];

:local firstup [:toarray $firstuptmp];

:local twodown [:toarray $twodowntmp];

:local twoup [:toarray $twouptmp];



:global dcount ("1");

:for dcount from=1 to=$userscount step=1 do={



:if ( ($ActiveThresholddown * $timedelay) < ([:pick $twodown ($dcount-1)] - [:pick $firstdown ($dcount-1)]) ) do={

:set activedownuserstmp ($activedownuserstmp . [:pick $users ($dcount-1)] . ",");

:set activedowncount ($activedowncount+1);

};



:if ( ($ActiveThresholdup * $timedelay) < ([:pick $twoup ($dcount-1)] - [:pick $firstup ($dcount-1)]) ) do={

:set activeupuserstmp ($activeupuserstmp . [:pick $users ($dcount-1)] . ",");

:set activeupcount ($activeupcount+1);

};



};



:local activedownusers [:toarray $activedownuserstmp];

:local activeupusers [:toarray $activeupuserstmp];



:local maxlimitdown ("0");

:local maxlimitup ("0");



:if ( $activedowncount > 0 ) do={

:set maxlimitdown ($MaxRateDownload/$activedowncount);

:global dcount ("1");

:for dcount from=1 to=$activedowncount step=1 do={

:if ([/queue tree get [find name=[:pick $activedownusers ($dcount-1)] . "_down"] max-limit] != $maxlimitdown) do={

/queue tree set [/queue tree find name=[:pick $activedownusers ($dcount-1)] . "_down"] max-limit=$maxlimitdown; };

};

};



:if ( $activeupcount > 0 ) do={

:set maxlimitup ($MaxRateUpload/$activeupcount);

:global dcount ("1");

:for dcount from=1 to=$activeupcount step=1 do={

:if ([/queue tree get [find name=[:pick $activeupusers ($dcount-1)] . "_up"] max-limit] != $maxlimitup) do={

/queue tree set [/queue tree find name=[:pick $activeupusers ($dcount-1)] . "_up"] max-limit=$maxlimitup; };

};

};



:local kbsmaxdown ($MaxRateDownload/1000);

:local kbsmaxup ($MaxRateUpload /1000);



:if ( $maxlimitdown = 0 ) do={ :set maxlimitdown ($MaxRateDownload); };

:if ( $maxlimitup = 0 ) do={ :set maxlimitup ($MaxRateUpload); };

:local kbsmaxlimitdown ($maxlimitdown/1024);

:local kbsmaxlimitup ($maxlimitup/1024);



:set scriptstopmin ([: pick [/system clock get time] 3 5]);

:set scriptstopsec ([: pick [/system clock get time] 6 8]);



:if ( $scriptstopmin > $scriptstartmin) do={

:set scripttimedelay (($scriptstopmin-$scriptstartmin) * 60);

};

:set scripttimedelay (($scripttimedelay+$scriptstopsec)-$scriptstartsec);

######################################################



######################################################

:log info ("------------------------------------------");

:log warning ("Shaper:");

:log info ("MaxRate Download : " . $MaxRateDownload . " bps /" . $kbsmaxdown . " kbs / Upload : " . $MaxRateUpload . " bps /" . $kbsmaxup . " kbs");

:log info ("Active Users : Download : " . $activedowncount . " / Upload : " . $activeupcount );

:log info ("User Speed Download : " . $maxlimitdown . " bps /" . $kbsmaxlimitdown . " kbs / Upload : " . $maxlimitdown . " bps /" . $kbsmaxlimitup . " kbs" );

:log warning ("Performance Time: " . $scripttimedelay . " seconds.");

:log info ("------------------------------------------");

######################################################



######################################################

# (C) Inlarion icq 429-587 mikrotik.axiom-pro.ru Copyright!

######################################################









最新の願いについて




このバージョンでは、「Performance Time」システムログに新しい行が追加されていることがわかります。この行により、スケジューラでスクリプトの実行間隔を正しく設定できます。 「パフォーマンス時間」は、スクリプトの実行時間を秒単位で+ -1秒の精度で反映します。 この時間は、/ ip firewall address-list list = "users"に追加されたクライアントの数、microtikの負荷、およびスクリプトの実行間隔が誤って設定されると急激に増加するため、このパラメーターを常に監視する必要があります。



式:パフォーマンス時間+ 10-15秒に基づいて、スクリプトの実行間隔を設定します。 初めてスクリプトを実行するときは、間隔を1〜2分に設定します。理想的には、その時点でシステムが可能な限りビジーである場合です。



スクリプトパラメータ:


:local MaxRateDownload ("15000000");

:local MaxRateUpload ("15000000");

:local MaxRateDownloadNight ("20000000");

:local MaxRateUploadNight ("20000000");







以前にインターネットを使用したことがない別のユーザーがアクティブになったときにブレーキがかかるのを避けるために、チャネルの幅より少し小さく設定する必要があります。



:local ActiveThresholddown ("15000");

:local ActiveThresholdup ("15000");









必要に応じてこれらの値を設定しますが、計算に基づいて:Thresholddown =を掛けたユーザー数はMaxRateDownloadを超えてはなりません。そうしないと、ユーザーは常に非アクティブになります。 当然ユーザー* ActiveThresholdup = MaxRateUploadを超えてはなりません。 常にある程度のマージンを残します。



すべてに加えて、バージョン5.xでスクリプトを使用することの不適切性の質問は閉じられていることに注意してください。 バージョン5.0rc7をテストした後、以前のバージョンと比較してMikrotikの/ queueの動作が改善されたと確信しました。そのため、バージョン5.xではスクリプトは不要です。 しかし、開発者が許可するバグを考慮すると、5番目のバージョンへの切り替えの問題は非常に疑わしいです。 たとえば、rc3では、pingユーティリティは不器用でパラメーターを返しません.rc7では、テーブルで名前を使用するとルーティングが機能しませんが、以前のバージョンではすべてが正常に機能していました。 しかし、これはただのRCですが、すでに7番目であり、非常に心配です。



メイン部分は必要なくても/キューツリーを使用している場合でも、スクリプトを使用してルールを作成するだけで済みます。これは、ユーザーを追加または削除するときに非常に便利なことです。



All Articles