2012-03-02 70 views
7

我要描述的實質上是兩個不同系統之間的兩階段提交問題,我正在尋找如何處理它的建議。在我們的Web應用程序中,我們將一些昂貴的/第三方操作(例如發送電子郵件)轉移到帶外後臺工作進程(我們稱之爲我們的工作基礎結構)。兩階段提交 - 如何有效使用我的隊列?

要發送電子郵件,我們在數據庫中創建了一個電子郵件對象和電子郵件作業。然後,我們必須等待我們的工作監視器收取電子郵件作業併發送它。作業監視器基本上是在閒置時每隔幾秒輪詢一次數據庫。

但是,這會在電子郵件發送中添加一個延遲,並將添加的數據添加到數據庫的非法負載中。如果我們可以在電子郵件創建後立即將電子郵件作業放到隊列中,那將會更好。

但是,這目前失敗的原因有兩個。首先,隊列通常比網絡請求快得多。在Web請求提交數據庫事務之前,該電子郵件會被拾取以供處理,因此無法正確生成電子郵件。其次,如果Web請求失敗,它將回滾其數據庫事務,這意味着電子郵件應該發送而不是。但是,如果已經放入隊列中,則不再處於請求的控制之下。

在隊列和數據庫之間創建兩階段提交是否有很好的策略?作爲參考,我們使用RabbitMQ和MySQL與InnoDB表。我提出的一個想法是在數據庫事務提交後將電子郵件作業粘貼到隊列中,但這會使電子郵件從不會排隊。我仍然必須創建一個輪詢過程來監視應該發送但不發送的電子郵件。

回答

0

我意識到這是一個晚了幾年:)但我想爲這個問題添加一些想法。

您可以延遲發送消息以增加作業獲取時數據庫準備就緒的機會。我從來沒有使用過RabbitMQ,但是我發現使用rabbitMQ隊列作爲延遲隊列How to create a delayed queue in RabbitMQ?的例子。您的電子郵件工作仍然需要處理任何未註釋的記錄,因爲延遲不是處理分佈式處理的確定性方法。

這就是說,它覺得有空間來改善你的設計。通常服務體系結構在服務之間共享數據庫表是一個壞主意。它導致分佈式事務和擴展問題。我會盡力確保RabbitMQ消息包含獨立於任何其他服務處理電子郵件所需的所有數據。或者如果它需要更多數據,它應該通過ServiceBus請求而不是數據庫查詢請求該數據。