Spring integration Spring集成:聚合器之后如何处理服务中的异常?

Spring integration Spring集成:聚合器之后如何处理服务中的异常?,spring-integration,amqp,Spring Integration,Amqp,我有一个依赖Spring集成(4.0.4.RELEASE)和RabbitMQ的应用程序。我的流程如下: 2014-09-23 16:41:18,725 ERROR o.s.i.s.SimpleMessageStore:174: Exception in expiry callback org.springframework.messaging.MessageHandlingException: java.lang.Exception: ahahaha at org.springframe

我有一个依赖Spring集成(4.0.4.RELEASE)和RabbitMQ的应用程序。我的流程如下:

2014-09-23 16:41:18,725 ERROR o.s.i.s.SimpleMessageStore:174: Exception in expiry callback
org.springframework.messaging.MessageHandlingException: java.lang.Exception: ahahaha
    at org.springframework.integration.handler.MethodInvokingMessageProcessor.processMessage(MethodInvokingMessageProcessor.java:78)
    at org.springframework.integration.handler.ServiceActivatingHandler.handleRequestMessage(ServiceActivatingHandler.java:71)
    at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:170)
    at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:78)
(...)

Caused by: java.lang.Exception: ahahaha
    at com.myapp.ServiceD.doSomething(ServiceD.java:153)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
(...)

2014-09-23 16:41:18,733 ERROR o.s.s.s.TaskUtils$LoggingErrorHandler:95: Unexpected error occurred in scheduled task.
org.springframework.messaging.MessageHandlingException: java.lang.Exception: ahahaha
(...)
消息通过一个进程放入队列(它们不希望得到任何答复): 网关->通道->RabbitMQ

然后通过另一个过程排出:

RabbitMQ --1--> inbound-channel-adapter A --2--> chain B --3--> aggregator C --4--> service-activator D --5--> final service-activator E 问题:
如何告知处理来自此类聚合器的消息的服务将错误发布到errorChannel?我试图通过标头enricher在标头中指定错误通道,但没有成功。我使用的是默认的errorChannel定义,但我也尝试更改它的名称并重新定义它。我在这里毫无头绪,即使我找到了,也没能让它发挥作用。提前感谢您的帮助

如StackTrace所示,您的进程是从
MessageGroupStoreReaper
线程启动的,该线程是从默认的
ThreadPoolTaskScheduler
启动的

因此,您必须为此提供一个自定义bean:

<bean id="scheduler" class="org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler">
    <property name="errorHandler">
        <bean class="org.springframework.integration.channel.MessagePublishingErrorHandler">
            <property name="defaultErrorChannel" ref="errorChannel"/>
        </bean>
    </property>
</bean>

<task:scheduled-tasks scheduler="scheduler">
    <task:scheduled ref="messageStoreReaperBean" method="run" fixed-rate="2000" />
</task:scheduled-tasks>


然而,我看到了在
上设置
错误通道的好处,在那里我们确实有来自不同分离线程的几个点,我们无法正常获得交易。

谢谢Artem,它可以工作!我几乎什么都试过了,但不是这个。但是,如果我们在代码中的其他地方(以及在相同的上下文中)依赖另一个
任务调度器
(通常是通过
@enablespatcheduling
-类注释创建的调度器),这会很烦人。春天4号会抱怨的。我通过使用
SchedulingConfigurer
修复了它,但是直接支持报头聚合和错误通道内置聚合器组件对于避免那些额外的代码行是非常好的!呃。。糟糕的是,在所有这些
async
情况下,我们在
Runnable.run()
之前的入口点向
调度器/执行器提供
MessagePublishingErrorHandler
,以捕获所有底层异常。这意味着更深入地捕捉异常(在我们的聚合器中)就像打破了这个概念。然而,我认为
errorChannel
对于
MessageGroupStoreReaper
就足够了。你可以就这件事提出一个JIRA问题,我们会考虑进一步的解决办法。
<int:service-activator  ref="serviceDBean"
                            method="doSomething"
                            input-channel="channel4"
                            output-channel="channel5" />
<int-amqp:inbound-channel-adapter   channel="channel2"
                                            queue-names="si.queue1"
                                            error-channel="errorChannel"
                                            mapped-request-headers="*"
                                            acknowledge-mode="MANUAL"
                                            prefetch-count="${properties.prefetch_count}"
                                            connection-factory="rabbitConnectionFactory"/>
<int:chain input-channel="errorChannel">
            <int:transformer ref="errorUnwrapperBean" method="unwrap" />
            <int:service-activator ref="amqpAcknowledgerBean" method="rejectMessage" />
</int:chain>
2014-09-23 16:41:18,725 ERROR o.s.i.s.SimpleMessageStore:174: Exception in expiry callback
org.springframework.messaging.MessageHandlingException: java.lang.Exception: ahahaha
    at org.springframework.integration.handler.MethodInvokingMessageProcessor.processMessage(MethodInvokingMessageProcessor.java:78)
    at org.springframework.integration.handler.ServiceActivatingHandler.handleRequestMessage(ServiceActivatingHandler.java:71)
    at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:170)
    at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:78)
(...)

Caused by: java.lang.Exception: ahahaha
    at com.myapp.ServiceD.doSomething(ServiceD.java:153)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
(...)

2014-09-23 16:41:18,733 ERROR o.s.s.s.TaskUtils$LoggingErrorHandler:95: Unexpected error occurred in scheduled task.
org.springframework.messaging.MessageHandlingException: java.lang.Exception: ahahaha
(...)
<bean id="scheduler" class="org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler">
    <property name="errorHandler">
        <bean class="org.springframework.integration.channel.MessagePublishingErrorHandler">
            <property name="defaultErrorChannel" ref="errorChannel"/>
        </bean>
    </property>
</bean>

<task:scheduled-tasks scheduler="scheduler">
    <task:scheduled ref="messageStoreReaperBean" method="run" fixed-rate="2000" />
</task:scheduled-tasks>