所有其他指标均无用
對于隊列,無論是實現為JMS ,數據庫表(即Ruby的Delayed :: Job用于隊列的什么),甚至是Amazon的SQS ,用于評估隊列狀態的最常見指標是其長度。 從本質上講,可以基于在任何給定時間隊列中駐留多少消息來得出效率度量。 如果只有幾條消息,則表明隊列正在高效地運行。 如果有很多消息,則說明效率低下,必須發出警報。
但是,如果您處于持續繁忙的環境中,并且隊列突然出現快速填充的趨勢,那該怎么辦? 如果你有足夠的工人已經在運行來處理突發,你需要更多的火起來?
您可以解雇更多的工人,但這樣做可能會花費您。 也就是說,您可能必須設置新的工作程序實例,例如Heroku工作程序dynos或AWS AMI,這最終將使您花費大量的金錢。 有時,這些工作人員實例需要一些時間來啟動,當它們開始運行時,活動爆發已經結束,隊列又恢復了正常–最初可用的工作人員充分地處理了負載。
事實證明,隊列的長度是一個滯后指標。 您浪費了不必要的資源。 錯誤的警報!
如果您已經有足夠的能力來處理隊列中的消息大量涌入,那么監視隊列的長度就不會有太大幫助。 實際上,這是一個誤導性指標,可能會導致您采取不必要的操作。
因此,當已經有足夠的工人在場時,隊列的長度并不表示系統的效率 。 相反,在高容量環境中意味著某些事情的度量標準是消息在隊列中駐留的時間 。 這是一個可行的指標:如果消息被卡在隊列中等待處理,那么您需要更多的處理器!
Moo超過隊列長度,讓隊列等待時間
默認情況下, Amazon的SQS不提供查詢消息已在隊列中保留多長時間的功能。 因此, 我寫了Moo 。
Moo為客戶端提供了一個接口,該接口可用于獲取隊列度量標準中的消息時間并對其采取措施。 這是通過使用時間戳擴展SQS消息來完成的。 然后,當從SQS隊列中彈出消息時,將檢查該時間戳。 如果超過閾值差,則調用回調。
Moo的用戶會發現它的用法類似于Ahoy! ,它是AWS Java SDK之上的面向異步回調的外觀。 實際上,Moo使用Ahoy! 在下面,帶有附加功能,即附加“最大排隊時間”異步回調。
Moo支持多個隊列時間閾值,并且設置最大隊列時間的方法如下:
為隊列中的時間添加最大閾值
//adds a 1 second max threshold
sqs.addQueueWaitTimeCallback(1000, new QueueWaitTimeCallback() {public void onThresholdExceeded(long waitTime) {//waitTime is the actual time in queue//do something... like fire off a web hook, etc}
});請注意, addQueueWaitTimeCallback方法在隊列值和相伴的QueueWaitTimeCallback回調實現中花費的最長時間為毫秒。 如果超過最大閾值,則在消息接收期間將異步調用onThresholdExceeded方法;否則,將被onThresholdExceeded 。 此外, onThresholdExceeded將接收實際隊列等待時間作為參數。
告訴我Mo
要啟動Moo實例,您有多種選擇,包括配置AWS的AmazonSQS實例或僅傳遞密鑰,機密和隊列名稱,如下所示:
為隊列中的時間添加最大閾值
SQS sqs = new SQS(System.getProperty("key"), System.getProperty("secret"), System.getProperty("queue"));接下來,您可以將零附加到許多QueueWaitTimeCallback實例,如下所示:
為隊列中的時間添加最大閾值
sqs.addQueueWaitTimeCallback(600000, new QueueWaitTimeCallback() {public void onThresholdExceeded(long actualWaitTime) {//do something -- fire off SNS message?}
});在這種情況下,如果消息在隊列中的時間超過10分鐘,我將添加一個要調用的回調。 注意,這些QueueWaitTimeCallback回調由隊列讀取器實例觸發。 因此,例如, QueueWaitTimeCallback當然可以啟動其自身的更多實例。
這是一個示例JSON文檔,您可能希望將其放入SQS隊列中:
為隊列中的時間添加最大閾值
{ "employees":[{ "firstName":"John", "lastName":"Doe" },{ "firstName":"Anna", "lastName":"Smith" },{ "firstName":"Peter", "lastName":"Jones" }
]}發送和接收此消息與使用Ahoy!時完全一樣。 例如,要發送消息,只需將String傳遞給send方法:
為隊列中的時間添加最大閾值
sqs.send(json, new SendCallback() {public void onSend(String messageId) {//messageId is from SQS}
});注意, send方法帶有一個可選的SendCallback 。
通過receive方法接收消息,該方法需要一個強制的ReceiveCallback – 對于從隊列中接收到的每個消息,該回調將被異步調用。 每個實例將接收放置在隊列中的消息以及消息的SQS ID。
為隊列中的時間添加最大閾值
sqs.receive(new ReceiveCallback() {public void onReceive(String messageId, String message) {//do something w/the message -- in this case it's JSON}
});注意,如果在收到消息后,Moo注意到消息在隊列中等待的時間超過為關聯的QueueWaitTimeCallback配置的最大隊列等待時間閾值,則Moo將調用它。 注意,Moo可以調用多個實例。 因此,您可以建立一條鏈來隨著時間的增加采取各種行動。
請記住,隊列的長度通常是一個滯后指標。 實際含義的度量標準是消息在隊列中的停留時間。 這是一個可行的指標, Moo使您能夠對此做點事情! 你能挖一下它么?
翻譯自: https://www.javacodegeeks.com/2013/10/all-other-metrics-are-useless.html
總結
- 上一篇: 手机圈的金九银十来了 苹果、华为、蔚来领
- 下一篇: Apache ActiveMQ 5.9发