[英]token bucket algorithm, rate limiting javascript?
我正在嘗試編寫一個算法來防止在8秒內發送超過5條消息,我在python中找到了令牌桶算法的公式,所以我試圖用javascript實現它,但我錯過了一件事。
last_check
變量對我來說並不清楚。 如果我在一分鍾內跟蹤60秒,問題是在第59秒后它重新循環,數學被拋棄。
第一次迭代
如果last_check
= new Date().getSeconds()
讓我們說它在跟蹤的那一刻是33秒,我們現在比較33秒。
當rateLimit()
函數執行時,它獲取調用它的current
時間,例如消息, current
new Date().getSeconds()
是40秒,例如.... last_check
后7秒
所以time_passed
現在是7秒, last_checked
變成40。
津貼結果
allowance
為7 * (5.0/8.0) = 4.375
。
問題出在哪里
如果last_checked
保持在40,並且22秒通過直到新消息,則下面的第二次迭代的公式變為。
第二次迭代
current
變為2(40 + 22) new Date().getSeconds()
循環回到2 ... time_passed
現在是(2-40)= -38秒, last_checked
現在是2。
津貼結果
allowance
值為-38 * (5.0/8.0) = -23.75
。
var rate = 5.0; // unit: messages
var per = 8.0; // unit: seconds
var allowance = rate; // unit: messages
var last_check = new Date().getSeconds();
function rateLimit() {
current = new Date().getSeconds(); // floating-point, e.g. usec accuracy. Unit: seconds
time_passed = current - last_check;
last_check = current;
allowance += time_passed * (rate / per);
console.log('Current time: ' + current);
console.log('Time passed: ' + time_passed);
console.log('Last check: ' + last_check);
console.log('Allowance: ' + allowance);
if (allowance > rate) {
allowance = rate; // throttle
console.log('throttle');
}
if (allowance < 1.0) {
console.log('discard message');
return false;
} else {
allowance -= 1.0;
console.log('forward message');
return true;
}
}
我同意@ Evilzebra的評論,即解決方案可能有點復雜。 根據您所需的行為,我以這種方式實現它:
var ii = 0;
var perMils = per * 1000;
function rateLimit() {
if (ii <= rate) {
++ii;
setTimeout(function() {--ii;}, perMils);
return true;
}
return false;
}
在current - last_check
,您需要兩個日期之間的差異,而不是秒針的位置之間的差異。
用new Date().getSeconds()
替換new Date().getSeconds()
new Date().getTime()/1000
(或new Date().getTime()
但你必須用var per = 8000.0
替換var per = 8.0
)。
這將導致current - last_check
始終為正數秒(或毫秒),而不是當秒數翻轉到分鍾時為負數。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.