2014-06-09 2 views
0

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에이 권고를 추가 할 경우. 모든 Handler에서 트랜잭션 관리가 필요합니다.

+0

표시, 어떻게 그 '조언'을 적용하십시오. 'endpoint' 설정입니다. 'TransactionManager'는'PlatformTransactionManager' 여야합니다. –

+0

안녕 Artem, 코드로 질문을 업데이트했습니다. –

답변

0

우선 : 귀하의 txansactionAdviceretryAdvice에 중첩되어 있으므로 여기에서 각각 다시 시도하십시오.

다시 시도 할 때마다 circuitBreakerAdvice을 적용하는 이유가 분명하지 않습니다. 나는이 후딱지가 '주변'retryAdvice을 사용하는 것이 더 나을 것이라고 말하고 싶습니다.

그리고 txansactionAdvice이 위에 있어야합니다. 그래서, 그것은 다음과 같습니다

txansactionAdvice 
circuitBreakerAdvice 
retryAdvice 

그리고 또 하나의 포인트 : 트랜잭션은 ErrorMessage를 전송하고 예외를 목 졸라 사용에 recoveryCallback, bacause, 롤백되지 않습니다.

HTH이 문제에 대한 귀하의 생각이 바뀝니다.

+0

감사합니다 Artem 이것은 유용했습니다. 그리고 지금 나는 어떤 메시지 손실을 보지 않는다. –