티스토리 뷰

로드밸런서에 대한 사전지식 쌓기

 

내가 만든 서비스 사용자가 두명인 경우

서버는 여유롭게 사용자가 원하는 결과를 응답해줄 수 있다

 

하지만 내가 만든 서비스가 대박나서 동시사용자가 수천만명이 되었을 경우

서버는 터져버리게된다....!!!!!

 

이러한 문제를 해결하기 위한 두가지 방식

  • Scale - up : 서버가 더 빠르게 동작하기 위해 하드웨어(cpu 등)의 성능을 올리는 방법
  • Scale - out : 하나의 서버가 아닌 여러대의 서버를 만들어 일을 나눠 하는 방법 

 

로드밸런싱이란?

하나의 인터넷 서비스가 발생하는 트래픽이 많을 때 여러 대의 서버가 분산처리하여 로드율 증가, 부하량, 속도저하 등을 고려하여 적절히 분산처리하여 해결해주는 서비스 , 즉 스케일 아웃의 방식을 사용한 트래픽 분산처리 서비스

 

L4 로드 밸런싱과 L7 로드 밸런싱

네트워크 통신 시스템은 OSI 7 Layer로 나뉜다. 상위 계층에서 사용되는 장비는 하위 계층의 장비가 가지고 있는 기능을 모두 가지고 있으며 상위계층으로 갈수록 더 정교한 로드밸런싱이 가능하다

 

L4 로드밸런서 

  • 네트워크 계층(IP)이나 트렌스포트 계층(TCP,UDP)의 정보를 바탕으로 로드를 분산한다. IP 주소나 포트번호에 따라 트래픽을 나누는 것이 가능하다
  • hardware 등이 있음

L7 로드밸런서

  • 애플리케이션(HTTP 등)에서 로드를 분산하기 때문에 Http 헤더, 쿠키 등과 같은 사용자의 요청을 기준으로 특정 서버에 트래픽을 분산하는 것이 가능하다. 예를 들어 URL에 따라 부하를 분산시키거나 HTTP 헤더의 쿠키값에 따라 부하를 분산하는 등 클라이언트의 요청을 보다 세분화해 서버에 전달 할 수 있다
  • Nginx, HAProxy 등이 있음

Server Side LoadBalancer

  • 일반적인 L4 Switch 기반의 Load Balancing
  • Client는 L4의 주소만 알고 있고 L4 switch는 서버의 목록을 알고 있다
  • 하드웨어 서버 사이드 로드 밸런서의 단점
    • H/W 가 필요하다 (비용 큼)
    • 서버 목록의 추가를 위해서는 설정이 필요하다(자동화 어려움)
    • 로드밸런싱 설정이 한정적이다 

Cleint LoadBalancer - Ribbon

  • Client에 탑재퇴는 소프트웨어 모듈이다
  • API를 호출하는 Client 서버가 서버 목록을 가지고 있고 해당 목록에서 로드밸런싱을 수행한다
  • Ribbon의 장점
    • H/W가 필요없이 S/W로만 로드밸런싱이 가능하다
    • 서버 목록의 동적 변경이 자유롭다
    • 로드밸런싱 설정을 마음대로 구성할 수 있다

대부분의 로드밸런서는 서버 사이드 로드 밸런서를 사용한다. 하지만 이번 시간에는 서버 사이드 로드 밸런서의 단점을 보완한 클라이언트 사이드 로드밸런서의 한 종류인 Ribbon을 사용하여 실습을 하도록하겠다 (Ribbon 또한 Spring Cloud에서 제공하는 Nexflix 오픈소스 라이브러리이다)


실습하기

 

1. 라이브러리 의존성 추가

    compile('org.springframework.cloud:spring-cloud-starter-netflix-ribbon')  // 2. To use ribbon

 

2. 메인 클래스의 RestTemplate 생성 부분에  @LoadBalanced 추가

@SpringBootApplication
@EnableCircuitBreaker
public class DisplayApplication {

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

    public static void main(String[] args) {
        SpringApplication.run(DisplayApplication.class);
    }

}

 

3. RestTemplate의 URL 변경

@Service
public class ProductRemoteServiceImpl implements ProductRemoteService {

    private static final String url = "http://product/products/";
    private final RestTemplate restTemplate;

    public ProductRemoteServiceImpl(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }

    @Override
    @HystrixCommand(commandKey = "productInfo", fallbackMethod = "getProductInfoFallback")
    public String getProductInfo(String productId) {
        return this.restTemplate.getForObject(url + productId, String.class);
    }

    public String getProductInfoFallback(String productId, Throwable t) {
        System.out.println("t = " + t);
        return "[ this product is sold out ]";
    }
}
  • url을 "http:localhost:8082/products"에서 "http:product/products"로 변경

4. application.yml에서 설정추가

product:
  ribbon:
    listOfServers: localhost:8082

 

디버깅을 해보면 @LoadBalancer가 Interceptor를 기반으로 로드밸런싱을 하고있는 것을 확인할 수 있다

*) Interceptor란 ? 

  • 컨트롤러 실행 전과 실행된 후에 공통 처리를 할 수 있도록 도와주는 것
  • Dispatcher servlet에서 Handler(Controller)로 요청을 보낼 때, Handler에서 Dispathcer servlet으로 응답을 보낼 때 동작

Retries 기능 추가해보기

 

1. 라이브러리 의존성 추가

complie('org.springframework.retry:spring-retry:1.2.2REALEASE')

 

2. application.yml 설정 변경

product:
  ribbon:
    listOfServers: localhost:8082, localhost:7777
    MaxAutoRetries: 0
    MaxAutoRetriesNextServer: 1

8082, 7777 두개의 서버에 대하여 로드밸런싱을 실행한다

즉 같은 서비스를 구동중인 8082와 7777 두대의 서버에 대하여 client 서버가 로드밸런싱을 실행하게 된다

 

디버깅을 해보면 Interceptor의 이름이 변경되어 잘 실행되고 있는 것을 확인할 수 있다

주의사항

Hystrix가 Ribbon을 감싸고 있어서 Hystrix Timeout이 발생하면 Riddon이 Retry를 하지 못하고 에러를 반환할 수 있다

Retry를 끄거나 재시도 횟수를 0으로 하여도 해당 서버로의 호출이 항상 동일한 비율로 실패하지않는다(리본 룰을 설정하는 것이 좋다)

 


마무리

 

Ribbon을 통해 Client Load Balancing이 가능하다

Ribbon은 다양한 설정이 가능하다 (서버 선택, 실패시 Skip 시간, Ping 체크) - 넷플릭스 제공 라이브러리 사용해야 함

Ribbon에는 Retry 기능이 내장되어있다 - Retry 라이브러리 추가해야 함

Eureka와 함께 사용될 때 강력하다 (다음 정리할 부분)

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/10   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
글 보관함