ActiveMQ重复消息检测(Wildfly,Java EE)

时间:2018-09-26 02:40:16

标签: queue jms activemq-artemis

首先,对不起我的英语! 我有一个使用JMS和ActiveMQ的项目

@Stateless
@LocalBean
public class Producer {

public void produceMessage(List<String> entityIds) {
  try {
    InitialContext initialContext = new InitialContext();
    ConnectionFactory connectionFactory = (ConnectionFactory) initialContext.lookup("java:/JmsXA");
    Destination destination = (Destination) initialContext.lookup("jms/queue/cachedAttrs");

    Connection connection = connectionFactory.createConnection();
    Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
    MessageProducer producer = session.createProducer(destination);
    producer.setDeliveryMode(DeliveryMode.PERSISTENT);

    entityIds.forEach(entityId -> {                 
                TextMessage message = session.createTextMessage(entityId);
                message.setStringProperty("_AMQ_DUPL_ID", entityId);
                producer.send(message);                     
        }
    );

    connection.close();
    session.close();
    initialContext.close();
  } catch (Exception e) {
    throw new IllegalStateException("..." + e.getMessage());
  }
 }
}

@MessageDriven(
  name = "Consumer",
  activationConfig = {
    @ActivationConfigProperty(propertyName = "destination", propertyValue = 
"jms/queue/cachedAttrs"),
    @ActivationConfigProperty(propertyName = "destinationType", propertyValue = 
  "javax.jms.Queue"),
    @ActivationConfigProperty(propertyName = "useDLQ", propertyValue = "false")
  }
)
public class Consumer implements MessageListener {  

@PersistenceContext
private EntityManager entityManager;

@Override
public void onMessage(Message message) {
  TextMessage id = (TextMessage) message;
}
}

Producer.produceMessage()可以在项目的许多地方同时调用。如果此ID包含在队列中,我需要检查重复的ID,而不是调用Consumer作为ID。

我读了https://activemq.apache.org/artemis/docs/1.0.0/duplicate-detection.html 并这样做

message.setStringProperty("_AMQ_DUPL_ID", entityId);

呼叫生产者:

producer.produceMessage(Arrays.asList("1", "2", "1", "3", "2"));

并获得异常:

  

起因:ActiveMQDuplicateIdException [errorType = DUPLICATE_ID_REJECTED       message =检测到重复消息-消息将不会被路由。消息信息:ServerMessage [messageID = 266288062339,durable = true,userID = 0c03aadc-c07a-11e8-9fb7-775c9c2bdfeb,优先级= 4,bodySize = 225,时间戳= Tue Sep 25 11:18:25 GMT + 07:00 2018,到期= 0,持久= true,地址= jms.queue.deviceCachedAttrs,属性= TypedProperties [__ AMQ_CID = f627a880-c079-11e8-9fb7-775c9c2bdfeb,_AMQ_DUPL_ID = 1]] @ 1895765804]   在org.apache.activemq.artemis.core.protocol.core.impl.ChannelImpl.sendBlocking(ChannelImpl.java:406)   在org.apache.activemq.artemis.core.protocol.core.impl.ChannelImpl.sendBlocking(ChannelImpl.java:304)   在org.apache.activemq.artemis.core.protocol.core.impl.ActiveMQSessionContext.xaPrepare(ActiveMQSessionContext.java:457)   在org.apache.activemq.artemis.core.client.impl.ClientSessionImpl.prepare(ClientSessionImpl.java:1241)

我做错了什么? 我可以在服务中@Inject我的Producer还是需要创建新对象? 谢谢!

1 个答案:

答案 0 :(得分:0)

据我所知,您没有做错任何事情。根据您所说的,您需要经纪人拒绝重复的消息。您已经在消息中设置了重复ID,并且代理检测到重复消息,但该消息已被拒绝。请注意,该异常显示为“检测到重复消息-消息不会被路由。”