
MSA 프로젝트를 개인적으로 진행하며 인증을 담당하는 Auth-service와 사용자의 CRUD를 담당하는 User-service를 분리하여 개발하였다.
하지만 Auth-service에서 로그인 처리를 하기 위해선 User 정보가 필요하여 User-service에 작성된 코드를 Auth-service에 똑같이 작성하고 있는 나를 보았다.
무언가 잘 못 되었다고 생각하여 어떻게 하면 MSA 구조에서 각각의 서비스의 역할을 명확히 분리하여 중복 코드도 제거하고 효율적으로 개발 할 수 있을지 알아보았다.
결론은 외부 API를 호출하는 것처럼 다른 서비스의 API를 호출하면 된다. 예를 들면, Auth-service에서 사용자 정보를 DB에서 확인하는 것이 아닌 User-service에 이미 만들어진 사용자 정보 조회 API를 호출하는 것이다.
이때 사용할 수 있는 방법 중 하나가 OpenFeign이다. 이 글에서는 OpenFeign에 대한 개념과 활용법을 간단히 정리해보려고 한다.
Open Feign은 Netflix에 의해 처음 만들어진 Declarative(선언적) HTTP Client 도구로써, 외부 API 호출을 쉽게 할 수 있도록 도와준다. 여기서 "선언적인" 이란 어노테이션 사용을 의미하는데, Open Feign은 인터페이스에 어노이션들만 붙여주면 된다.
실제로 프로젝트에서 사용자 정보를 가져오기 위해 구현한 코드는 다음과 같다.
@FeignClient(name = "user-service")
public interface UserClient {
@PostMapping(UserUri.DEFAULT)
ResponseEntity<ApiResponse<UserEntityResponse>> join(UserEntityRequest userEntityRequest);
@GetMapping(UserUri.DEFAULT + UserUri.USERNAME_VARIABLE)
ResponseEntity<ApiResponse<UserEntityResponse>> getDetail(@PathVariable String username);
}
@FeignClient 어노테이션을 붙이고 속성 값으로 name을 입력해준다. 여기서 외부 API를 호출하는 경우 name에는 말그대로 임의의 이름을 적어주면 되고, url을 추가로 입력해주어 해당 url의 client를 호출할 수 있도록 한다.
하지만 여기선 Eureka 서비스로 등록 된 내부 API 통신이 이루어지기 때문에 이 경우엔 Eureka에 등록 된 서비스 명(application name)만 name에 입력해주면 된다.
OpenFeign을 적용하면서 연관된 라이브러리인 Resilence4j라는 것을 알게 되었다.
해당 라이브러리를 사용하기 위해서 서킷브레이커 패턴을 알아야 한다.
https://mangkyu.tistory.com/289
해당 글에서 잘 설명해주어 참고하였다.
서킷브레이커 패턴은 장애가 발생한 서비스에 대한 호출을 제한하여 시스템 전체의 장애 전파를 막고, 일정 시간이 지나거나 오류율이 감소하면 다시 요청을 허용하는 방식으로 동작한다. 이를 Spring Boot에서 구현하기 윟해 Resilence4j 라이브러리를 활용할 수 있다.
서킷 브레이커는 아래와 같은 주요 상태를 가진다.
처음에는 Closed가 왜 정상적인 상태지? 라고 생각했는데 대상 서버가 기준이 아닌 서킷 브레이커를 기준으로 상태를 생각하면 쉽게 이해할 수 있다.
Resilence4j의 기능은 서킷 브레이커를 기본으로 하여 다음과 같은 기능을 추가로 제공한다.
Retry: 일정 횟수만큼 재시도하는 기능
Rate Limiter: 특정 시간 내 요청 수를 제한하는 기능
Bulkhead: 병렬 요청 수를 제한하는 기능
TimeLimiter: 요청이 일정 시간 내 응답하지 않으면 타임아웃 처리하는 기능
이 기능을 활용하여 clent 서버에 장애가 발생했을 때 기본 응답을 하도록 설정한다던지 재요청을 보낸다던지 대응을 할 수 있도록 해준다.
Spring에서 REST API를 호출하는 방법으로 openFeign 외에 두가지 정도를 들 수 있을 것 같다.
이들을 비교해보자면 난이도는 WebClient > RestTemplate > OpenFeign 순으로 쉽고 RestTemplate의 경우 Spring 5.0부터 Deprecated 예정이라 Spring Cloud를 사용한다면 OpenFeign을 그렇지 않다면 WebClient를 사용하면 될 것 같다.
다만 OpenFeign은 기본적으로 RestTemplate으로 동작하기에 사실상 동일한데, 이를 WebClient로 변경하여 사용할 수도 있으니 비동기로 구현하고 싶거나 높은 성능을 요구한다면 변경을 고려해볼만하다.
OpenFeign을 활용해보았고 연관된 라이브러리인 Resilence4j에 대해서도 간단히 정리해보았다.
좋은 기능임에는 틀림없지만 아직까지는 이러한 기능의 필요성을 느끼지 못하고 있어 추후 적용해보면 좋을 것 같다.
그리고 openFeign client에 대한 테스트 코드를 작성하는 것에 있어 어려움을 느꼈는데 이에 대한 내용도 조금 더 공부를 해봐야 할 것 같다.