이번에는 서비스간 동기 통신이 필요한 경우 어떻게 해결했는지 이야기해보려 합니다.
1. 문제 발생 : 동기 통신이 필요하게 된 계기
region-service에는 모든 지역의 땅 주인 정보를 조회하는 API가 있습니다. 각 지역의 땅 주인 닉네임과 펫 정보를 함께 제공해야 하지만, 서비스 분리로 인해 DB가 나뉘면서 region-service DB에서는 최근 땅 주인들의 userId 정보만 조회할 수 있고, 해당 userId에 대한 추가 정보는 조회할 수 없습니다.
이를 해결하기 위해, 유저의 닉네임과 펫 정보를 project-service에 동기적으로 요청하기로 결정했습니다.
2. 동기 통신 구성 : Spring Cloud OpenFeign
Open Feign이란 ?
선언적인 http 클라이언트 도구로, 인터페이스에 어노테이션을 추가하여 외부 API 호출을 돕는 도구를 말합니다.
Spring Cloud에 통합되어 Eureka를 활용하여 Open Fegin를 사용할 수 있습니다.
이미 Eureka를 활용하고 있기 때문에 특정 ip나 포트를 호출하지 않아도, 서비스별로 호출이 용이합니다.
3. Spring Cloud Open Feign 구성
1) gralde 의존성 추가
implementation 'org.springframework.cloud:spring-cloud-starter-openfeign'
2) FeignClient 활성화
@EnableFeignClients
@EnableDiscoveryClient
@SpringBootApplication
public class ProjectApplication {
public static void main(String[] args) {
SpringApplication.run(ProjectApplication.class, args);
}
}
3) project-service에 controller 생성
유저의 닉네임과 펫 정보를 조회할 수 있는 controller입니다.
@RestController
@RequestMapping("/api/v2/user-service")
@RequiredArgsConstructor
public class UserController {
private final UserService userService;
@GetMapping("/user-pets")
public UserAndPetInfo fetchUserAndPetsInfo(@PathVariable int userId) {
UserAndPetInfo response = userService.findUserAndPetsInfo(userId);
return response;
}
}
4)region-service에서 FeignClient 인터페이스 생성
project-service에서 호출할 client의 인터페이스를 생성합니다.
@FeignClient(name = "project-service", path = "/api/v2/user-service")
public interface UserFeignClient {
@GetMapping("/user-pets")
public UserAndPetInfo fetchUserAndPetsInfo(@PathVariable int userId);
}
5) 인터페이스 호출
메서드를 호출함으로써, client가 실행되고 project-service에 http 요청을 전달하여 응답값을 받아옵니다.
@Service
@RequiredArgsConstructor
public class RegionService {
...
private final UserFeignClient userFeignClient;
...
/**
* resion_owner_log 테이블에서 지역별 땅 주인을 조회한다.
*/
public RegionVisit<RegionOwnerCityDetail> fetchRegionOwners() {
// 최근 땅 주인 조회
List<RegionOwnerInfo> regionOwnerInfos = regionOwnerLogRepository.findRegionOwner();
...
// 주인 닉네임과 펫 정보 요청
UserAndPetInfo userAndPetInfo = userFeignClient.fetchUserAndPetsInfo(roi.getUserId());
...
return regionVisit;
}
4. 연결 테스트
테스트 결과, 모든 지역 땅 주인 조회 시, 각 유저의 닉네임과 펫 정보도 같이 조회됩니다.
4. 보완하면 좋을 점
userId에 정보를 조회하기 위해 매번 api 요청을 할 순 없으니, MSA 전환 과정이 끝나면, 캐싱 또는 다른 방법을 고려해 api 호출 빈도수를 줄여야겠습니다.
'댕댕어디가 프로젝트 > MSA' 카테고리의 다른 글
[댕댕어디가] MSA 아키텍처 전환기(8) - 서비스간 트랜잭션 (0) | 2025.01.15 |
---|---|
[댕댕어디가] MSA 아키텍처 전환기(7) - 인증서버 연결 (0) | 2025.01.14 |
[댕댕어디가] MSA 아키텍처 전환기(5) - 서비스간 비동기 통신 (kafka 연결) (0) | 2025.01.11 |
[댕댕어디가] MSA 아키텍처 전환기(4) - 서비스간 비동기 통신하기 (0) | 2025.01.08 |
[댕댕어디가] MSA 아키텍처 전환기(3) - API Gateway 구현 (0) | 2025.01.07 |