我有一個由第三方發佈的JMS隊列。 我想在不同的機器上設置多個使用者,只有一臺特定的機器使用者,確認該隊列上的消息。簡而言之,如果特定機器的消費者沒有收到消息,那麼不應該從隊列中刪除該消息。 這是可以實現的嗎?JMS - 一個隊列和很多接收者(消費者)
回答
好的,你可能有這個設置的原因,這很容易實現。
我會去與本地會話事務。根據某些標準提交或回滾事務是相當容易的,例如哪個服務器正在消費該消息。如果回滾,則消息將再次在隊列中首先結束。
示例代碼可能是這樣的:
public class MyConsumer implements MessageListener{
Session sess;
public void init(Connection conn, Destination dest){
// connection and destination from JNDI, or some other method.
sess = conn.createSession(true, Session.AUTO_ACKNOWLEDGE);
MessageConsumer cons = sess.createConsumer(dest);
cons.setMessageListener(this);
conn.start();
}
@Override
public void onMessage(Message msg) {
// Do whatever with message
if(isThisTheSpecialServer()){
sess.commit();
}else{
sess.rollback();
}
}
private boolean isThisTheSpecialServer(){
// figure out if this server should delete messages or not
}
}
如果您正在使用JTA在Java EE容器內這樣做的,你正在使用UserTransactions,你可以只調用UserTransaction.setRollBack(); 或者如果您正在使用聲明性事務,則只需讀取Runtime異常以使事務失敗並將消息回滾到隊列中,一旦您讀取了消息並完成了任務。請注意,使用這種方法數據庫更改也會回滾(如果您使用的是JTA而不是本地JMS事務)。
UPDATE:
你真的應該做到這一點使用的交易,而不是確認。
在這裏可以找到該主題的摘要(對於ActiveMQ,但通常爲JMS編寫)。 http://activemq.apache.org/should-i-use-transactions.html
我不知道這種行爲是與所有的JMS實現一致的,但如果的ActiveMQ您嘗試使用與Session.CLIENT_ACKNOWLEDGEMENT非事務會話,那麼就不會真正表現爲您預期。已經被讀取但未被確認的消息仍然在隊列中,但不會被「釋放」並被傳遞給其他JMS使用者,直到連接斷開到第一個使用者(即connection.close(),崩潰或類似)。
使用本地事務,您可以通過顯式地控制session.commit()和session.rollback()。我沒有看到沒有使用交易的真正意義。確認只是爲了保證交付。
供參考:回滾將增加JMSXDeliveryCount。 JMS隊列配置爲在JMSXDeliveryCount達到閾值後將消息移動到退出隊列。 – Shashi 2012-07-16 03:28:36
在這裏使用交易並不能幫助你,除了確保你從頭到尾加入JTA交易。 – 2012-07-16 17:29:49
當然,但可以配置退貨閾值(取決於供應商)。現在的問題仍然是爲了全面瞭解這個問題。 – 2012-07-16 18:59:59
查看此問題的另一種方法是在轉發隊列的情況下。您可以通過執行以下操作將它應用於您的設計:
- 在第三方發佈的隊列中創建消費者。
- 這位消費者有一份工作 - 將每封郵件分發給其他隊列。
- 創建您的真實用戶將收聽的其他隊列。
- 將您的消息監聽器編碼爲接收每條消息並將其轉發到各個目標。
- 更改每個偵聽器以從其特定隊列中讀取。
通過這樣做,可以確保每一位聆聽者看到的每封郵件,每一筆交易正常工作,而你不知道如何才能發送消息的任何假設(例如,如果發佈方是什麼做AUTO_ACKNOWLEDGE
?)
- 1. 生產者 - 消費者多個生產者多個隊列單個消費者
- 2. JMS隊列消費者:同步接收()或單線程onMessage()
- 3. 多個消費者一個隊列
- 4. JMS - 消費者在消費之前瀏覽隊列消息
- 5. 鎖定免費隊列 - 單個生產者,多個消費者
- 6. 一個隊列的Spring JMS配置消費者
- 7. JBOSS 7.1中隊列的JMS生產者/消費者最終
- 8. 隊列爲多個生產者和消費者
- 9. Pentaho JMS消費者 - 對單個消費者的多個生產者
- 10. 對於單個生產者和消費者,JMS隊列是否遵循FIFO?
- 11. 消費者過濾的生產者 - 消費者阻塞隊列
- 12. 單個生產者多個消費者 - 隊列包含null
- 13. 生產者/消費者工作隊列
- 14. 生產者消費者阻止隊列
- 15. Apache的駱駝發送消息JMS消費者接收消息
- 16. AMQP - 隊列中有多少消費者?
- 17. 製片人 - 消費者Scenerio。我有一個生產者和多個消費者
- 18. 同步生產者,消費者和生產者隊列
- 19. JMS隊列接收消息?
- 20. JMS拓撲結構(排隊多個消費者)和消息分組
- 21. Spring JMS消費者拉動
- 22. 多生產者多消費者無鎖(甚至等待)隊列
- 23. 轉:一個生產者很多消費者
- 24. ActiveMQ一個生產者多消費者
- 25. 單隊列:多個消費者同時處理消息
- 26. RabbitMQ從多個消費者隊列序列化消息
- 27. 線程安全FIFO /隊列(多個生產者,一個消費者)
- 28. 如何限制ActiveMQ JMS隊列中消費者的數量
- 29. JBoss消息隊列卡住,遠程接口和MDB消費者
- 30. rabbitmq中的多個消費者爲多個隊列
不知道是什麼原因,我想所有的消費者都必須收到消息,但只有一個特定的消費者會承認這個消息。如果情況並非如此,那麼爲什麼你想讓同一隊列中有多個消費者? – Shashi 2012-07-16 03:22:43