【问题标题】:Restart server without losing JMS connection在不丢失 JMS 连接的情况下重新启动服务器
【发布时间】:2023-03-21 01:16:02
【问题描述】:

我有两个应用服务器。一个使用 JMS 向另一个发送消息。发送方在 Tomcat 上运行,在 Spring Framework 模板方法调用中使用 ActiveMQ。接收器在 Jetty 上运行。

问题在于,当我重新启动其中一个服务器(消息的接收方)时,它在重新启动后不会再收到任何 JMS 消息,直到另一台服务器也重新启动。我不确定为什么会这样。有没有办法只需要重启一台服务器?

发送方 XML 配置:

<bean id="producerJmsTemplate" class="org.springframework.jms.core.JmsTemplate">
    <property name="connectionFactory">
        <bean
            class="org.springframework.jms.connection.SingleConnectionFactory">
            <property name="targetConnectionFactory" ref="jmsFactory"/>
        </bean>
    </property>
</bean>

<bean id="simulationMessageSender" class="com.forio.simulate.activemq.SimulationMessageSenderImpl">
    <constructor-arg ref="producerJmsTemplate"/>
</bean>

<bean id="destination" class="org.apache.activemq.command.ActiveMQQueue"
    autowire="constructor">
    <constructor-arg value="com.forio.simulate.activemq"/>
</bean>

发送方java代码:

public void send(final SimulationMessage simulationMessage) throws JMSException
{
    jmsTemplate.send(destination, new MessageCreator()
    {
        public Message createMessage(Session session) throws JMSException
        {
            Log.debug("Sending message: " + simulationMessage);
            ObjectMessage message = session.createObjectMessage(simulationMessage);
            message.setStringProperty("simulationMessage", "true");
            return message;
        }
    });
}

接收方 XML 配置:

<bean id="brokerContainer" class="org.apache.activemq.xbean.BrokerFactoryBean">
    <property name="config" value="classpath:activemq.xml" />
</bean>

<bean id="jmsFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
    <property name="brokerURL" value="${jms.url}" />
</bean>

<bean id="destination" class="org.apache.activemq.command.ActiveMQQueue"
    autowire="constructor">
    <constructor-arg>
        <value>com.forio.simulate.activemq</value>
    </constructor-arg>
</bean>

<bean id="messageListener"
    class="com.forio.simulate.activemq.SimulationMessageListener">
    <property name="messageConverter">
        <bean
            class="com.forio.simulate.activemq.converter.SimulationMessageConverter" />
    </property>
    <property name="simulationMessageService" ref="simulationMessageService"/>
</bean>

<bean
    class="org.springframework.jms.listener.SimpleMessageListenerContainer" init-method="start">
    <property name="connectionFactory" ref="jmsFactory" />
    <property name="destination" ref="destination" />
    <property name="concurrentConsumers" value="3" />
    <property name="messageListener" ref="messageListener" />
</bean>

<bean id="consumerJmsTemplate" class="org.springframework.jms.core.JmsTemplate">
    <property name="connectionFactory" ref="jmsFactory" />
</bean>

【问题讨论】:

    标签: java jms activemq


    【解决方案1】:

    这是因为您使用的是SingleConnectionFactory。每次调用SingleConnectionFactory.createConnection() 时,它都会返回相同的连接,即使在通过重新启动接收服务器而关闭它之后也是如此。 也许CachingConnectionFactory 会满足您的需求,因为它有一些异常机制恢复。

    【讨论】:

    • 非常有帮助。有什么推荐的替代方案?
    • 对不起,有一个错字。我的意思是CachingConnectionFactory。另一种解决方案是继承SingleConnectionFactory 并覆盖SingleConnectionFactory.prepareConnection(),您可以在其中附加ExceptionListener,这将调用SingleConnectionFactory.resetConnection()
    • 您可以尝试在 SingleConnectionFactory 上将 setReconnectOnException 设置为 true。假设您的底层连接抛出 JMSException,那么 SingleConnectFactory 将重置连接。
    猜你喜欢
    • 2012-04-08
    • 2012-10-03
    • 2020-09-05
    • 1970-01-01
    • 1970-01-01
    • 2011-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多