记录通道上的异常并重新排队

时间:2018-01-22 17:56:59

标签: logging spring-integration

我使用spring集成将消息从RabbitServer X上定义的队列移动到多个RabbitMQ Server Y,Z ......

在同一个配置文件中,我定义了多个频道(每个队列要移动一个)。

<!-- Channel 1  -->
<int:channel id="one" ></int:channel>
<int:channel id="error1" ></int:channel>
<int:logging-channel-adapter channel="error1" logger-name="log1" >
<rabbit:connection-factory id="connectionFactory" username="guest" password="guest" addresses="XX.XX.XX.XX:5672"  cache-mode="CONNECTION" virtual-host="/"/>
<int-amqp:inbound-channel-adapter channel="one" id="inboundChannelAdapter1"  queue-names="myqueue" connection-factory="connectionFactory"   error-channel="error1"  auto-startup="true"  channel-transacted="true" />
<rabbit:connection-factory id="connectionFactoryRmqDest" username="guest" password="guest" addresses="YY.YY.YY.YY:5672" cache-mode="CONNECTION" connection-cache-size="50" virtual-host="/"/> 
<rabbit:template id="rabbitTemplateRmqDest" connection-factory="connectionFactoryRmqDest"/>
<int-amqp:outbound-channel-adapter channel="one" id="outboundChannelAdapter1" routing-key="keyMyQueue" exchange-name="direct.exchange" amqp-template="rabbitTemplateRmqDest" default-delivery-mode="PERSISTENT" >

<!-- Channel 2  -->
<int:channel id="two" ></int:channel>
<int:channel id="error2" />
<int:logging-channel-adapter channel="error2" logger-name="log2" />
<rabbit:connection-factory id="connectionFactory2" username="guest" password="guest" addresses="XX.XX.XX.XX:5672"  cache-mode="CONNECTION" virtual-host="/"/>
<int-amqp:inbound-channel-adapter channel="two" id="inboundChannelAdapter2"  queue-names="myqueue2" connection-factory="connectionFactory"  error-channel="error2" auto-startup="true"  channel-transacted="true" />
<rabbit:connection-factory id="connectionFactoryRmqDest2" username="guest" password="guest" addresses="ZZ.ZZ.ZZ.ZZ:5672" cache-mode="CONNECTION" connection-cache-size="50" virtual-host="/"/> 
<rabbit:template id="rabbitTemplateRmqDest2" connection-factory="connectionFactoryRmqDest2"/>
<int-amqp:outbound-channel-adapter channel="two" id="outboundChannelAdapter2" routing-key="keyMyQueue2" exchange-name="direct.exchange" amqp-template="rabbitTemplateRmqDest2" default-delivery-mode="PERSISTENT" />

使用此配置时,如果入站通道发生错误,通道上的错误将转到为log1或log2定义的特定日志文件。

如果目标代理Z(通道2上的出站通道适配器)出现故障,我想在日志“log2”中记录错误,但也要在源代理上重新排队消息以防止消息松散。

我该怎么做?需要写一些豆子吗?我需要在为通道定义的specfic日志文件中记录错误(在入站或出站通道上)。

感谢您的帮助。

此致

于12/03/2018编辑

频道配置

<bean id="log" class="com.logger.Logger"/>

<!-- Logger -->
<int:channel id="one" ></int:channel>
<int:channel id="error1" ></int:channel>
<int:publish-subscribe-channel id="processChannel1"  />  
<int:logging-channel-adapter channel="processChannel1" logger-name="log1" level="ERROR"/>   
<int:service-activator input-channel="processChannel1"  ref="log" output-channel="error1" />

<!-- Source -->
<rabbit:connection-factory id="connectionFactory" username="guest" password="guest" addresses="XX.XX.XX.XX:5672" cache-mode="CONNECTION" virtual-host="/" />
<int-amqp:inbound-channel-adapter channel="one" id="inboundChannelAdapter1" queue-names="myqueue" connection-factory="connectionFactory" error-channel="processChannel1" channel-transacted="true" advice-chain="retryInterceptor" />

<!-- Destination -->
<rabbit:connection-factory id="connectionFactoryRmqDest" username="guest" password="guest111" addresses="YY.YY.YY.YY:5672" cache-mode="CONNECTION" connection-cache-size="50" virtual-host="/" />
<rabbit:template id="rabbitTemplateRmqDest" connection-factory="connectionFactoryRmqDest" />
<int-amqp:outbound-channel-adapter channel="one" id="outboundChannelAdapter1" routing-key="keyMyQueue" exchange-name="direct.exchange" amqp-template="rabbitTemplateRmqDest" default-delivery-mode="PERSISTENT"/>

Logger.java

package com.logger;
public class Logger {

    public Message<?> log(Message<?> message) {
        System.out.println("*************************************");
        throw new AmqpException("Error on channel");
    }
}   

1 个答案:

答案 0 :(得分:0)

当您只记录错误时:

error-channel="error2"
...
<int:channel id="error2" />
<int:logging-channel-adapter channel="error2" logger-name="log2" />

<int-amqp:inbound-channel-adapter>将其视为消息处理的完美结束。要使其重新排队失败的消息,您应该从错误流中重新抛出异常。为此,我建议将error2更改为<publish-subscribe-channel>,然后再添加一个<service-activator>作为订阅者。并且最后一个将向AMQP通道抛出异常以进行重新排队。