我有一个由第三方发布的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. JMS队列消费者:同步接收()或单线程onMessage()
- 2. 多个消费者一个队列
- 3. 锁定免费队列 - 单个生产者,多个消费者
- 4. JBOSS 7.1中队列的JMS生产者/消费者最终
- 5. 队列为多个生产者和消费者
- 6. Pentaho JMS消费者 - 对单个消费者的多个生产者
- 7. 对于单个生产者和消费者,JMS队列是否遵循FIFO?
- 8. 消费者过滤的生产者 - 消费者阻塞队列
- 9. 单个生产者多个消费者 - 队列包含null
- 10. Apache的骆驼发送消息JMS消费者接收消息
- 11. AMQP - 队列中有多少消费者?
- 12. JMS队列接收消息?
- 13. 制片人 - 消费者Scenerio。我有一个生产者和多个消费者
- 14. 同步生产者,消费者和生产者队列
- 15. JMS拓扑结构(排队多个消费者)和消息分组
- 16. Spring JMS消费者拉动
- 17. 多生产者多消费者无锁(甚至等待)队列
- 18. ActiveMQ一个生产者多消费者
- 19. RabbitMQ从多个消费者队列序列化消息
- 20. 线程安全FIFO /队列(多个生产者,一个消费者)
- 21. 如何限制ActiveMQ JMS队列中消费者的数量
- 22. JBoss消息队列卡住,远程接口和MDB消费者
- 23. rabbitmq中的多个消费者为多个队列
- 24. Fober et al无锁定FIFO队列:多个消费者和生产者?
- 25. JMS生产者和消费者花费太多时间。为什么?
- 26. JAVA - 并发 - 多生产者/多消费者请求和响应队列
- 27. 生产者和消费者的Java同步队列线程
- 28. 多个生产者,单个消费者
- 29. 单生产者单一消费者队列与“阻塞”流行
- 30. 当我使用多个消费者时同步接收消息
不知道是什么原因,我想所有的消费者都必须收到消息,但只有一个特定的消费者会承认这个消息。如果情况并非如此,那么为什么你想让同一队列中有多个消费者? – Shashi 2012-07-16 03:22:43