Интеграция с JMS и Spring, устранение зависимости от наличия экземпляра ActiveMQ.

Недавно я настроил ведение журналов в AcitveMQ в качестве службы «выстрелил и забыл», чтобы приложение могло просто отправить сообщение в «ActivityLoggingChannel» и не иметь дело с сквозными проблемами ведения журнала.

Все отправляется на ActivityLoggingGateway, который является просто интерфейсом с каналом по умолчанию. Затем он запрашивает у Pojo (динамического маршрутизатора) имя канала, чтобы получить конечную точку сообщения. Существует точка входа JMX для динамического маршрутизатора, которая позволяет мне переключать конечные точки на лету. Если конечная точка сообщения установлена ​​на jmsChannelSender и она не может разрешить URL-адрес ActiveMQ, это приведет к падению всей системы.

Проблема, с которой я сталкиваюсь, заключается в том, что если URL-адрес ActiveMQ недоступен, я бы хотел, чтобы система вернулась к другому каналу сообщений, который использует простой многопоточный подход в процессе.

Вот конфигурация интеграции spring ниже. Использование версии 2.0.0.RELEASE

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:int="http://www.springframework.org/schema/integration"
    xmlns:jms="http://www.springframework.org/schema/integration/jms"
    xmlns:int-jmx="http://www.springframework.org/schema/integration/jmx"
    xsi:schemaLocation="http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms-3.0.xsd
        http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-2.0.xsd
        http://www.springframework.org/schema/integration/jmx http://www.springframework.org/schema/integration/jmx/spring-integration-jmx-2.0.xsd
        http://www.springframework.org/schema/integration/jms http://www.springframework.org/schema/integration/jms/spring-integration-jms-2.0.xsd
        http://www.springframework.org/schema/integration/stream http://www.springframework.org/schema/integration/stream/spring-integration-stream-2.0.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <import resource="dm-activitylogging-services.xml"/>

    <bean name="decisionActivityLoggingAspect" class="com.idna.dm.aspects.logging.activity.DecisionActivityLogAspect" 
        factory-method="aspectOf">
        <property name="activityLoggingGateway">
            <ref bean="activityLoggingGateway" />
        </property>
    </bean>

<!-- New Activity Logging Services Reference dm-activity-logging -->    
<!-- JMS Channel Adapter -->
    <int:channel id="jmsSenderChannel" />

    <bean id="destinationLocalQueue" class="org.apache.activemq.command.ActiveMQQueue">
        <constructor-arg index="0" value="${activemq.queuename.activitylogging}" />
    </bean>

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

    <bean id="activityLogConverter" class="com.idna.dm.domain.activitylogging.jms.ActivityLogConverter" />
    <jms:outbound-channel-adapter channel="jmsSenderChannel"  destination="destinationLocalQueue" connection-factory="connectionFactory" message-converter="activityLogConverter"/>

<!--  In Process Adapter -->

    <int:channel id="inProcessChannel" />   
    <int:outbound-channel-adapter channel="inProcessChannel" ref="inProcessAdapter" method="persistLog" />
    <bean id="inProcessAdapter" class="com.idna.dm.logging.activity.impl.InProcessActivityLoggingImpl" >
        <property name="activityLoggingService" >
            <ref bean="activityLogging" />
        </property>
    </bean>

    <int:channel id="asyncInProcessChannel" />
    <int:outbound-channel-adapter channel="asyncInProcessChannel" ref="asyncInProcessAdapter" method="persistLog" />
    <bean id="asyncInProcessAdapter" class="com.idna.dm.logging.activity.impl.AsyncInProcessActivityLoggingImpl" >
        <property name="activityLoggingService">
            <ref bean="activityLogging" />
        </property>
    </bean>

<!-- Custom channel for console output using the router -->

    <!-- Console Channel 
    <int:channel id="consoleAdapterChannel" />
    <int:outbound-channel-adapter channel="consoleAdapterChannel" ref="consoleAdapter" method="printToStdout" />
    <bean id="consoleAdapter" class="com.idna.dm.logging.activity.util.StdoutTargetAdapter" />
     -->

    <!-- Log4j Channel -->
    <int:channel id="loggingChannel" />
    <int:logging-channel-adapter auto-startup="true" level="INFO" log-full-message="true" channel="loggingChannel" />

<!-- Router -->
    <int:gateway id="activityLoggingGateway" 
        service-interface="com.idna.dm.logging.activity.logger.ActivityLoggingGateway" />


    <int:channel id="activityLoggingChannel" />

    <int:router input-channel="activityLoggingChannel" ref="dynamicRouter"
        method="route" default-output-channel="asyncInProcessChannel"
        ignore-channel-name-resolution-failures="true" />

    <bean id="dynamicRouter" class="com.idna.dm.logging.activity.router.DynamicRouter">
        <constructor-arg index="0" value="asyncInProcessChannel" />
    </bean>

person DeliveryNinja    schedule 19.01.2011    source источник
comment
Хорошая идея, а в чем вопрос?   -  person iwein    schedule 06.05.2011
comment
Извините, мой вопрос здесь больше не актуален, но я спрашивал о том, как найти способ вернуться к асинхронному каналу в качестве аварийного переключения для ActiveMQ. Поэтому, если бы MQ вышел из строя, я бы вообще отказался от использования MQ. Теперь у нас есть отдельный активный экземпляр MQ в качестве резервного сервера, так что это больше не проблема.   -  person DeliveryNinja    schedule 09.05.2011


Ответы (1)


Вы можете добиться этого, используя механизм failover:

<channel id="input">
  <dispatcher load-balancer="none"/>
</channel>

<service-activator input-channel="input" order="1"/>

<service-activator input-channel="input" order="2"/>

В этом случае первый <service-activator> всегда будет вызываться первым. И второй только в том случае, если первый выйдет из строя.

failover по умолчанию равно true.

person Artem Bilan    schedule 01.06.2014
comment
Опоздал всего на 3 года;) В наши дни перешел на использование Spring интеграции с RabbitMQ. - person DeliveryNinja; 17.06.2014