2017-05-23 3 views
0

HTTP 재발송 게이트웨이와 관련된 재시도 시나리오에서 작업하고 있습니다. 재시도 논리는 매우 잘 작동하지만 재 시도하지 않는 논리에는 버그가 있습니다.봄 재시도 : NeverRetryLogic ExceptionClassifierRetryPolicy를 사용하여 예상대로 작동하지 않습니다.

40400,503,504와 다른 http 상태 오류가 발생하면 다시 시도하지 않는 것이 좋습니다.

테스트하기 위해 구성 가능한 엔드 포인트가 있습니다.이 엔드 포인트는 성공하기 전에 X 시간 동안 모든 HTTP 상태 오류로 응답하도록 구성 할 수 있습니다.

예를 들어 처음으로 HTTP 400 상태가되도록 엔드 포인트를 구성 할 수 있습니다. 그런 다음 재 시도 할 때 성공한 응답을 받게됩니다.

즉, 내가 예상했던 것은 처음으로 http 400 상태를 얻으려고 엔드 포인트를 구성 할 때 다시 시도하지 않아도되지만 작동하지 않는 것처럼 보입니다. 그것은이 작업을 수행해야 NeverRetryPolicy 클래스에 따르면

public class CustomRetryPolicy extends ExceptionClassifierRetryPolicy { 

    private String maxAttempts; 

    @PostConstruct 
    public void init() { 

     final RetryPolicy defaultRetry = defaultRetryPolicy(); 
     this.setExceptionClassifier(new Classifier<Throwable, RetryPolicy>() { 
      @Override 
      public RetryPolicy classify(Throwable classifiable) { 
       Throwable exceptionCause = classifiable.getCause(); 
       if (exceptionCause instanceof HttpStatusCodeException) { 
        int statusCode = ((HttpStatusCodeException) classifiable.getCause()).getStatusCode().value(); 
        handleHttpErrorCode(statusCode); 
       } 
       return defaultRetry; 
      } 
     }); 
    } 

    public void setMaxAttempts(String maxAttempts) { 
     this.maxAttempts = maxAttempts; 
    } 


    private RetryPolicy handleHttpErrorCode(int statusCode) { 
     RetryPolicy retryPolicy = null; 
     switch(statusCode) { 
     case 404 : 
     case 500 : 
     case 503 : 
     case 504 : 
      retryPolicy = defaultRetryPolicy(); 
      break; 
     default : 
      retryPolicy = neverRetry(); 
      break; 
     } 

     return retryPolicy; 
    } 

    private RetryPolicy neverRetry() { 
     return new NeverRetryPolicy(); 
    } 

    private RetryPolicy defaultRetryPolicy() { 
     final SimpleRetryPolicy simpleRetryPolicy = new SimpleRetryPolicy(); 
     simpleRetryPolicy.setMaxAttempts(5); 
     return simpleRetryPolicy; 
    } 

} 

:

<int-http:outbound-gateway 
      header-mapper="httpHeaderMapper" 
      request-channel="some_request_channel" 
      url-expression="'http://some_url" 
      http-method="POST" 
      expected-response-type="java.lang.String" 
      charset="UTF-8" 
      reply-timeout="${com.property.value.from.db.for.time.out:5000}" 
      reply-channel="some_reply_channel"> 

      <int-http:request-handler-advice-chain> 
         <bean class="org.springframework.integration.handler.advice.RequestHandlerRetryAdvice"> 
          <property name="recoveryCallback"> 
           <bean class="org.springframework.integration.handler.advice.ErrorMessageSendingRecoverer"> 
            <constructor-arg ref="errorChannel" /> 
           </bean> 
          </property> 
          <property name="retryTemplate" ref="retryTemplate" /> 
         </bean> 
      </int-http:request-handler-advice-chain> 

    </int-http:outbound-gateway> 


    <bean id="retryTemplate" class="org.springframework.retry.support.RetryTemplate"> 
     <property name="retryPolicy"> 
      <bean class="com.whatever.CustomRetryPolicy"> 
       <property name="maxAttempts" value="${com.property.value.from.db.for.retry.MaxAttemps:5}" /> 
      </bean> 
     </property> 
     <property name="backOffPolicy"> 
      <bean class="org.springframework.retry.backoff.ExponentialBackOffPolicy"> 
       <property name="initialInterval" value="${com.property.value.from.db.for.backoffpolicy.initialInterval:1000}" /> 
       <property name="multiplier" value="${com.property.value.from.db.for.backoffpolicy.initialInterval:6}" /> 
      </bean> 
     </property> 
    </bean> 

CustomRetryPolicy 이것이다 :

나는 재시도 결코 시나리오에이 논리는 이것이다

처음 시도는 허용하지만 다시 시도하지 못하게하는 RetryPolicy입니다. 다른 정책의 기본 클래스로도 사용됩니다. 테스트 를 목적으로 한 스텁.

따라서 처음 시도는 엔드 포인트에 도달했을 때 HTTP 400 오류 상태를 수신 한 다음 다시 시도하지 않는 것입니다.

무엇이 잘못 되었나요?

+0

어디에서 handleHttpErrorCode를 호출합니까? 그리고 결과로 무엇을하고 있습니까? 런타임에 정책을 선택하는 것이 이상하게 보였지만 더 큰 그림이 누락되었을 수 있습니다. 질문을 편집하여 호출 코드와 재시도 템플릿 설정을 추가하십시오. –

+0

@GaryRussell 질문이 업데이트되었습니다. – Columb1a

답변

2

항상 기본 정책을 반환합니다. 당신이 여기 return 필요처럼 그런데 ...

return handleHttpErrorCode(statusCode); 

보이는, 오히려 새로운 매번 만드는 대신 한 번 정책을 만드는 것이 더 효과적입니다.

+0

네 말이 맞아! , 또한 코드는'defaultRetry'를 마지막에 반환해서는 안됩니다. 대신에, 그 대신에'neverRetry()'를 리턴해야하고, 그렇게하면 재 시도를하지 않을 것입니다.'HttpStatusCodeException'과 다른 것을 얻으면 – Columb1a