2011-01-26 77 views
1

我有一個隊列,沒有任何原因的停止,在這個隊列中,我已經實現了一個位置消息處理。在處理過程中,它會記錄並丟棄任何有毒消息。隊列停止(禁用)沒有任何有害消息

它一直很好了一年多的時間沒有停止。但最近(問題在四周前開始),它每週停止一次或兩次。只在本週它停了兩次。

當我用新的中毒信息檢查表時,沒有!當我啓用隊列時,處理將成功恢復,並且「毒訊」情況不會再現。

關於隊列的任務:每天接收約2-3000條消息。它用於在事務外運行存儲過程。每條消息都可以持續處理一段時間(進行大量選擇,插入和更新)。

讓我解釋一下這一點:數據庫具有在事務內觸發的觸發器,觸發器會發送消息在觸發器外運行一些代碼。異步行爲可防止丟棄數據庫的性能。

我發現即使在進行消息時發生死鎖,隊列也會將消息視爲中毒。所以原則上它不應該是一個性能問題。但是,它可以嗎?也許數據庫正在增長,處理消息的時間太長了?

但是,如果找不到它,我該如何找到它?
爲什麼其他原因隊列停止?
如何節約時間和與消息隊列中得到了禁用?
是否有人有任何想法,我該怎麼辦任何取證分析?
有什麼想法?


UPDATE揭露僞解決方案:
根據萊姆斯後,我試圖用事件通知得到確切時刻隊列停止時。

CREATE EVENT NOTIFICATION [QueueDisabledEN] 
    ON QUEUE [dbo].[ProcessQueue] 
    FOR BROKER_QUEUE_DISABLED 
    TO SERVICE 'Queue Watch Service', 'current database'; 

,然後檢查事件日誌:

select * from sys.event_notificiation 

但因爲它是很難知道的事件發生,(還有什麼是在momment運行?)環境,法醫分析在那裏結束。幸好我的經紀人服務實現存儲與運輸,收到的日期,日期處理日期的消息,...這幫助我檢測到3秒內的隊列上充斥着數百封郵件是需要很長時間來處理。

雖然我找到真正的解決方案只是暫時的解決辦法是用代理的工作就是檢查隊列中的每x分鐘的狀態,並啓用它:

IF (EXISTS(SELECT * FROM sys.service_queues WHERE name like 'ProcessQueue' AND (is_receive_enabled = 0 OR is_enqueue_enabled = 0))) BEGIN 
    PRINT convert(nvarchar, getdate(), 121)+ ': Activando la cola ProcessQueue' 
    ALTER QUEUE ProcessQueue WITH STATUS = ON 
END 

感謝萊姆斯!

回答

4

當您找到處於禁用狀態的隊列並且您啓用了回隊列時,我認爲處理成功恢復並且「有毒消息」情況不會再現。這將表明原因是短暫的或與時間有關。它可能是一個正在運行的SQL代理作業,並導致隊列處理髮生死鎖,迫使隊列處理回滾。根據我的經驗,死鎖是最典型的毒藥訊息原因。您的最佳取證工具是系統事件日誌,因爲激活的過程確實將錯誤輸出到ERRORLOG中,並因此輸入到系統事件日誌中。

每當有毒消息觸發器(5次連續回滾)禁用隊列時,就會觸發類型爲QUEUE_DISABLED的event notification。您可以在處理此事件時捕獲更多的取證信息,因爲它會在禁用隊列後立即運行。

作爲一個方面說明,你永遠不可能有真正的'毒訊息處理'。每當您增強處理以處理某些錯誤情況時,「有害消息」的定義更改爲該消息能夠禁用新的錯誤處理

+0

Hi @Remus Rusanu,關於毒藥信息處理:當然不是真正的和明確的'毒藥信息處理',但我認爲它是最接近我可以發現一個非常簡單的解決方案:如果3檢測到回滾,在接下來的「recibe-action」中,該消息將被直接解散以用於以後的分析。 任何可以避免隊列停止並達到5個連續回滾的地方。 ...但是當毒害信息被保存以供日後分析時,它可能會產生一個錯誤(由死鎖或瞬時問題引起)並達到第五次回退。 一種偏執,不是嗎? – Alex 2011-01-27 15:34:22