首先,对不起我的英语! 我有一个使用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还是需要创建新对象? 谢谢!
答案 0 :(得分:0)
据我所知,您没有做错任何事情。根据您所说的,您需要经纪人拒绝重复的消息。您已经在消息中设置了重复ID,并且代理检测到重复消息,但该消息已被拒绝。请注意,该异常显示为“检测到重复消息-消息不会被路由。”