Spring Microservice

Load Balancer를 지원하는 Spring RestTemplate을 활용한 서비스 호출

헬로우월드 2025. 3. 14. 17:56

🚀 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-serviceEureka에서 등록된 서비스 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와 연동되어 동적으로 서비스 위치를 탐색하고 호출할 수 있음
로드 밸런싱이 적용되어 여러 개의 인스턴스가 있을 경우 자동으로 분배됨