2010-08-08 338 views
2

我想有選擇地從AMQP隊列中刪除消息,甚至不讀取它們。如何有選擇地從AMQP(RabbitMQ)隊列中刪除消息?

的情況如下:

發送方要到期基於一個事實,即X型的新信息到達X型的消息。因爲用戶很可能沒有使用類型爲X的最新消息,所以發佈者應該刪除先前的X型消息並將最新消息放入隊列中。整個操作對用戶來說應該是透明的 - 事實上,他應該使用像STOMP這樣簡單的東西來獲取消息。

如何使用AMQP執行此操作?或者在另一個消息協議中更方便?

我想避免複雜的基礎結構。所需的全部消息與上述一樣簡單:一個隊列,一個訂閱者,一個發佈者,但發佈者必須能夠根據給定標準臨時刪除消息。

發佈者客戶端將使用Ruby,但實際上我會盡快處理任何語言,只要我發現如何在協議中執行此操作。

回答

4

您目前不能在RabbitMQ(或更一般地說,在AMQP中)自動執行此操作。但是,這是一個簡單的解決方法。

假設你想發送三種類型的消息:Xs,Ys和Zs。如果我正確理解您的問題,當X消息到達時,您希望代理人忘記所有尚未交付的其他X消息。

這是相當容易的RabbitMQ做到:

  • 生產者聲明瞭三個隊列:X,Y和Z(它們會自動綁定到他們的名字作爲路由鍵,這是默認的交換正是我們想要的),
  • 發佈消息時,生產者首先清除相關隊列(因此​​,如果它發佈X消息,它首先清除X隊列);這有效地消除了過時的消息,消費者從它想要的隊列中簡單消費(X代表X消息,Y代表Y消息等);從它的角度來看,它只需要做一個basic.get來獲得下一個相關的消息。

這意味着兩個生產者幾乎同時發送相同類型的消息時的競爭條件。其結果是它可能使隊列同時具有兩個(或更多)消息,但是由於消息的數量被生產者的數量所限制,並且由於多餘的消息在下一次發佈時被清除,這應該不是什麼大問題。

總之,該解決方案具有最佳的解決方案只是一個額外的步驟,即清除出版類型X的消息之前隊列X

如果您需要任何幫助建立這樣的配置,完善的地方問徵求意見是rabbitmq-discuss郵件列表。

+0

在我的情況下,使用隊列的唯一原因是X,Y,Z事件是交錯的,用戶應該按照它們來的順序讀取它們 - 但只有最新的X,最新的Y和最新的Z.而且,類型數量是數千的順序,所以用戶不會聽到數千個隊列。 – 2010-08-09 00:55:46

+0

啊。聽成千上萬的隊列不會有問題(幾乎沒有開銷)。一旦他們在隊列中,你不能真正有選擇地刪除消息。它發生在我身上,你想要的是一個支持原子移動操作的文件服務器:發佈者啓動wrtiting到一個臨時文件中,當它完成時,將該文件移動(重命名)爲X;客戶端然後只讀取文件X. – scvalex 2010-08-09 09:09:01

6

你不想要一個消息隊列,你想要一個鍵值數據庫。例如,您可以使用Redis或Tokyo Tyrant獲取簡單的網絡可訪問鍵值數據庫。或者只是使用一個memcache。

每種消息類型都是一個關鍵。當您使用相同的密鑰編寫新消息時,它會覆蓋之前的值,因此此數據庫的讀者將永遠無法獲得過期信息。

在這一點上,只需要一個消息隊列來確定密鑰的讀取順序,如果這很重要的話。否則,只需不斷掃描數據庫。如果您不斷掃描數據庫,最好將數據庫放在讀取器附近以減少網絡流量。

我可能會做這樣的事情 key: typecode value: lastUpdated, important data

然後我會發送包含 typecode, lastUpdated這樣讀者可以比較LASTUPDATED爲關鍵,他們上次從數據庫中讀取一個消息,並跳過讀它因爲它們已經是最新的了。

如果您確實需要使用AMQP執行此操作,請使用RabbitMQ和自定義交換類型,特別是最後一個值緩存交換。示例代碼在這裏https://github.com/squaremo/rabbitmq-lvc-plugin

1

此問題由於其標題而具有很高的可見性。通過描述詳述了更具體的情況。 那麼誰正在尋找真正從隊列中刪除下一個(記得FIFO)消息的用戶,你可以利用rabbitmqadmin併發出以下命令:

rabbitmqadmin get queue=queuename requeue=false count=1

該命令主要消費信息並無所事事。帶有標誌的完整命令可用於備份消息,如下所示。確保根據您的要求添加任何其他參數。

sudo python rabbitmqadmin -V virtualhostname -u user -p pass get queue=queuename requeue=false count=1 payload_file=~/origmsg

0

這似乎從RabbitMQ的網絡UI也行,如果你只是想從隊列

  • 除去第一n條消息選擇選項卡「隊列」的隊列中,向下滾動章節「獲取信息」
  • 參數設定「重新排隊=否」,你想從隊列中刪除
  • 按「獲取信息」的消息的數字按鈕
相關問題