Load Balancer를 지원하는 Spring RestTemplate을 활용한 서비스 호출
🚀 Load Balancer를 지원하는 Spring RestTemplate을 활용한 서비스 호출
마이크로서비스 환경에서는 서비스 간 동적인 호출이 필수적입니다.
Spring Boot는 이를 위해 로드 밸런싱이 적용된 RestTemplate을 제공하며,
이를 사용하면 Eureka에 등록된 서비스의 위치를 자동으로 탐색하고 호출할 수 있습니다.
이번 글에서는 Spring Cloud의 Load Balancer–aware RestTemplate을 활용하여 서비스 호출하는 방법을 다룹니다. 💡
🎯 1. Load Balancer–aware RestTemplate이란?
Spring Cloud에서 제공하는 @LoadBalanced RestTemplate 은 Eureka와 연동되어 자동으로 서비스 인스턴스를 탐색하고 호출할 수 있는 기능을 제공합니다.
✅ 기존 RestTemplate vs Load Balancer–aware RestTemplate
방식 | 사용 방법 | 장점 | 단점 |
---|---|---|---|
기존 RestTemplate | 직접 URL 지정 (http://localhost:8081 ) |
직접 제어 가능 | Eureka를 통한 서비스 탐색 불가 |
@LoadBalanced RestTemplate | http://organization-service 처럼 서비스 ID로 호출 |
Eureka와 자동 연동 | 특정 환경에서는 설정이 필요 |
✔ 기존 RestTemplate은 특정 호스트와 포트로 요청을 보냄
✔ @LoadBalanced RestTemplate은 Eureka를 활용하여 서비스 위치를 동적으로 탐색
💡 즉, 하드코딩된 URL을 사용하지 않고 Eureka의 서비스 ID를 이용하여 동적으로 호출할 수 있습니다. 🚀
🏗 2. Load Balanced RestTemplate 설정하기
✅ 1️⃣ RestTemplate
을 Bean으로 등록
Spring Boot에서 로드 밸런싱을 지원하는 RestTemplate을 사용하려면, @LoadBalanced
애너테이션을 추가하여 Bean으로 등록해야 합니다.
📌 LicenseServiceApplication.java
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
@RefreshScope
public class LicenseServiceApplication {
public static void main(String[] args) {
SpringApplication.run(LicenseServiceApplication.class, args);
}
@LoadBalanced
@Bean
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
}
✔ @LoadBalanced
를 추가하면 RestTemplate이 Eureka와 연동됨
✔ 이제 서비스 ID(organization-service
)만으로 호출 가능
✔ Spring Cloud Load Balancer가 자동으로 적절한 인스턴스를 선택하여 요청을 보냄
🔍 3. Load Balanced RestTemplate을 활용한 서비스 호출
✅ 2️⃣ RestTemplate
을 사용하여 Organization Service 호출
이제 RestTemplate
을 사용하여 Organization Service의 데이터를 가져오는 클라이언트를 작성해보겠습니다.
📌 OrganizationRestTemplateClient.java
@Component
public class OrganizationRestTemplateClient {
@Autowired
private RestTemplate restTemplate;
public Organization getOrganization(String organizationId) {
ResponseEntity<Organization> restExchange =
restTemplate.exchange(
"http://organization-service/v1/organization/{organizationId}",
HttpMethod.GET, null, Organization.class, organizationId);
return restExchange.getBody();
}
}
✔ @Autowired RestTemplate
을 사용하여 서비스 호출
✔ "http://organization-service"를 직접 사용 → Eureka에서 자동으로 적절한 인스턴스를 찾음
✔ 로드 밸런싱이 적용되어 여러 개의 Organization Service 인스턴스가 있을 경우 자동 분배됨
⚠️ 4. Load Balanced RestTemplate을 사용할 때 주의할 점
1️⃣ Eureka 서비스 ID 사용 방식
기존의 RestTemplate에서는 다음과 같이 직접 URL을 지정해야 했습니다.
restTemplate.exchange("http://localhost:8081/v1/organization/{organizationId}", ...)
하지만 @LoadBalanced RestTemplate을 사용하면 Eureka 서비스 ID를 직접 사용할 수 있습니다.
restTemplate.exchange("http://organization-service/v1/organization/{organizationId}", ...)
✔ organization-service
→ Eureka에서 등록된 서비스 ID
✔ Eureka가 자동으로 해당 서비스의 실제 위치(IP, 포트)를 찾아 요청을 보냄
2️⃣ @LoadBalanced 애너테이션이 없는 경우 오류 발생 🚨
만약 @LoadBalanced
없이 위 코드를 실행하면, 다음과 같은 오류가 발생합니다.
java.net.UnknownHostException: organization-service
💡 해결 방법:
- RestTemplate을 Bean으로 등록할 때
@LoadBalanced
를 반드시 추가해야 함
@LoadBalanced
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
🔄 5. Load Balanced RestTemplate vs 다른 방식 비교
방식 | Eureka 연동 | 로드 밸런싱 지원 | 코드 간결성 | 사용 추천 시점 |
---|---|---|---|---|
DiscoveryClient | ✅ | ❌ (직접 선택해야 함) | 복잡함 | 서비스 목록을 직접 조회할 때 |
Load Balanced RestTemplate | ✅ | ✅ | 보통 | REST API 호출 시 |
Feign Client | ✅ | ✅ | 가장 간결함 | 간단한 API 호출 시 |
💡 Feign Client가 가장 사용하기 편리하지만, 일부 경우에는 RestTemplate이 필요할 수도 있습니다.
🎯 6. 서비스 호출 예제
✔ GET 요청 예시
GET http://localhost:8082/v1/organization/123/license/456/rest
✔ RestTemplate을 사용한 서비스 호출
Organization organization = restTemplate.getForObject(
"http://organization-service/v1/organization/{organizationId}",
Organization.class, organizationId);
📌 Eureka에서 organization-service
의 실제 위치를 자동으로 찾아 호출 🎯
🏆 결론
이번 글에서는 Spring Cloud Load Balancer를 지원하는 RestTemplate을 활용하여 마이크로서비스를 호출하는 방법을 알아보았습니다. 🚀
✅ 핵심 정리
✔ @LoadBalanced를 사용하면 Eureka 서비스 ID로 호출 가능
✔ RestTemplate을 직접 생성하는 것이 아니라 Spring Boot에서 Bean으로 등록해야 함
✔ Eureka와 연동되어 동적으로 서비스 위치를 탐색하고 호출할 수 있음
✔ 로드 밸런싱이 적용되어 여러 개의 인스턴스가 있을 경우 자동으로 분배됨