김민주

[MSA] Client Side Load Balancing(ReignClient, Ribbon) 본문

STUDY/이론

[MSA] Client Side Load Balancing(ReignClient, Ribbon)

7alswn 2024. 12. 4. 16:19

MSA 목차

  • Spring Cloud
  • 서비스 디스커버리(Eureka)
  • 클라이언트 사이드 로드 밸런싱 (FeignClient, Ribbon)   해당 포스트
  • 서킷 브레이커 (Resilience4j)
  • API 게이트웨이 (Spring Cloud Gateway)
  • 보안 구성 (OAuth2 + JWT)
  • 컨피그 서버 (Spring Cloud Config)
  • 분산 추적 (Spring Cloud Sleuth) 및 로깅 (Zipkin)
  • 이벤트 드리븐 아키텍처와 스트림 처리 (Spring Cloud Stream)
  • 마무리, 쿠버네티스

Client Side Load Balancing

로드 밸런싱이란?

네트워크 트래픽을 여러 서버로 분산시켜 서버의 부하를 줄이고, 시스템의 성능과 가용성을 높이는 기술입니다. 이를 통해 서버 간 트래픽을 고르게 분배하여 특정 서버에 부하가 집중되는 것을 방지할 수 있습니다. 종류로는 클라이언트 사이드 로드 밸런싱과 서버 사이드 로드 밸런싱이 있습니다.

Client Side Load Balancing

클라이언트가 직접 여러 서버 중 하나를 선택해 요청을 보내는 방식이 클라이언트 사이드 로드 밸런싱입니다. 클라이언트는 서버의 목록을 갖고 있으며, 이를 바탕으로 로드 밸런싱을 수행합니다.

FeignClient

FeignClient는 Spring Cloud에서 제공하는 HTTP 클라이언트이며, 선언적으로 RESTful 웹 서비스를 호출할 수 있습니다.

  • 선언적 HTTP 클라이언트: 인터페이스와 어노테이션으로 REST API를 호출할 수 있습니다.
  • Eureka 연동: Eureka와 통합하여 서비스 인스턴스 목록을 동적으로 조회하고 로드 밸런싱을 수행합니다.
  • 자동 로드 밸런싱: Ribbon과 통합되어 있어 자동으로 로드 밸런싱을 수행합니다.

Ribbon

넷플릭스가 개발한 클라이언트 사이드 로드 밸런서로, MSA에서 서비스 인스턴스 간의 부하를 분산합니다.

  • 서버 리스트 제공자: Eureka로부터 서비스 인스턴스 리스트를 제공받아 로드 밸런싱에 사용합니다.
  • 로드 밸런싱 알고리즘: 라운드 로빈, 가중치 기반 등 다양한 로드 밸런싱 알고리즘을 지원합니다.
  • Failover: 요청 실패 시 다른 인스턴스로 자동 전환합니다.

설정

FeignClient와 Ribbon을 사용하려면 Spring Boot 애플리케이션에 의존성을 추가해야 합니다.

// build.gradle

dependencies {
    implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
    implementation 'org.springframework.cloud:spring-cloud-starter-openfeign'
}
// Spring Boot 애플리케이션

@SpringBootApplication
@EnableFeignClients // 이 부분을 추가해야 합니다.
public class MyServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(MyServiceApplication.class, args);
    }
}

이후 FeignClient 인터페이스를 작성하여 서비스 호출을 수행할 수 있습니다.

// 예시 코드

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

@FeignClient(name = "my-service")
public interface MyServiceClient {

    @GetMapping("/endpoint")
    String getResponse(@RequestParam(name = "param") String param);
}

Load Balancing 알고리즘

  • 라운드 로빈: 각 서버에 순차적으로 요청을 분배합니다. 간단하고 공평하게 트래픽을 분산할 수 있습니다.
  • 가중치 기반: 각 서버에 가중치를 부여하고, 가중치에 비례하여 요청을 분배합니다. 서버의 성능이나 네트워크 상태에 따라 가중치를 조절할 수 있습니다.
  • 최소 연결: 현재 연결된 클라이언트 수가 가장 적을 서버로 요청을 보냅니다.
  • 응답 시간 기반: 서버의 응답 시간을 기준으로 가장 빠른 서버로 요청을 보냅니다.

FeignClient와 Eureka 연동

Eureka와 FeignClient를 함께 사용하면 동적으로 서비스 인스턴스를 조회하여 로드 밸런싱을 수행할 수 있습니다.

우선 Eureka 서버를 띄우고 FeignClient를 설정한 서비스의 application.yml 파일을 아래와 같이 설정합니다.

# 예시 설정 파일
my-service:
  ribbon:
    eureka:
      enabled: true

FeignClient와 Ribbon 동작 원리

  • 서비스 이름: @FeignClient(name = "my-service") 어노테이션은 Eureka에 등록된 서비스 이름을 참조합니다.
  • 서비스 인스턴스 조회: Eureka 서버에서 my-service라는 이름으로 등록된 서비스 인스턴스 목록을 조회합니다.
  • 로드 밸런싱: 조회된 서비스 인스턴스 목록 중 하나를 선택하여 요청을 보내면 Ribbon을 통해 로드 밸런싱이 수행됩니다.
  • 요청 분배: 여러 서비스 인스턴스가 있을 경우, Round Robin 또는 다른 설정된 로드 밸런싱 알고리즘을 사용하여 요청을 분배합니다.

시나리오

  • Order 서비스 인스턴스: 1개
  • Product 서비스 인스턴스: 3개

여기서 Order 서비스는 Product 서비스를 호출하여 상품 정보를 가져옵니다. 이럴 경우 동작 과정은 아래와 같습니다.

  1. Order 서비스 실행: Order 서비스가 실행되면 Eureka 서버에서 Product 서비스 인스턴스 목록을 가져옵니다.
  2. Product 서비스 호출: Order 서비스에서 Product 서비스의 정보를 가져오기 위해 FeignClient를 사용하여 호출합니다.
  3. Ribbon을 통한 로드 밸런싱: FeignClient는 Ribbon을 통해 3개의 Product 인스턴스 중 하나를 선택하여 호출합니다. 이 과정에서 Round Robin 알고리즘을 사용하여 요청을 순차적으로 분배합니다.
  4. 응답 처리: 선택된 Product 인스턴스에서 응답을 받아 Order 서비스에 반환하고, 최종적으로 클라이언트에 응답을 전달합니다.