MSA 아키텍처에서 API Gateway, Eureka(Discovery Server)의 차이점과 Load Balancer

cchoijjinyoung·2025년 2월 11일

마이크로서비스 아키텍처(MSA)를 설계할 때, 확장성유지보수성을 위해 각 구성 요소의 역할을 명확히 하는 것이 중요합니다. 이번 글에서는 API Gateway, Eureka(Discovery Server), Load Balancer(LB), 그리고 클라이언트가 각각 어떤 목적을 가지고 있으며, 이들이 어떻게 상호 작용하여 확장성 있는 시스템을 구성하는지 정리해보겠습니다.


1. API Gateway와 Eureka의 차이점 및 역할 구분

1.1 API Gateway

  • 주소 추상화 및 라우팅:

    • 클라이언트가 직접 각 서비스의 포트나 주소를 알 필요 없이, http://api-gateway/ 등의 단일 엔드포인트로 접근할 수 있도록 합니다.

    • 예를 들어, ProductService의 실제 주소가 http://localhost:9091이라 하더라도, Gateway에서 http://product-service로 매핑해주면, Front-end 개발자분들은 포트 변경이나 인스턴스 스케일아웃에 대해 신경 쓸 필요가 없습니다.

  • 부가 기능 제공:

    • 인증/인가: 잘못된 요청은 내부 서비스로 전달되지 않고 Gateway에서 바로 401/403 응답 처리

    • 캐싱: 빈번하지만 변경이 적은 데이터를 Gateway에서 캐싱하여 응답 속도 개선

    • 로깅, 모니터링 등 추가 기능을 제공하여 서비스의 안정성을 높입니다.

1.2 Eureka (Discovery Server)

  • 서비스 등록 및 상태 모니터링:

    • 각 서비스는 자신이 어느 포트에서 실행되고 있는지, 그리고 정상적인 상태(UP/DOWN)를 Eureka에 등록합니다.

    • Eureka 서버는 등록된 서비스들의 정보를 실시간으로 관리하며, 다른 서비스가 요청 시 Eureka를 통해 최신 정보를 받아올 수 있습니다.

  • 동적 서비스 검색:

    • 내부 서비스(예: order-service)가 product-service에 요청을 보내야 할 때, Eureka에서 현재 사용 가능한 인스턴스의 정보를 조회하고 적절한 인스턴스를 선택할 수 있습니다.

2. FeignClient와 Load Balancer (Ribbon → Spring Cloud LoadBalancer)

2.1 FeignClient

목적:

  • FeignClient는 MSA에서 마이크로서비스 간의 HTTP 요청을 보다 쉽게 처리할 수 있도록 해주는 선언적(Declarative) REST 클라이언트입니다.
  • 내부 서비스 간 통신을 단순화하며, Eureka와 연동하여 동적으로 서비스 인스턴스를 찾을 수 있습니다.
  • Spring Cloud 2020 이전에는 Netflix Ribbon을 사용하여 로드밸런싱을 수행했지만, 이후 버전에서는 Spring Cloud LoadBalancer가 기본 로드밸런서로 사용됩니다.

예제:

@FeignClient(name = "product-service")
public interface ProductClient {
    @GetMapping("/products/{id}")
    ProductResponse getProductById(@PathVariable("id") Long id);
}
  • name = "product-service"를 설정하면, product-service의 인스턴스를 Eureka에서 자동으로 조회하여 로드밸런싱을 수행합니다.

2.2 Load Balancer (Ribbon → Spring Cloud LoadBalancer)

목적:

  • 여러 인스턴스로 구성된 동일 서비스(예: 여러 개의 product-service 인스턴스) 사이에 요청을 분산
  • 과부하를 방지하고, 장애가 발생한 인스턴스 대신 정상적인 인스턴스로 요청을 라우팅

Spring Cloud 2020 이전 (Ribbon 사용 시)

기존 Spring Cloud에서 FeignClient는 기본적으로 Ribbon을 사용하여 로드밸런싱을 수행했습니다.

@FeignClient(name = "product-service")
public interface ProductClient {
    @GetMapping("/products/{id}")
    ProductResponse getProductById(@PathVariable("id") Long id);
}

✔️ Ribbon이 Eureka와 연동되어 자동으로 서비스 인스턴스를 조회하고 로드밸런싱을 수행했습니다.

Spring Cloud 2020 이후 (Spring Cloud LoadBalancer 적용)

Ribbon이 Spring Cloud에서 제거되었으며, 대신 Spring Cloud LoadBalancer가 기본 로드밸런서로 적용되었습니다.

spring:
  cloud:
    loadbalancer:
      ribbon:
        enabled: false  
                # true => Ribbon 활성화

✔️ Ribbon을 비활성화하고, Spring Cloud LoadBalancer를 기본적으로 사용하도록 변경되었습니다.

Spring Cloud LoadBalancer 사용 예제

@Bean
@LoadBalanced
public RestTemplate restTemplate() {
    return new RestTemplate();
}

✔️ @LoadBalanced를 붙이면 RestTemplate이 Eureka에서 서비스 인스턴스를 조회하여 로드밸런싱을 수행합니다.

참고: API Gateway도 간단한 로드밸런싱 기능을 제공할 수 있으나, Gateway의 본래 목적은 클라이언트 요청 라우팅과 인증/인가, 캐싱 등 부가 기능에 집중하는 것입니다. 따라서, 본격적인 부하 분산은 전용 LB가 맡는 것이 좋습니다.


3. 결론

MSA 환경에서 API Gateway, Eureka(Discovery Server), Load Balancer는 각자의 목적에 맞게 역할을 수행하며, 이를 적절히 활용하면 확장성과 유지보수성이 뛰어난 시스템을 구축할 수 있습니다.

  • API Gateway는 클라이언트 요청을 최적화하고,
  • Eureka는 내부 서비스들의 위치 및 상태를 관리하며,
  • Load Balancer는 부하를 효율적으로 분산합니다.
  • Spring Cloud 2020 이후 Ribbon이 제거되었으며, Spring Cloud LoadBalancer가 기본 로드밸런서 역할을 수행합니다.

이를 통해 안정적이고 확장 가능한 MSA 아키텍처를 설계할 수 있습니다.

MSA API Gateway Eureka Load Balancer 썸네일

profile
반갑습니다 :)

0개의 댓글