Invoking services with a Load Balancer–aware Spring REST template

2026. 1. 4. 21:50Spring Microservice/Service Discovery

🚀 Load Balancer 인지 Spring RestTemplate로 서비스 호출하기

앞선 챕터에서는 Spring Discovery Client를 사용해
서비스 레지스트리(Eureka)에 등록된 인스턴스를 직접 조회하고 호출하는 방법을 살펴봤습니다.

이번에는 한 단계 더 나아가,
👉 Spring Cloud Load Balancer를 인지하는 RestTemplate 을 사용해
👉 훨씬 간결하고 실무 친화적인 방식으로 서비스를 호출하는 방법을 살펴보겠습니다.

 

🧠 Load Balancer–aware RestTemplate이란?

Load Balancer–aware RestTemplate
Spring Cloud가 제공하는 클라이언트 사이드 로드 밸런싱 기능이 결합된 RestTemplate입니다.

이 방식의 핵심 특징은 다음과 같습니다.

  • ✅ DiscoveryClient를 직접 호출하지 않음
  • ✅ 서비스의 물리적 위치(IP, 포트)를 전혀 알 필요 없음
  • ✅ Eureka에 등록된 서비스 인스턴스를 대상으로
    자동 Round-Robin 로드 밸런싱
  • ✅ 개발자는 논리적인 서비스 이름(service ID) 만 사용

 

⚙️ 1단계: Load Balancer–aware RestTemplate Bean 정의

Load Balancer 기능이 적용된 RestTemplate을 사용하려면
먼저 @LoadBalanced 어노테이션이 붙은 RestTemplate Bean을 정의해야 합니다.

📂 src/main/java/com/optimagrowth/license/LicenseServiceApplication.java

// Most of the import statements have been removed for conciseness
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();
    }
}

🔑 핵심 포인트 정리

  • 🧩 @Bean
    • Spring 컨테이너가 관리하는 RestTemplate Bean 생성
  • 🔥 @LoadBalanced
    • 이 RestTemplate에 Spring Cloud Load Balancer 인터셉터를 자동 주입
  • ⚙️ 이 인터셉터가
    • 서비스 이름 → 실제 인스턴스 주소
    • 로드 밸런싱 처리
      를 담당

👉 이제 이 RestTemplate은 일반 RestTemplate이 아닙니다.
👉 Load Balancer가 인지하는 스마트한 RestTemplate 입니다.

 

🔌 2단계: Load Balancer–aware RestTemplate 사용

이제 이 RestTemplate을 실제 서비스 호출에 사용해 보겠습니다.

📂 src/main/java/com/optimagrowth/license/service/client/OrganizationRestTemplateClient.java

// Package and import definitions left out for conciseness
@Component
public class OrganizationRestTemplateClient {

    @Autowired
    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();
    }
}

 

🔍 코드 분석: 이전 방식과 무엇이 달라졌을까?

이 코드는 앞서 살펴본 Discovery Client 방식과 비슷해 보이지만,
실제로는 두 가지 핵심적인 차이점이 있습니다.

 

❌ 1. DiscoveryClient가 보이지 않는다

@Autowired
private DiscoveryClient discoveryClient;
  • ❌ 없음
  • ❌ 서비스 인스턴스 조회 코드 없음
  • ❌ ServiceInstance 리스트 없음

👉 Discovery Client를 직접 다루지 않습니다.

 

🔥 2. URL이 매우 “이상해” 보인다

"http://organization-service/v1/organization/{organizationId}"

처음 보면 의문이 듭니다.

🤔 “organization-service”라는 서버가 실제로 존재하나?

 

🧠 URL의 비밀: 서비스 ID 기반 호출

이 URL의 서버 이름 부분은 다음과 같은 규칙을 따릅니다.

http://{applicationId}/v1/organization/{organizationId}

여기서

  • organization-service
    • Eureka에 등록할 때 사용한 application ID
  • 실제 IP, 포트 정보는 ❌ 전혀 포함되지 않음

 

⚙️ 내부 동작 원리 (중요!)

Load Balancer–enabled RestTemplate은 다음과 같은 순서로 동작합니다.

1️⃣ RestTemplate이 URL을 파싱
2️⃣ organization-service서버 이름(server name) 으로 인식
3️⃣ 이 값을 키(key) 로 사용해 Load Balancer에 질의
4️⃣ Load Balancer가

  • Eureka에서 해당 서비스의 인스턴스 목록 조회
    5️⃣ 그중 하나의 인스턴스를 선택
    6️⃣ 실제 호출 대상 URL로 변환
    7️⃣ HTTP 요청 전송

👉 이 모든 과정이 개발자 코드 밖에서 자동으로 수행됩니다.

 

🔄 자동 Round-Robin 로드 밸런싱

또 하나의 중요한 장점은 바로 이것입니다.

Spring Cloud Load Balancer는
모든 서비스 인스턴스에 대해
Round-Robin 방식으로 요청을 분산합니다.

  • ✔️ 첫 요청 → 인스턴스 A
  • ✔️ 두 번째 요청 → 인스턴스 B
  • ✔️ 세 번째 요청 → 인스턴스 C
  • ✔️ 다시 A …

👉 추가 코드 작성 없이 자동 로드 밸런싱

 

✨ Discovery Client 방식 vs LoadBalanced RestTemplate

구분 Discovery Client LoadBalanced RestTemplate
서비스 인스턴스 조회 직접 자동
URL 구성 직접 조합 서비스 ID만 사용
로드 밸런싱 ❌ 직접 구현 ✅ 자동
코드 복잡도 높음 매우 낮음
실무 사용성 낮음 매우 높음

 

🧾 정리 (Takeaway)

Load Balancer–aware RestTemplate
Spring에서 가장 일반적으로 사용되는 서비스 호출 방식 중 하나입니다.

✔ 개발자는 다음만 신경 쓰면 됩니다.

  • 🔑 서비스 ID
  • 🔑 API 경로

✔ 다음은 Spring Cloud가 대신 처리합니다.

  • 🔥 서비스 인스턴스 조회
  • 🔥 로드 밸런싱
  • 🔥 실제 주소 변환

👉 “서비스가 어디 있는지”는 잊고
“무슨 서비스를 호출할지”에만 집중하세요.