重试策略不起作用
<task:executor id="ticketSourceExc" pool-size="1"
queue-capacity="0" rejection-policy="CALLER_RUNS" />
<task:executor id="regulatoryExc" pool-size="1"
queue-capacity="5" rejection-policy="CALLER_RUNS" />
<int:service-activator input-channel="ticketCacheChannel"
output-channel="sourceTicketsSplitter" ref="ticketSerActivator"
method="fetchDataFromDB">
<int:poller fixed-rate="10" task-executor="ticketSourceExc" />
</int:service-activator>
<!-- I am getting List<Tickets> -->
<int:splitter input-channel="sourceTicketsSplitter"
output-channel="sourceTicketChannel">
<int:request-handler-advice-chain>
<ref bean="retrier" />
</int:request-handler-advice-chain>
<int:poller fixed-rate="10" />
</int:splitter>
<int:handler-retry-advice id="retrier" max-attempts="4" recovery-channel="myErrorChannel" >
<int:exponential-back-off initial="1000" multiplier="5" maximum="6000"/>
</int:handler-retry-advice>
<int:bridge id="regulatoryBrigde" input-channel="sourceTicketChannel"
output-channel="regulatoryChannel">
<int:poller fixed-rate="10" task-executor="regulatoryExc" />
</int:bridge>
<int:chain id="regulatoryChainFlow" input-channel="regulatoryChannel">
<int:service-activator ref="regulatoryTaskActivator1"
method="process" />
<int:service-activator ref="regulatoryTaskActivator2"
method="process" />
<int:service-activator ref="regulatoryTaskActivator3"
method="process" />
</int:chain>
我已为拆分器配置重试策略。输出通道是深度为1(用于测试目的)的队列通道。我的期望是当我得到一个包含10个项目的列表时,应在队列已满后转到异常通道。这不是这种情况。我将线程睡眠置于RegulatoryTaskActivator1中以阻止队列
答案 0 :(得分:1)
这是正确的,因为建议中不包含发送到输出通道的信息。这仅用于 request 部分。请仔细阅读有关此问题的文档:https://docs.spring.io/spring-integration/docs/5.0.8.RELEASE/reference/html/messaging-endpoints-chapter.html#message-handler-advice-chain。该建议仅适用于handleRequestMessage()
方法。
更新
对于用例,当您想处理队列的有限大小并通过重试进行一些错误处理时,建议您将拆分结果输出到service-activator
周围,@MessagingGateway
error-channel
方法上适当的@Retryable
和可能的@Gateway
:
<splitter input-channel="sourceTicketsSplitter"
output-channel="gatewayInputChannel">
<poller fixed-rate="10" />
</splitter>
<service-activator input-channel="gatewayInputChannel" ref="gateway">
<request-handler-advice-chain>
<ref bean="retrier" />
</request-handler-advice-chain>
</service-activator>
<gateway id="gateway" default-request-channel="sourceTicketChannel"/>
如果您的流程是单向,并且您不希望收到regulatoryChainFlow
的任何答复,那么默认的RequestReplyExchanger
不符合您的要求,您需要通过void
方法为网关引入一个简单的接口,并将该<gateway>
配置为service-interface
。
更新
我为您忘记提及的是,需要使用timeout
来发送到受限队列。如果没有这样的超时时间,发件人只需就座并等待房间,房间就会出现在上述Thread.sleep(10000);
之后。
所以,您需要的是这样的
<int:gateway id="stateGateWay" default-request-channel="stateChannel"
default-request-timeout="100"
service-interface="com.biswo.myspringapp.gateway.StateGateWay" />
请注意:
<xsd:attribute name="default-request-timeout" type="xsd:string">
<xsd:annotation>
<xsd:documentation>
<![CDATA[
Provides the amount of time dispatcher would wait to send a message.
This timeout would only apply if there is a potential to block in the send call.
For example if this gateway is hooked up to a Queue channel.
Value is specified in milliseconds; it can be a simple long value or a SpEL
expression; array variable #args is available.
]]>
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
此后,我开始在日志中看到关联,然后是Dispatcher has no subscribers
:
2018-10-09 14:53:03.466 TRACE 15808 --- [ask-scheduler-3] o.s.retry.support.RetryTemplate : RetryContext retrieved: [RetryContext: count=0, lastException=null, exhausted=false]
2018-10-09 14:53:03.466 DEBUG 15808 --- [ask-scheduler-3] o.s.retry.support.RetryTemplate : Retry: count=0
2018-10-09 14:53:03.568 DEBUG 15808 --- [ask-scheduler-3] o.s.r.backoff.ExponentialBackOffPolicy : Sleeping for 100
2018-10-09 14:53:03.669 DEBUG 15808 --- [ask-scheduler-3] o.s.retry.support.RetryTemplate : Checking for rethrow: count=1
2018-10-09 14:53:03.669 DEBUG 15808 --- [ask-scheduler-3] o.s.retry.support.RetryTemplate : Retry: count=1
2018-10-09 14:53:03.771 DEBUG 15808 --- [ask-scheduler-3] o.s.r.backoff.ExponentialBackOffPolicy : Sleeping for 500
2018-10-09 14:53:04.271 DEBUG 15808 --- [ask-scheduler-3] o.s.retry.support.RetryTemplate : Checking for rethrow: count=2
2018-10-09 14:53:04.271 DEBUG 15808 --- [ask-scheduler-3] o.s.retry.support.RetryTemplate : Retry: count=2
2018-10-09 14:53:04.372 DEBUG 15808 --- [ask-scheduler-3] o.s.r.backoff.ExponentialBackOffPolicy : Sleeping for 600
2018-10-09 14:53:04.973 DEBUG 15808 --- [ask-scheduler-3] o.s.retry.support.RetryTemplate : Checking for rethrow: count=3
2018-10-09 14:53:04.973 DEBUG 15808 --- [ask-scheduler-3] o.s.retry.support.RetryTemplate : Retry: count=3
2018-10-09 14:53:05.073 DEBUG 15808 --- [ask-scheduler-3] o.s.retry.support.RetryTemplate : Checking for rethrow: count=4
2018-10-09 14:53:05.073 DEBUG 15808 --- [ask-scheduler-3] o.s.retry.support.RetryTemplate : Retry failed last attempt: count=4
2018-10-09 14:53:05.077 WARN 15808 --- [ask-scheduler-3] o.s.i.c.MessagePublishingErrorHandler : Error message was not delivered.
org.springframework.messaging.MessageDeliveryException: Dispatcher has no subscribers for channel 'application.errorChannel'.; nested exception is org.springframework.integration.MessageDispatchingException: Dispatcher has no subscribers, failedMessage=ErrorMessage [payload=org.springframework.messaging.MessageDeliveryException: Dispatcher has no subscribers for channel 'application.errorChannel'.; nested exception is org.springframework.integration.MessageDispatchingException: Dispatcher has no subscribers, failedMessage=ErrorMessage [payload=org.springframework.messaging.MessageHandlingException: nested exception is org.springframework.messaging.MessageDeliveryException: Failed to send message to channel 'stateChannel' within timeout: 100, failedMessage=GenericMessage [payload=State [id=2426, name=Pamanzi, countryId=141], headers={id=710d13df-dfbb-ba95-8d28-4785d1a1e3d3, timestamp=1539111184973}], failedMessage=GenericMessage [payload=State [id=2426, name=Pamanzi, countryId=141], headers={COUNTRY_ID=141, sequenceNumber=2, COUNTRY=com.biswo.myspringapp.model.Country@5fd4ea2d, sequenceSize=2, correlationId=ab423aa4-c80e-6af0-33a8-f57337f25352, id=a70d6b11-fc23-edd9-7973-1342c3fab8a6, timestamp=1539111183466}], headers={id=ee0ffd29-8e6a-ab5a-6ffb-1016fa38457e, timestamp=1539111185074}], failedMessage=ErrorMessage [payload=org.springframework.messaging.MessageHandlingException: nested exception is org.springframework.messaging.MessageDeliveryException: Failed to send message to channel 'stateChannel' within timeout: 100, failedMessage=GenericMessage [payload=State [id=2426, name=Pamanzi, countryId=141], headers={id=710d13df-dfbb-ba95-8d28-4785d1a1e3d3, timestamp=1539111184973}], failedMessage=GenericMessage [payload=State [id=2426, name=Pamanzi, countryId=141], headers={COUNTRY_ID=141, sequenceNumber=2, COUNTRY=com.biswo.myspringapp.model.Country@5fd4ea2d, sequenceSize=2, correlationId=ab423aa4-c80e-6af0-33a8-f57337f25352, id=a70d6b11-fc23-edd9-7973-1342c3fab8a6, timestamp=1539111183466}], headers={id=ee0ffd29-8e6a-ab5a-6ffb-1016fa38457e, timestamp=1539111185074}], headers={id=34d0e6e6-0af8-1078-5dd7-aa6643ba6c8d, timestamp=1539111185075}] for original GenericMessage [payload=[State [id=2425, name=Mayotte, countryId=141], State [id=2426, name=Pamanzi, countryId=141]], headers={COUNTRY_ID=141, id=ab423aa4-c80e-6af0-33a8-f57337f25352, COUNTRY=com.biswo.myspringapp.model.Country@5fd4ea2d, timestamp=1539111183462}]
仅仅是因为您的errorChannel
是DirectChannel
,并且没有任何消费者。