添加到Activemq队列时如何识别重复消息

时间:2019-05-14 09:42:27

标签: java spring spring-boot jms activemq

我正在Spring Boot应用程序中使用ActiveMq设置JMS。但是无法理解如何阻止发件人(消息提供者)将重复的消息添加到队列中。

我的应用程序的初始JMS和消息转换器bean配置如下

@Bean
    public Queue queue() {
        return new ActiveMQQueue("pendingDocuments.queue");
    }


@Bean 
 public MessageConverter jacksonJmsMessageConverter() {
       MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
            converter.setTargetType(MessageType.TEXT);
            converter.setTypeIdPropertyName("_type");
            return converter;
        }

发送方方法实现

@Autowired
private JmsMessagingTemplate jmsMessagingTemplate;

@Autowired
private Queue pendingDocumentsQueue;

public void getPendingDocuments(){

/*My Custom Java Object, Actually these objects will read from DB for every 5 min, so process no way to know either these are already added to queue or not*/

Document document= new Document();
document.setUniqueId("122212");
document.setContent("TEST CONTENT");
this.jmsMessagingTemplate.convertAndSend(this.pendingDocumentsQueue, document);

        }

我想知道如何根据文档唯一ID将消息(我的文档对象)添加到队列中。

1 个答案:

答案 0 :(得分:0)

如果我理解正确,那么即使在发生崩溃的情况下,您也试图阻止您的通信处理重复的消息?

通常,您不应该有重复项(ActiveMQ不会“自行创建”重复项),但是如果您考虑可能的失败点(发件人崩溃,经纪人崩溃,消费者崩溃),您会看到发件人和经纪人不能做出“重复”的决定,除非消费者告诉他们实际处理的最后一条消息。

这可能是由于从消费者到代理的内部ACK(防止丢失消息,但没有重复)或通过使用JMS事务(也可以防止重复)而发生的。如果您通过jmsTemplate.setSessionTransacted(true); (see here) 使发送者和消费者使用事务处理会话,则将使用以下协议重复进行免费通信:

  1. 发件人从持久性存储(可能是数据库)中检查下一步 唯一ID是。
  2. 发件人发送消息。
  3. 发件人在同一时间提交交易     时间记录了处理此UniqueID的时间。
  4. 经纪人将使用唯一的交易ID传递此消息。
  5. 消费者收到消息。
  6. 消费者处理此UniqueID,并同时提交     交易。