我正在寫一個算法,它接收消息,然後確定它們是否符合建立的消息速率。速率限制器不能正常工作
例如,在任何50秒的窗口中不會發送超過5條消息。因此,這個窗口必須是一個滾動窗口。
我已經從this post.實現了這個令牌桶算法但是,我不能一致地工作。它通過了一些測試用例,但不通過其他測試用例,這讓我認爲這裏隱藏着一個邏輯問題。
這是我到目前爲止有:
public class Messaging {
//times in millis
double time_before;
double time_now;
double now;
double time_passed;
double allowance;
//constants
static double per = 50000; // 50 seconds
static double rate = 5; //5 messages
public Messaging(){
time_before = System.currentTimeMillis();
allowance = rate;
}
public void onEvent(){
time_now = System.currentTimeMillis();
time_passed = time_now - time_before;
time_before = time_now;
allowance += time_passed * (rate/per);
if (allowance > rate){
allowance = rate;
System.out.println("Reset Allowance");
}
if (allowance < 1.0){
System.out.println("Discard");
}else{
System.out.println("Forward message");
allowance -= 1.0;
}
}
這不工作,雖然!
public static void main(String[] args) {
Messaging orders = new Messaging();
for (int i = 0; i < 10; i++) {
orders.onEvent();
try {
Thread.sleep(5000);
} catch (Exception ex) {
}
}
}
運行上面的代碼中給出了這樣的:
Forward message. Time: 1469830426910
Forward message. Time: 1469830431912
Forward message. Time: 1469830436913
Forward message. Time: 1469830441920
Forward message. Time: 1469830446929
Forward message. Time: 1469830451937
Forward message. Time: 1469830456939
Forward message. Time: 1469830461952
Forward message. Time: 1469830466962
Discard. Time: 1469830471970
Total time passed: 50067
爲什麼只被丟棄的最後一條消息?不應該允許遞減到第5條消息後自動失效嗎?
我希望能幫助您解決這個問題。實際的實現將採用沒有隊列的專有語言等。
我們不能告訴任何事情,因爲您的輸出沒有時間戳。我們無法告訴發生了什麼事。一個建議是:將過濾代碼從時間戳中分離出來,這樣無論調試如何,都可以爲其提供可重複的測試數據集。這將讓你逐步完成代碼並找出結果。 –
@JimGarrison我添加了時間戳輸出。我正在測試不同的變體,所以現在只需使用Thread.sleep來模擬每x秒發送一次的消息。通過代碼我可以告訴行'allowance + = time_passed *(rate/per);'是什麼造成了這個問題,但因爲我已經看到了很多實現上的相同的線,我想知道我是否特別做某事在我的錯誤或如果這個算法不適用於滑動窗口。 – cheenbabes
這不完全是他的意思 - 我正在寫一個答案,我希望能解釋它。 –