JMS-生产者已关闭

JMS-生产者已关闭,jms,activemq,Jms,Activemq,下面的代码试图使用JMS在队列上发送消息 connection=jmsConnectionFactory.createConnection(); connection.start(); 会话=connection.createSession(false,session.AUTO_-ACKNOWLEDGE); 目的地=session.createQueue(queueName); MessageProducer=session.createProducer(目的地); producer.setDe

下面的代码试图使用JMS在队列上发送消息

connection=jmsConnectionFactory.createConnection();
connection.start();
会话=connection.createSession(false,session.AUTO_-ACKNOWLEDGE);
目的地=session.createQueue(queueName);
MessageProducer=session.createProducer(目的地);
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。

查看
org.apache.ActiveMQ.ActiveMQMessageProducer
变量的代码(由堆栈跟踪顶部的
checkClosed()
方法检查)初始化为
false
,因此必须将其设置为
true
,才能引发此异常。据我所见,只有当生产者本身、发起会话或发起连接关闭时,才会将其设置为
true
。连接和/或会话可能由于其他故障而在后台关闭,而生产者的此异常是该问题的第一个可见症状


在任何情况下,如果没有关于您的代码或理想情况下的一些额外细节,就不可能得出可靠的结论。

查看
org.apache.activemq.ActiveMQMessageProducer
closed变量的代码(该变量由
checkClosed()检查)
堆栈跟踪顶部的方法)初始化为
false
,因此必须将其设置为
true
,才能引发此异常。据我所见,只有当生产者本身、发起会话或发起连接关闭时,才会将其设置为
true
。连接和/或会话可能由于其他故障而在后台关闭,而生产者的此异常是该问题的第一个可见症状


在任何情况下,如果没有至少一些关于您的代码的额外细节或理想情况,就不可能得出可靠的结论。

您能分享更多的客户代码吗?您是否正在为发送的每封邮件创建连接、会话和生产者?如果是这样的话,这是一种你绝对应该避免的反模式。我已经看到许多其他帖子抱怨共享会话引起的问题。我想使用一个连接池,但我不想重用会话,除非存在不会产生问题的已知模式。没有太多的代码。设置重新交付模式后,它会发送一些消息并返回。您当然不希望在多个线程之间同时使用会话,但JMS连接是线程安全的,因此您可能只需要其中的一个,然后您可以在每个线程中有一个会话,而不是每次发送消息时创建一个会话。生产者也是如此——每个线程一个。我不太关心您的代码在调用
setDeliveryMode()
后会做什么,我更关心的是如何定义所有变量以及并发线程如何实际使用包含的类来发送消息。您能分享更多的客户端代码吗?您是否正在为发送的每封邮件创建连接、会话和生产者?如果是这样的话,这是一种你绝对应该避免的反模式。我已经看到许多其他帖子抱怨共享会话引起的问题。我想使用一个连接池,但我不想重用会话,除非存在不会产生问题的已知模式。没有太多的代码。设置重新交付模式后,它会发送一些消息并返回。您当然不希望在多个线程之间同时使用会话,但JMS连接是线程安全的,因此您可能只需要其中的一个,然后您可以在每个线程中有一个会话,而不是每次发送消息时创建一个会话。生产者也是如此——每个线程一个。我不太关心你的代码在调用
setDeliveryMode()后会做什么
正如我所说的,所有变量是如何定义的,以及试图发送消息的并发线程如何实际使用包含的类。如果用户表示正在进行压力测试,一种可能是他们超过了代理内存限制或类似限制,并且由于本机线程创建失败或如果用户声明正在进行压力测试,一种可能是他们已经超过了代理内存限制或类似限制,并且由于本机线程创建失败或类似原因而断开了连接。