codememo

Netflix Feign - 마이크로 서비스를 통해 상태 및 예외 전파

tipmemo 2023. 4. 3. 21:32
반응형

Netflix Feign - 마이크로 서비스를 통해 상태 및 예외 전파

Netflix Feign을 사용하여 Microservice A의 한 조작과 Spring Boot을 사용하여 코드를 검증하는 Microservice B의 다른 조작을 호출합니다.

마이크로 서비스 B, 마이크로 서비스 B, 마이크로 서비스 B. 하여 ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★.HttpStatus.UNPROCESSABLE_ENTITY (422)는요?

@ExceptionHandler({
       ValidateException.class
    })
    @ResponseStatus(HttpStatus.UNPROCESSABLE_ENTITY)
    @ResponseBody
    public Object validationException(final HttpServletRequest request, final validateException exception) {
        log.error(exception.getMessage(), exception);
        error.setErrorMessage(exception.getMessage());
        error.setErrorCode(exception.getCode().toString());
        return error;
    }

따라서 Microservice A가 인터페이스의 B에 다음과 같이 콜을 하면 다음과 같이 됩니다.

@Headers("Content-Type: " + MediaType.APPLICATION_JSON_UTF8_VALUE)
@RequestLine("GET /other")
void otherOperation(@Param("other")  String other );

@Headers("Content-Type: " + MediaType.APPLICATION_JSON_UTF8_VALUE)
@RequestLine("GET /code/validate")
Boolean validate(@Param("prefix") String prefix);

static PromotionClient connect() {

    return Feign.builder()
        .encoder(new GsonEncoder())
        .decoder(new GsonDecoder())
        .target(PromotionClient.class, Urls.SERVICE_URL.toString());
}

검증에 실패하면 다음 메시지와 함께 내부 오류 500이 반환됩니다.

{
  "timestamp": "2016-08-05T09:17:49.939+0000",
  "status": 500,
  "error": "Internal Server Error",
  "exception": "feign.FeignException",
  "message": "status 422 reading Client#validate(String); content:\n{\r\n  \"errorCode\" : \"VALIDATION_EXISTS\",\r\n  \"errorMessage\" : \"Code already exists.\"\r\n}",
  "path": "/code/validate"
}

하지만 나는 Microservice operation B와 동일하게 반품해야 합니다.

Netflix Feign을 사용하여 마이크로 서비스를 통해 상태 및 예외를 전파하는 가장 좋은 방법 또는 기술은 무엇입니까?

ErrorDecoder

https://github.com/OpenFeign/feign/wiki/Custom-error-handling

여기 예가 있습니다.

public class MyErrorDecoder implements ErrorDecoder {

    private final ErrorDecoder defaultErrorDecoder = new Default();

    @Override
    public Exception decode(String methodKey, Response response) {
        if (response.status() >= 400 && response.status() <= 499) {
            return new MyBadRequestException();
        }
        return defaultErrorDecoder.decode(methodKey, response);
    }

}

봄에 ErrorDecoder를 픽업하려면 ApplicationContext에 저장해야 합니다.

@Bean
public MyErrorDecoder myErrorDecoder() {
  return new MyErrorDecoder();
}

리플렉션을 사용하여 응답 본문에 반환된 오류 코드를 기반으로 체크된 예외(및 체크되지 않은 경우)를 동적으로 재투입하는 작은 라이브러리용 파렴치 플러그.

readme에 대한 자세한 내용은http://https://github.com/coveo/feign-error-decoder 를 참조해 주세요.

OpenFeign의 FeignException이 특정 HTTP 상태에 바인딩되지 않음(Spring을 사용하지 않음)@ResponseStatus에 의해 로 「」로 됩니다.500의 경우에FeignException괜찮아요, 왜냐하면FeignException에는 특정 HTTP 상태와 관련되지 않는 여러 원인이 있을 수 있습니다.

, 할 수 .FeignExceptions .ExceptionHandlerthat 를 취급하는FeignException필요한 방법(여기를 참조):

@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(FeignException.class)
    public String handleFeignStatusException(FeignException e, HttpServletResponse response) {
        response.setStatus(e.status());
        return "feignError";
    }

}

이 예에서는 스프링이 Microservice B로부터 받은 것과 같은 HTTP 상태를 반환하도록 합니다.더 나아가 원래 응답 본문을 반환할 수도 있습니다.

response.getOutputStream().write(e.content());

사용자 정의 예외 매퍼를 작성하여 등록합니다.응답을 사용자 정의할 수 있습니다.

완전한 예는 다음과 같습니다.

public class GenericExceptionMapper implements ExceptionMapper<Throwable> {

    @Override
    public Response toResponse(Throwable ex) {
        return Response.status(500).entity(YOUR_RETURN_OBJ_HERE).build();
    }

}

2017년 이후 NAT은 주석으로 이를 수행하는 라이브러리를 만들었습니다(요청 등과 마찬가지로 주석으로 코드화하는 것이 매우 용이합니다).

기본적으로 에러 처리를 다음과 같이 코드화할 수 있습니다.

@ErrorHandling(codeSpecific =
    {
        @ErrorCodes( codes = {401}, generate = UnAuthorizedException.class),
        @ErrorCodes( codes = {403}, generate = ForbiddenException.class),
        @ErrorCodes( codes = {404}, generate = UnknownItemException.class),
    },
    defaultException = ClassLevelDefaultException.class
)
interface GitHub {

    @ErrorHandling(codeSpecific =
        {
            @ErrorCodes( codes = {404}, generate = NonExistentRepoException.class),
            @ErrorCodes( codes = {502, 503, 504}, generate = RetryAfterCertainTimeException.class),
        },
        defaultException = FailedToGetContributorsException.class
    )
    @RequestLine("GET /repos/{owner}/{repo}/contributors")
    List<Contributor> contributors(@Param("owner") String owner, @Param("repo") String repo);
}

OpenFeign 조직(https://github.com/OpenFeign/feign-annotation-error-decoder에서 찾을 수 있습니다.

면책사항:난 그 에러 디코더의 주 개발자이자 가장의 공신이다.

델의 업무는 다음과 같습니다.

예외를 포함하는 공통 jar를 두 마이크로 서비스와 공유합니다.

1) microservices에서 예외를 DTO 클래스로 변환하면 ErrorInfo라고 합니다.String 예외와 함께 커스텀 예외의 모든 속성이 포함됩니다.유형: 예외 클래스 이름을 포함합니다.

2) 마이크로서비스 B에서 수신되면 마이크로서비스 B의 ErrorDecoder에 의해 처리되며 예외에서 예외 개체를 생성하려고 합니다.다음과 같이 입력합니다.

@Override
public Exception decode(String methodKey, Response response) {       

ErrorInfo errorInfo = objectMapper.readValue(details, ErrorInfo.class);
Class exceptionClass;

Exception decodedException;

try {

    exceptionClass = Class.forName(errorInfo.getExceptionType());  

    decodedException = (Exception) exceptionClass.newInstance();

    return decodedException;

 }

 catch (ClassNotFoundException e) {

    return new PlatformExecutionException(details, errorInfo);

 }
  return defaultErrorDecoder.decode(methodKey, response);
 }

언급URL : https://stackoverflow.com/questions/38786207/netflix-feign-propagate-status-and-exception-through-microservices

반응형