MSA 기반 프로젝트 중 마이크로 서비스 간 통신 방식에 대하여 고민하게 되었다.
알람 서비스에서는 Kafka를 이용하여 실시간 비동기 처리를 통해 빠르게 여러 마이크로 서비스에서 이벤트를 받는 식으로 구성했었다.
그런데 현재 개발중인 쪽지 서비스에서 채팅방 목록을 출력할 때 상대방의 닉네임들을 같이 출력해야 하는데 이것을 어떻게 가져올지 고민했다.
Kafka를 이용하여 가져오기엔 닉네임 하나 가져오자고 굳이 Kafka 설정 코드들을 작성해야 하나 생각이 들었다.
물론 실시간성이 중요한 서비스라면 Kafka를 통해 통신하는게 필수라고 생각하지만 채팅방 닉네임 출력 같은 경우에는 한 번만 얻어오면 되고, 그렇게 실시간성을 요하는 기능이 아니라 생각되어서 REST API를 통해 요청을 보내기로 했다.
마이크로 서비스간에 REST API 통신을 손쉽게 할 수 있는 방법으로 FeignClient라는 라이브러리가 있다.
Feign Client
HTTP 요청을 자동으로 대신 보내주는 REST 클라이언트로 비동기 처리 방식이 아닌 일반적인 동기 처리 방식이다.
마이크로 서비스에서 통신을 단순화하기 위해 사용한다.
먼저 의존성을 추가해야한다.
build.gradle에 아래의 의존성을 추가하자
implementation 'org.springframework.cloud:spring-cloud-starter-openfeign'
그리고 메인 실행 클래스에 @EnableFeignClients 애노테이션을 붙여줘야 동작한다.
주의
현재 Spring Boot 3.4.4 버전에서 지원을 하지 않는다. 3.2.x 버전으로 낮춰서 사용하자
아니라면 RestTemplate 혹은 WebClient로 통신해야 한다.
build.gradle에서 아래 사진과 같이 버전을 간단하게 변경할 수 있다.
코드 작성 및 사용 방법
그리고 Interface를 만들어서 통신할 마이크로 서비스의 엔드포인트와 포트번호 등을 작성한다.
현재 나는 유저 Service에서 닉네임을 얻어와 채팅방에 상대방의 닉네임을 표시해야 하기 때문에 닉네임 반환 API를 호출하는 메서드를 작성했다.
configuration 부분은 인증 등이 필요하여 Config 설정이 필요한 경우가 아니면 생략해도 된다.
나는 user-service에 접근하므로 현재 Security 인증이 필요한 상황이기 때문에 FeignConfig.class에 토큰 관련 설정을 추가했다.
서비스 단에서는 일반 메서드처럼 불러서 사용하면 된다.
private String getTargetNickname(Long targetUserId) {
return userClient.getNicknameById(targetUserId).getData();
}
getTargetNickname 메서드를 호출하면 userClient의 getNicknameById가 유저 서비스에 API 호출을 하여 얻은 응답 값을 반환해 준다.
나는 DTO에 상대방 닉네임을 삽입하는 게 목적이었으므로 아래와 같이 사용했다.