【发布时间】:2019-09-26 02:25:52
【问题描述】:
以下代码尝试使用 JMS 在队列上发送消息。
connection = jmsConnectionFactory.createConnection();
connection.start();
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Destination destination = session.createQueue(queueName);
MessageProducer producer = session.createProducer(destination);
producer.setDeliveryMode(DeliveryMode.PERSISTENT);
它大部分时间都可以工作,但是在运行并行发送许多消息的压力测试时,我发现了一次以下异常:
Caused by: javax.jms.IllegalStateException: The producer is closed
at org.apache.activemq.ActiveMQMessageProducer.checkClosed(ActiveMQMessageProducer.java:195)
at org.apache.activemq.ActiveMQMessageProducerSupport.setDeliveryMode(ActiveMQMessageProducerSupport.java:136)
在setDeliveryMode() 中抛出异常。
我看过其他关于同一问题的帖子,但就我而言,我没有使用共享会话,也没有使用共享连接。
我正在运行 ActiveMQ 5.14.5。
【问题讨论】:
-
您能分享更多您的客户端代码吗?您是否正在为您发送的每条消息创建连接、会话和生产者?如果是这样,那是你绝对应该避免的反模式。
-
我看到很多其他帖子抱怨共享会话引起的问题。我正在考虑使用连接池,但我宁愿不重用会话,除非存在不会产生问题的已知模式。
-
没有那么多代码了。设置redelivery模式后,发送一些消息并返回。
-
您当然不想在多个线程之间同时使用会话,但是 JMS 连接是线程安全的,因此您可能只需要其中的 1 个,然后您可以每个线程有一个会话,而不是而不是每次发送消息时创建一个。生产者也是如此 - 每个线程一个。
-
我不太关心你的代码在调用
setDeliveryMode()后会做什么,因为我关心的是如何定义所有变量以及并发线程如何实际使用包含类发送消息。