我正在尝试为将在我的SI流中使用的所有消息处理程序创建一个通用的错误处理过程。这将, 1.重试连接异常。 2.使用断路器停止SI流量。 3.将失败的消息回滚到通道。
我已经实现了重试和断路功能。但是,我无法将消息回滚到频道。 我尝试使用交易建议。但它不起作用。
这是代码。
<bean id="retryAdvice"
class="org.springframework.integration.handler.advice.RequestHandlerRetryAdvice">
<property name="retryTemplate">
<bean class="org.springframework.retry.support.RetryTemplate">
<property name="backOffPolicy">
<bean class="org.springframework.retry.backoff.ExponentialBackOffPolicy">
<property name="initialInterval" value="2000" />
<property name="multiplier" value="2" />
</bean>
</property>
</bean>
</property>
<property name="recoveryCallback">
<bean
class="org.springframework.integration.handler.advice.ErrorMessageSendingRecoverer">
<constructor-arg ref="recoveryChannel" />
</bean>
</property>
<property name="retryStateGenerator">
<bean
class="org.springframework.integration.handler.advice.SpelExpressionRetryStateGenerator">
<constructor-arg value="headers['uniqueId']" />
</bean>
</property>
</bean>
<int:channel id="recoveryChannel" />
<int:transformer id="defaultTransformer" input-channel="recoveryChannel"
output-channel="loggerChannel" ref="defaultTransformer" method="transform">
</int:transformer>
<int:logging-channel-adapter id="loggerChannel"
level="INFO" log-full-message="true" auto-startup="true">
</int:logging-channel-adapter>
<bean id="defaultTransformer"
class="com.bestbuy.ingestion.foundation.core.util.DefaultTransformer" />
<bean id="circuitBreakerAdvice"
class="org.springframework.integration.handler.advice.RequestHandlerCircuitBreakerAdvice">
<property name="threshold" value="2" /> <!-- close after 2 failures -->
<property name="halfOpenAfter" value="60000" /> <!-- half open after 15 seconds -->
</bean>
<tx:advice id="txansactionAdvice" transaction-manager="transactionManager">
</tx:advice>
我需要使用哪种类型的事务管理器。 我可能在不同的数据源上使用不同的消息处理程序。
以下是我如何将这些建议添加到消息处理程序。
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
logger.error("called for bean id :: "+beanName+" with bean class "+bean.getClass().getName());
if(bean instanceof AbstractSimpleMessageHandlerFactoryBean){
logger.error("************ Bean "+beanName+" is instance of AbstractSimpleMessageHandlerFactoryBean **********");
}
if(bean instanceof ConsumerEndpointFactoryBean){
logger.error("Bean is of type ConsumerEndpointFactoryBean");
return populateRequestHandlerAdviceChain((ConsumerEndpointFactoryBean)bean);
}
if(bean instanceof AbstractSimpleMessageHandlerFactoryBean){
logger.error("Bean is of type AbstractSimpleMessageHandlerFactoryBean");
return populateRequestHandlerAdviceChain((AbstractSimpleMessageHandlerFactoryBean<?>)bean);
}
return bean;
}
private Object populateRequestHandlerAdviceChain(ConsumerEndpointFactoryBean bean){
ArrayList<Advice> list = new ArrayList<Advice>();
logger.error("Adding Retry Advice");
list.add((Advice)factory.getBean("retryAdvice"));
logger.error("Adding Cricuit Breaker Advice");
list.add((Advice)factory.getBean("circuitBreakerAdvice"));
logger.error("Adding Transactional Advice");
list.add((Advice)factory.getBean("txansactionAdvice"));
bean.setAdviceChain(list);
return bean;
}
如果ConsumerEndpointFactoryBean类型的bean我添加了这些建议。我需要在所有这些处理程序中进行事务管理。
答案 0 :(得分:0)
首先:由于您的txansactionAdvice
嵌套在retryAdvice
,因此您在此处重新开始重试。
另一方面,不清楚为何每次重试都应用circuitBreakerAdvice
。我会说这种模式会更好地使用'around'retryAdvice
。
txansactionAdvice
应排在最前面。所以,它可能看起来像这样:
txansactionAdvice
circuitBreakerAdvice
retryAdvice
还有一点:您的交易不会被回滚,因为您使用recoveryCallback
,只会发送ErrorMessage
并扼杀异常。