Перезапустите сервер без потери соединения JMS

У меня есть два сервера приложений. Один отправляет сообщения другому с помощью JMS. Отправитель работает на Tomcat, а ActiveMQ используется внутри вызова метода шаблона Spring Framework. Ресивер работает на 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>

person Will Glass    schedule 23.01.2011    source источник


Ответы (1)


Это потому, что вы используете SingleConnectionFactory. каждый раз, когда вызывается SingleConnectionFactory.createConnection(), он возвращает одно и то же соединение, даже после его закрытия путем перезапуска принимающего сервера. Возможно, CachingConnectionFactory удовлетворит ваши потребности, поскольку у него есть механизм восстановления при исключении.

person Tomasz Krzyżak    schedule 23.01.2011
comment
Очень полезно. Какая рекомендуемая альтернатива? - person Will Glass; 24.01.2011
comment
Извините, была опечатка. Я имел в виду CachingConnectionFactory. другое решение состоит в том, чтобы создать подкласс SingleConnectionFactory и переопределить SingleConnectionFactory.prepareConnection(), где вы можете присоединить ExceptionListener, который вызовет SingleConnectionFactory.resetConnection() - person Tomasz Krzyżak; 24.01.2011
comment
Вы можете попробовать установить для setReconnectOnException значение true в SingleConnectionFactory. Предполагая, что ваше базовое соединение вызывает JMSException, тогда SingleConnectFactory сбросит соединение. - person Patrick; 18.03.2011