클라이언트 사이드 로드 밸런싱 FeignClient와 Ribbon 이해하기

2024. 8. 17. 16:22·Spring
728x90
반응형

 

 

로드 밸런싱

 

로드 밸런싱은 네트워크 트래픽을 여러 서버로 분산시켜 서버의 부하를 줄이고, 시스템의 성능과 가용성을 높이는 기술.

서버 간 트래픽을 고르게 분배하여 특정 서버에 부하가 집중되는 것을 방지.

종류 : 클라이언트 사이드 로드 밸런싱, 서버 사이드 로드 밸런싱

 

클라이언트 사이드 로드 밸런싱

 

클라이언트 사이드 로드 밸런싱은 클라이언트가 직접 여러 서버 중 하나를 선택하여 요청을 보내는 방식.

클라이언트는 서버의 목록을 가지고 있으며, 이를 바탕으로 로드 밸런싱을 수행.

 


 

FeignClient

 

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

Eureka와 같은 서비스 디스커버리와 연동하여 동적으로 서비스 인스턴스를 조회하고 로드 밸런싱을 수행.

주요 특징

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

 


 

Ribbon

 

넷플릭스가 개발한 클라이언트 사이드 로드 밸런서로, 마이크로서비스 아키텍처에서 서비스 인스턴스 간의 부하를 분산.

다양한 로드 밸런싱 알고리즘을 지원하며, Eureka와 같은 서비스 디스커버리와 연동하여 사용.

주요 특징

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

 

FeignClient와 Ribbon 기본 설정

 

SpringBoot 어플리케이션에 의존성 추가하기

build.gradle

dependencies {
    implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
    implementation 'org.springframework.cloud:spring-cloud-starter-openfeign'
}

 

SpringBoot 애플리케이션 설정

@SpringBootApplication
@EnableFeignClients
public class MyServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(MyServiceApplication.class, args);
    }
}

 

어노테이션으로 @EnableFeignClients 추가

 

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);
}

 

@FeignClient 선언 ( ) 안에는 호출하고자 하는 호스트 이름 작성

인터페이스 안에는 호출하고자 하는 endpoint 작성

 

FeignClient와 Ribbon의 동작 원리

 

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

 


 

실습

 

 

유레카 서버에 주문 인스턴스와 같은 기능의 포트만 다른 상품 인스턴스 3개 연결하기.

상품을 요청하면 응답하는 인스턴스의 포트번호를 노출해 라운드로빈 방법으로 로드 밸런싱이 되는지 확인한다.

 

👉🏻 https://start.spring.io/ 에서 order와 product 프로젝트 생성

 

이전 글에서 만들었던 Eureka 서버를 재사용할 것이기 때문에 같은 폴더로 옮겨주고 firstClient와 secondClient는 삭제.

2024.08.17 - [Spring/MSA] - 서비스 디스커버리 Eureka 이해하기 및 실습

 

서비스 디스커버리 Eureka 이해하기 및 실습

서비스 디스커버리 서비스 디스커버리 : 마이크로서비스 아키텍처에서 각 서비스의 위치를 동적으로 관리하고 찾아주는 기능.각 서비스는 등록 서버에 자신의 위치를 등록하고, 다른 서비스는

tildacoderecorder.tistory.com

 

 

ProductClient 설정

 

ProductController.java 

@RestController
public class ProductController {
    @Value("${server.port}")
    private String port;

    @GetMapping("/product/{id}")
    public String getProduct(@PathVariable("id") String id) {
        return "Product : " + id + " info!! From port : " + port;
    }
}

 

@value 어노테이션을 사용하면 application.properties 또는 application.yml에 있는 값을 가져올 수 있다.

 

application.yml

spring:
  application:
    name: product-service
server:
  port: 19092
eureka:
  client:
    service-url:
      defaultZone: http://localhost:19090/eureka/

 

기존에 있던 application.properties를 삭제하고 yml 파일을 만든다. (둘 다 동일한 설정 파일이기에 yml파일로 만드는 법 연습)

 

 

동일한 인스턴스지만 포트번호만 다른 product을 3개 만들기 위해 다음과 같이 복제해준다. 구분을 위해 이름 뒤에 포트번호 추가.

 

 

복제된 product의 포트 번호를 바꾸기 위해 옵션의 VM 추가하기로 "-Dserver.port=포트번호" 다음과 같이 추가한다.

 

이제 유레카 서버를 실행시키고 Product 또한 실행시킨 뒤 위에서 설정한 엔드포인트로 접속하게되면 위와 같이 뜨는 것을 확인 할 수 있다.

 

OrderClient 설정

 

동작 원리 : OrderController로 요청이 들어오면 Eureka 서버에 등록된 FeignClient인 product을 찾아 반환. product을 찾는 방법은 라운드로빈 사용.

 

ProductClient.java

@FeignClient(name="product-service")
public interface ProductClient {
    @GetMapping("/product/{id}")
    String getProduct(@PathVariable("id") String id);
}

 

FeignClient인 product를 받아오기 위해 ProductClient 인터페이스를 만들어준다. Product들은 "product-service"라는 이름으로 등록이 되어 있기 때문에 위와 같은 어노테이션으로 찾아야 할 이름을 알려준다.

 

OrderController.java

@RestController
@RequiredArgsConstructor
public class OrderController {

    private final OrderService orderService;

    @GetMapping("/order/{orderId}")
    public String getOrder(@PathVariable("orderId") String orderId) {
        return orderService.getOrder(orderId);
    }


}

 

OrderController로 들어온 요청은 orderId를 받아 OrderService로 넘겨주게된다.

 

OrderService.java

@Service
@RequiredArgsConstructor
public class OrderService {

    private final ProductClient productClient;

    public String getProductInfo(String productId) {
        return productClient.getProduct(productId);
    }

    public String getOrder(String orderId) {
        if(orderId.equals("1")) {
            String productId = "2";
            String productInfo = getProductInfo(productId);
            return "Your order is " + orderId + " and " + productInfo;
        }else {
            return "Not Exist";
        }
    }

}

 

OrderService에서는 받아온 orderId를 이용해 Product 정보를 가져와 반환한다. 위에서 사용한 if/else문은 단순한 유효성 검사이다.

 

productId를 임의로 "2"라고 주었을 때 product의 getProduct를 호출해서 정보를 받아오면 모든 어플리케이션을 실행했을 때 다음과 같은 창이 뜬다.

 

 

같은 엔드포인트에 계속 접근하면 포트번호만 바뀐 채 같은 결과가 뜨는 것을 확인 할 수 있는데 이것으로 인해 라운드로빈 알고리즘이 쓰였음을 확인 할 수 있다.

 

728x90
반응형
저작자표시 비영리 변경금지

'Spring' 카테고리의 다른 글

Spring 공통 모듈 & 공통 DTO 사용하기  (0) 2024.10.01
서킷 브레이커 Resilience4j와 API 게이트웨이 이해하기  (1) 2024.08.17
서비스 디스커버리 Eureka 서버 이해하기 및 실습  (0) 2024.08.17
MSA와 Spring Cloud 이해하기  (0) 2024.08.17
Spring의 RestTemplate 이해하기  (0) 2024.08.17
'Spring' 카테고리의 다른 글
  • Spring 공통 모듈 & 공통 DTO 사용하기
  • 서킷 브레이커 Resilience4j와 API 게이트웨이 이해하기
  • 서비스 디스커버리 Eureka 서버 이해하기 및 실습
  • MSA와 Spring Cloud 이해하기
waVwe
waVwe
    반응형
  • waVwe
    waVwe 개발 블로그
    waVwe
  • 전체
    오늘
    어제
    • ALL (184)
      • Python (1)
      • Spring (15)
      • DevOps (10)
      • Git (6)
      • JAVA (4)
      • C (22)
      • 코테 문제 풀이 (124)
        • 프로그래머스 (43)
        • 백준 (2)
        • 정올 (64)
        • SW Expert Academy (1)
        • 온코더 oncoder (14)
  • 블로그 메뉴

    • 홈
    • 방명록
  • 링크

    • 🐙 Github
  • 공지사항

  • 인기 글

  • 태그

    CI/CD
    MSA
    C
    코테
    스파르타코딩
    연결리스트
    도커
    devops
    형변환
    이진트리
    스파르타코딩클럽
    프로그래머스
    내일배움캠프
    스프링부트
    알고리즘
    자료구조
    docker
    정올
    Til
    스프링
    자바
    온코더
    java
    while문
    C언어
    springboot
    progate
    아파치카프카
    깃헙
    깃
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
waVwe
클라이언트 사이드 로드 밸런싱 FeignClient와 Ribbon 이해하기
상단으로

티스토리툴바