2008-11-01 125 views
16

我一直在體驗真實生產環境中的消息傳遞系統的優缺點,我必須承認,每當有任何其他表單時,組織良好的表格或表格架構因爲:消息系統中的表對隊列

  1. 數據永久存儲在表中。我見過很多java(jms)應用程序,它們在未捕獲的異常或其他錯誤的途中丟失或消失了消息。
  2. 隊列傾向於填滿。相反,DB存儲實際上是無限的。
  3. 表格很容易訪問,而您必須使用esotic工具從隊列中讀取。

對於每種方法,您有什麼看法?

回答

33

短語每次跳動完全取決於您的要求開始。當然,每個人都不會打敗他們。

如果您正在構建其已經使用的數據庫的單一系統,你沒有非常高的性能吞吐量要求和你沒有任何其他球隊或系統,那麼你可能是正確的溝通。

對於簡單的,低thoughput,多爲單螺紋的東西,數據庫是一個完全細替代消息隊列。

當一個消息隊列照時

  • 你想有一個高性能,高併發的和可擴展的負載均衡,所以你可以同時在多個服務器/進程每秒處理的消息數萬(使用一個數據庫表你會幸運地處理幾百第二和處理多線程是相當困難的一個過程將趨於鎖定消息隊列表)
  • 你需要使用不同的數據庫不同的系統之間進行通信(所以不要」不得不將寫入權限交給系統數據庫給不同團隊中的其他人)

對於簡單的系統與一個單一的數據庫,團隊和相當適度的性能要求 - 務必使用一個數據庫。使用正確的工具進行這項工作等等。

但是,消息隊列閃耀的地方在於大型組織需要相互通信的大量系統(因此您不希望業務數據庫成爲中心故障點或地獄版)或者當你有高性能要求時。

在性能方面,消息隊列將始終擊敗數據庫表 - 因爲消息隊列是專門爲該作業設計的,並且不依賴悲觀表鎖(這是數據庫實現隊列所需的 - 要做負載平衡)和good message queues will perform eager loading of messages to queues to avoid the network overhead of a database

同樣 - 你不會使用數據庫在你的web服務器上對HTTP請求進行負載平衡 - 因爲它太慢了 - 如果你的負載平衡器有很高的性能要求,你不會使用數據庫無論是。

2

隊列提供可靠的消息。存儲轉發,排隊的連接性使得它比數據庫更具可擴展性,更不用說更強大的了。

隊列不應該用於永久存儲信息 - 最好將它們視爲臨時收件箱,不像數據庫。

9

我已經先使用過表格,然後當(如果)有原因時重構成一個完整的消息隊列 - 如果您的設計合理,這是微不足道的。如果你知道數據庫工具真的很好,它比使用它更容易,(b。它是一個更好的審計線索,因爲你有其他表加入到c)。 Message Queue工具,d。)在已經存在的應用程序的上下文中設置測試/開發環境通常會更容易一些(如果適用相同的熟悉情況)。

哦,和e。)對於也許你和其他人,它不是學習,安裝,配置,管理和支持的另一種產品。

IMPE,它同樣可靠,可以斷開連接,如果需要更大的可擴展性,您可以進行轉換。

8
  1. 數據永久存儲在一張桌子上。我見過很多java(jms)應用程序,它們會在未捕獲的異常或其他錯誤的方式中散播或消失消息。

    哪個JMS實現? Sun銷售可靠的隊列,不會丟失消息。也許你只是購買了俗氣的JMS兼容產品。 IBM的MQ非常可靠,並且有JMS庫可以訪問它。

  2. 隊列傾向於填滿。相反,DB存儲實際上是無限的。

    嗯......如果你的隊列填滿了,那聽起來好像有些東西壞了。如果你的應用程序崩潰,那不是一件好事,隊列與此無關。如果你購買了一個非常差的JMS實現,我可以看到你可能會對它感到不滿。這是一個有競爭力的市場。找一個更好的隊列管理器。 Sun的JCAPS有一個非常好的隊列管理器,以前是SeeBeyond消息隊列。

  3. 表格很容易訪問,而您必須使用esotic工具從隊列中讀取。

    這不符合我的經驗。通過這種特殊的「其他語言」(SQL)訪問表,並且要求我知道從表到對象的結構映射以及從VARCHAR2到String的數據類型映射。此外,我必須使用某種訪問層(JDBC或使用JDBC的ORM)。這似乎非常非常複雜。通過MessageConsumers和MessageProducers使用簡單的發送和接收來訪問隊列。

+1

太艱苦設法詆譭海報的(顯然是實質性的)個人經驗。不是每個人都對你的問題和選擇有高度的熟悉。 – dkretz 2008-11-01 18:59:47

+2

這就是SO的全部重點:熟悉程度低的人從熟悉程度高的人那裏學習。這就是爲什麼這樣的答案應該被投票決定,而不是失敗。 – 2008-11-01 21:06:20

6

聽起來好像你遇到的問題並不是消息傳遞所固有的,而是實施不良的消息傳遞系統的工件。構建消息傳遞系統比構建數據庫系統更困難嗎?是的,如果你所做的只是構建數據庫系統。

  • 將消息丟失爲未捕獲的異常?這幾乎不是消息隊列的錯誤。您使用的應用程序設計不佳。他們在處理完成之前從隊列中刪除消息。他們沒有使用交易,也沒有使用交易。
  • 當數據庫存儲爲「幾乎無限」時,消息隊列填滿了嗎?你說好像管理磁盤空間是數據庫不需要的東西。消息隊列服務器需要管理,就像數據庫服務器一樣。
  • 從隊列中讀取的深奧儀器?也許如果你發現異步方法深奧。也許如果你發現序列化和反序列化是很深奧的。 (至少,這些是我在學習消息時發現的深奧的東西,就像很多看似深奧的技術一樣,一旦你瞭解它們,它們實際上是非常平凡的,理解它們是經驗豐富的開發者教育的重要組成部分。)
  • 消息的

方面,使其優於數據庫:

  • 異步處理。消息隊列在新消息到達時通知等待進程。爲了在數據庫中完成此功能,等待進程必須輪詢數據庫。
  • 分離關注點。通信通道與消息內容的實現細節分離。只有發送者和接收者需要知道給定消息中的數據流格式。
  • 容錯。。當服務器間的連接間歇時,消息傳遞可以起作用。消息隊列可以在本地存儲消息,並且只在連接處於活動狀態時纔將其轉發到遠程服務器。
  • 系統集成。在Windows世界裏,至少,消息傳遞是內置在操作系統中的。它使用操作系統的安全模型,通過操作系統的工具進行管理等。

如果你不需要這些東西,你可能不需要消息傳遞。

下面是消息應用程序的一個簡單示例:我現在正在構建一個系統,其中用戶分佈在多個網絡中,正在進入相當複雜的用於生成打印輸出的事務集。輸出生成在計算上是昂貴的,而不是其工作流程的一部分;即用戶不關心輸出什麼時候產生,就是這樣做。

因此,我們將事務序列化爲消息並將其放入隊列中。運行在服務器上的進程從隊列中獲取消息,生成輸出並將輸出存儲在映像系統中。

如果我們使用的數據庫作爲我們的郵件存儲,我們不得不拿出一個方案來存儲,現在只有發送者和接收者關心,我們需要確保每個工作站上的交易格式網絡與數據庫服務器有永久的持續連接,我們沒有能力將這種事務負載分佈到多個服務器上,而且我們的輸出服務器必須每天查詢數據庫數千次,等待查看是否有新的作業要處理。