Sql-Server
關於如何在 Service Broker 中組織隊列的建議
我有一個服務代理應用程序,目前在兩台伺服器上有 5 或 6 個隊列。
一般的工作流程是:
伺服器 A
- 使用者填充一些表
- 使用者觸發儲存過程,將消息放入標頭隊列中,指示有工作要做
- Broker 從這個頭隊列中讀取數據並創建大量消息發送到伺服器 B
伺服器 B
- 消息全部進入 1 個隊列
- 在這個隊列中,消息被檢查和解綁,有效負載被執行,並且從我們與之互動的另一組過程/表中收集響應
- 創建響應消息並將其發送回伺服器 A
伺服器 A
- 響應消息進入一個特殊隊列並用於更新使用者在頂部填充的表
- 結束對話消息從發起者隊列中讀取,並用於更新另一個跟踪標頭記錄進度的表(即處理的 100 條消息中的 50 條)
- 當我們檢測到標頭記錄已被完全處理時,一條新消息被發送到另一個發送通知電子郵件的隊列
我建議在伺服器 A 上整合其中一些隊列,但我不確定最佳實踐是什麼。其中兩個隊列將具有相對較高的消息處理量,而電子郵件隊列將非常慢。
我們(我認為)在管理消息類型方面做得很好,所以理論上我們可以將它們全部放入一個隊列中,並且應用程序仍然可以執行。
在這種情況下何時維護單獨的隊列以及何時合併是否有最佳實踐?
這是一個懸而未決的問題,沒有明確的選擇。YMMV 所以你必須測試。以下是我的看法:
如果您希望能夠控制啟動任務的數量,那麼擁有一個隊列來處理所有事情是一個不錯的選擇,因為沒有全域 max_queue_readers。除此之外,我沒有看到很多優點。有人可能會爭辯說,單個啟動的過程更容易維護,但我認為在創建 SSB 啟動過程時應該使用某種模板/程式碼生成,因為通常大部分是千篇一律的程式碼,很少是特定於服務業務邏輯的。
但是,我可以看到單個隊列的幾個潛在問題,並且它們都是僅在事情已經變得糟糕(即在壓力/負載下)時才會出現的問題:
- 延遲和處理序列化。只有一個隊列可以將 max_queue_readers 保持在最大值,並且讓需要很少處理的消息坐在隊列中等待輪到它們被拾取。單獨的隊列允許低延遲服務快速耗盡其隊列,而高負載隊列以自己(較慢)的速度流失。
- 任何服務的消息高峰都會影響所有服務。與上述相同,但用於尖峰。大量消息的轉儲(例如,一些手動的“我們需要重新處理這 1MM 項”)將導致同一隊列中的所有其他服務等待直到峰值耗盡,然後才能訪問它們的消息(是由於會話組鎖定,有點複雜,但最終處理是 FIFO)。
- 可以避免參觀大排長龍的醜陋之地。如果您的 RAM/IO/CPU/啟動程式碼在 N 條消息中出現大隊列問題,則所有服務的一個隊列將比每個服務一個隊列更快/更頻繁地達到 N。
一般來說,我的建議是為每個服務設置一個隊列。