programing

클라이언트 행세 및 스프링 재시도

elecom 2023. 10. 15. 16:59
반응형

클라이언트 행세 및 스프링 재시도

저는 Spring Cloud Feign 클라이언트를 이용하여 외부 서비스를 호출하는 휴식형 서비스가 있습니다.

@FeignClient(name = "external-service", configuration = FeignClientConfig.class)
public interface ServiceClient {

    @RequestMapping(value = "/test/payments", method = RequestMethod.POST)
    public void addPayment(@Valid @RequestBody AddPaymentRequest addPaymentRequest);

    @RequestMapping(value = "/test/payments/{paymentId}", method = RequestMethod.PUT)
    public ChangePaymentStatusResponse updatePaymentStatus(@PathVariable("paymentId") String paymentId,
            @Valid @RequestBody PaymentStatusUpdateRequest paymentStatusUpdateRequest);

}

로그 파일에서 지난 3개월 동안 3-4번 다음과 같은 장애를 발견했습니다.

json.ERROR_RESPONGESS_BODY:연결에서 POST http://external-service/external/payments json.message:결제 추가 실패 보내기: {ERROR_RESPENT_BODY=연결에서 POST http://external-service/external/payments, EVENT=ADD_PANCY_FAILURE, TRANSACION_ID=XXXXXX} {} json 실행을 거부했습니다.EVENT:ADD_Payment_FAILURE json.stack_trace:feign.RetryableException:가장하여 POST http://external-service/external/payment 실행을 거부했습니다.feignException.error실행중(feignException.java:67)을 가장합니다.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:104)를 가장하여 실행합니다.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:76)를 가장합니다.리플렉티브 페이그 $페이그호출 처리기. 호출(ReflectiveFeign.java:103)

Feign 클라이언트에서 Spring Retry를 추가할 수 있습니까?내가 언급하고 싶었던 것은addPayment와의 작전.

@Retryable(value = {feign.RetryableException.class }, maxAttempts = 3, backoff = @Backoff(delay = 2000, multiplier=2))

하지만 이건 불가능한데, 다른 방법은 뭐가 있나요?

추가할 수 있습니다.Retryer에서FeignClientConfig

@Configuration
public class FeignClientConfig {

    @Bean
    public Retryer retryer() {
        return new Custom();
    }

}

class Custom implements Retryer {

    private final int maxAttempts;
    private final long backoff;
    int attempt;

    public Custom() {
        this(2000, 3);
    }

    public Custom(long backoff, int maxAttempts) {
        this.backoff = backoff;
        this.maxAttempts = maxAttempts;
        this.attempt = 1;
    }

    public void continueOrPropagate(RetryableException e) {
        if (attempt++ >= maxAttempts) {
            throw e;
        }

        try {
            Thread.sleep(backoff);
        } catch (InterruptedException ignored) {
            Thread.currentThread().interrupt();
        }
    }

    @Override
    public Retryer clone() {
        return new Custom(backoff, maxAttempts);
    }
}

샘플로 업데이트됨Retryer예제 구성:Retryer.Default.

리본을 사용하는 경우 속성을 설정할 수 있으며 다음 속성을 사용하여 다시 시도할 수 있습니다.

myapp.ribbon.MaxAutoRetries=5
myapp.ribbon.MaxAutoRetriesNextServer=5
myapp.ribbon.OkToRetryOnAllOperations=true

참고: "my app"이 서비스 ID입니다.

Github 구현에서 작동 예를 확인합니다.

새 컨스트럭터가 생겼습니다.Default

@Configuration
public class FeignClientConfig {
    @Bean
    public Retryer retryer() {
        return new Retryer.Default(100, 2000, 3);
    }
}

누군가에게 도움이 될 수 있다면 이것을 추가하는 것.해당 포트에서 알 수 없는 프로세스가 실행 중이어서 가장을 사용하여 연결을 재설정하고 있었습니다.포트를 변경해 봅니다.포트에서 실행 중인 프로세스를 찾으려면 이를 참조합니다.

Feign Client methods로 Spring Retry를 사용하는 것에 대한 블로그 글을 준비했습니다.당신은 포스트를 확인하는 것을 고려해 볼 수 있습니다.모든 단계는 게시물에 설명되어 있습니다.

이것이 제 구성입니다.스프링 부트 2.2.0에서 OK를 테스트합니다.RELEASE Spring Cloud Hoxton.M3.

feign.hystrix.enabled=true
MY-SPRING-API.ribbon.MaxAutoRetries=2
MY-SPRING-API.ribbon.MaxAutoRetriesNextServer=2
MY-SPRING-API.ribbon.OkToRetryOnAllOperations=true
MY-SPRING-API.ribbon.retryableStatusCodes=404,500

feign.client.config.PythonPatentClient.connectTimeout=500
feign.client.config.PythonPatentClient.readTimeout=500

hystrix.command.PythonPatentClient#timeTest(String).execution.isolation.thread.timeoutInMilliseconds=5000

자바 코드는:

@FeignClient(name = "MY-SPRING-API",configuration = {PythonPatentConfig.class},fallbackFactory = FallBack.class)
public interface PythonPatentClient 
@RequestLine("GET /test?q={q}")
    void timeTest(@Param("appNo") String q);

컨트롤러:

  @RequestMapping(value = "/test",method = {RequestMethod.POST,RequestMethod.GET})
    public Object test() throws InterruptedException {
        log.info("========important print enter test========");
         TimeUnit.SECONDS.sleep(10L);

pom.xml addit on addit:

<dependency>
            <groupId>org.springframework.retry</groupId>
            <artifactId>spring-retry</artifactId>
   </dependency>

옵션:

<dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aspects</artifactId>
    </dependency>

@EnableRetry
@SpringBootApplication
public class ApiApplication

문서입니다.

https://docs.spring.io/spring-cloud-netflix/docs/2.2.10.RELEASE/reference/html/ # retry- failed-

https://github.com/spring-projects/spring-retry

https://github.com/spring-cloud/spring-cloud-netflix/

ServiceClient 위에 래퍼를 만들어 해결했습니다.

@Configuration
public class ServiceClient {

@Autowired
ServiceFeignClient serviceFeignClient;

@Retryable(value = { ClientReprocessException.class }, maxAttemptsExpression = "#{${retryMaxAttempts}}", backoff = @Backoff(delayExpression = "#{${retryDelayTime}}"))

public void addPayment( AddPaymentRequest addPaymentRequest){
    return serviceFeignClient.addPayment(addPaymentRequest);
 }    
}

언급URL : https://stackoverflow.com/questions/47151448/feign-client-and-spring-retry

반응형