无法发送带有消息 "Server has been disposed" 的事件,但服务器继续接受其他事件

Failed to send event with message "Server has been disposed" but the server keeps accepting other events

我有一个使用 Apache ActiveMQ 作为其事件代理的应用程序。在处理一个事件时,它尝试发送第二个事件,但第二个事件失败并显示消息表明服务器已被处理。

在发生此错误的那一秒,我的经纪人在此错误之前接受了 4 条消息,并在此错误之后接受了 6 条消息(均在同一秒内)。在再次记录此错误之前,它又持续了 运行 7 秒(我们处理了大约 100 个事件)。第二次记录消息时,代理在此错误之前接受了 27 条其他消息,之后又接受了 42 条消息(同样,所有消息都在同一秒内)。

我们正在使用 Spring JmsTemplate 发送消息。

Caused by: de.dser.event.exceptions.EventServiceException: Server has been disposed.
    at org.apache.activemq.transport.vm.VMTransportServer.connect(VMTransportServer.java:69)
    at org.apache.activemq.transport.vm.VMTransportFactory.doCompositeConnect(VMTransportFactory.java:150)
    at org.apache.activemq.transport.vm.VMTransportFactory.doConnect(VMTransportFactory.java:56)
    at org.apache.activemq.transport.TransportFactory.connect(TransportFactory.java:65)
    at org.apache.activemq.ActiveMQConnectionFactory.createTransport(ActiveMQConnectionFactory.java:331)
    at org.apache.activemq.ActiveMQConnectionFactory.createActiveMQConnection(ActiveMQConnectionFactory.java:346)
    at org.apache.activemq.ActiveMQConnectionFactory.createActiveMQConnection(ActiveMQConnectionFactory.java:304)
    at org.apache.activemq.ActiveMQConnectionFactory.createConnection(ActiveMQConnectionFactory.java:244)
    at org.springframework.jms.support.JmsAccessor.createConnection(JmsAccessor.java:196)
    at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:494)
    at org.springframework.jms.core.JmsTemplate.send(JmsTemplate.java:584)

使用以下代码发送消息

        final ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(brokerService.getVmConnectorURI());
        final JmsTemplate jms = new JmsTemplate(connectionFactory);
        jms.send(queueName, session -> {
            final Message message = session.createObjectMessage(event);
            message.setStringProperty("name", eventName);
            return message;
        });

什么会导致此错误?服务器未关闭或重新启动。它继续毫无问题地处理绝大多数消息。

当异常消息说“服务器已被处置”时,它并不是在谈论 ActiveMQ 的整个实例。它只讨论客户端用来与代理建立 VM 连接的 org.apache.activemq.transport.vm.VMTransportServer 的实例。我建议您为 org.apache.activemq.transport.vm.VMTransportFactory 激活 DEBUG 日志记录。这可能会揭示幕后发生的事情。

除此之外,我强烈建议您更改使用 JMSTemplate 发送消息的方式。正如 the documentation 所述:

The thing to remember is JmsTemplate is designed for use in EJBs using the EJB containers JMS pooling abstraction. So every method will typically create a connection, session, producer or consumer, do something, then close them all down again. The idea being that this will use the J2EE containers pooling mechanism to pool the JMS resources under the covers. Without using a pooled JMS provider from the EJB container this is the worst possible way of working with JMS; since typically each create/close of a connection, producer/consumer results in a request-response with the JMS broker.

我建议您不要创建 ActiveMQConnectionFactory 实例并将其直接传递给 JMSTemplate,而是使用池连接工厂实现的单个实例。