시작이 반

[MSA] Spring Cloud ( Microservice간 통신 - feignClient) 본문

Programming/MSA

[MSA] Spring Cloud ( Microservice간 통신 - feignClient)

G_Gi 2021. 8. 8. 21:31
SMALL

 

https://happycloud-lee.tistory.com/207

Microservice간의 통신은 동기방식과 비동기 방식 2가지가 있다.

동기방식은 하나의 요청이 들어오면 다른작업을 하지 못한다.

이는 RestTemplate, FeignClient의 HTTP 통신 방법으로 구현이 가능하다. 

비동기방식은 변경된 사항을 전달해주고 서비스는 더이상 관여를 하지 않는 방식이디.

이는 AMQP라는 프로토콜을 이용하여 구현이 가능하다.

 

 Microservice간의 통신으로 FeignClient를 사용해보겠다.

 

FeignClient

- Rest Call을 추상화한 Spring Cloud Netfix에 포함된 라이브러리이다.

사용방법으로는 호출하려는 HTTP Endpoint에 대한 Interface를 생성하고 @FeingClient를 선언한다.

 

기존에  User-Service application을 만들어 놨다.

User-Service의 기능에서 해당 유저의 상품 주문 목록을 가져오는 API기능이 있었다.

기능 URI HTTP Method
사용자 정보 등록 /user-service/users POST
전체 사용자 조회 /user-service/users GET
사용자 정보, 주문 내역 조회 /user-service/users/{user_id} GET
작동 상태 확인 /user-service/health_check GET
환영 메시지 /user-service/welcome GET

이를 구현하기 위해서는 Order-Service에 접근하여 해당 user의 주문 목록을 가져와야한다.

기능 URI HTTP Method
사용자 별 상품 주문 /order-service/{user_id}/orders POST
사용자 별 주문 내역 조회 /order-service/{user_id}/orders GET
작동상태 확인 /order-service/health_check GET

 

즉 User-Service에서 Order-Service의 API를 호출해야한다.

User-Service에서 FeignClient를 사용하기 위해 디펜던시를 추가해준다.

또한 main 클래스에 @EnableFeignClients 어노테이션을 추가한다.

 

FeignClient는 Interface를 통해서 구현이 된다.

order-serivce를 호출해야하기 때문에 name부분에 호출하려는 마이크로서비스 이름을 작성한다. 또한 호출하고자 하는 메소드를 만들어준다. order-service의 주문목록을 가져오는 API를 호출해야 하기 떄문에 Interface에 order-service와 같은 메소드를 만들어줬다.

order-service.controller

 

 

이제 만든 FeignClient를 사용해보자.

 

사용하고자 하는 Service에서 해당 Interface를 주입시켜준다.

 

 

사용법은 간단하다 만들어놓은 인터페이스의 함수를 불러오면된다.

 

작동하는지 확인해보자

우선 userId가 필요함으로 회원가입을 해준다.

 

이번엔 해당 userId로 아무상품이나 주문을 해보자 (원래는 Catalog를 확인하고 주문해야함 아직 order와 catalog를 연결 안해놈)

 

이제 user-service에서 해당 user의 정보를 확인해보자.

주문 목록이 들어간 것을 확인할 수 있다.


로그추적

이번엔 FeignClient를 추적하는 로그를 남겨보자.

우선 application.yml파일에 해당 설정을 추가한다.

또한 main 클래스에 Logger.Level을 Bean으로 등록해준다.

 

이렇게 등록하고 해당 FeignClient를 사용하면

아래와 같이 추적할 수 있다.

 


예외처리

서비스는 서로 다른부서에서 만든다고 치자 그런데 user-service에서 order-service를 호출하는데 없는 주소를 호출한다면?

이러한 예외처리를 해보자

 

먼저 user-service에서 FeignClient로 order-service를 호출하는 주소를 order-service 없는 주소를 호출해보자.

order-service에는 order_ng라는 end point를 가진 주소를 매핑하는 함수가 없다.

해당 주소가 없기때문에 원래는 404에러가 떠야하지만

500에러가 뜨면서 설명에 FeignException의 404라고 에러가 떴다.

해당 주소가 없는게 맞는것이니 404에러가 뜨는게 좋겠다.

 

이러한 예외처리를 해보자.

물론 try-catch로 이 에러를 해결할 수 있지만 ErrorDecoder라는 Interface를 구현하여 사용할 수 있다.

ErrorDecoder라는 Interface에 선언되어있는 decode라는 메소드가 하는 역할은 FeignClient에서 발생한 에러 상태값으로 분기하여 에러를 처리할 수 있다.

해당 Interface를 구현하였다.

우선400, 404에러를 분기로 나눴고 다른 에러들은 default로 가게 해놨다.

404에러가 난다면 case 404:로 들어갈 것이다. 

 

그러먼 에러가 났을때 해당에러인 404에러를 확인할 수 있다.

 

 

이러한 서비스간의 통신(FeignClient) 오류는 user-service에서의 문제가 아님에도 해당 service에서 오류가 나는것을 볼 수 있다. 이러한것을 해결하기 위해서는 user-service가 호출하는 다른 서비스가 문제가 있을때 더이상 문제가 있는 서비스를 호출하지 않게 해야한다. 그래서 FeignClient측에서는 그 에러를 대신할 수 있는, 우회할 수 있는 다른 데이터 값을 보여줄 수 있도록 준비가 되어있어야한다.

이는 CircuitBreaker와 Resilience4J를 통해서 구현할 수 있다.

이는 다음에 포스팅하겠다.

 

 

 

<참고 : Spring Cloud로 개발하는 마이크로서비스 애플리케이션(MSA)>

LIST