본문 바로가기
{시리즈}/Nginx

6. HTTP 부하 분산을 위한 설정 방법

by jay2022 2023. 11. 5.

1. Nginx에서 제공하는 HTTP 부하 분산 기능 (with LB)

Nginx는 여러 알고리즘과 느린 시작 및 세션 지속성과 같은 고급 기능을 사용하여 웹 또는 애플리케이션 서버 그룹에서 HTTP 트래픽 부하 분산을 지원한다.

*Nginx는 오픈소스이지만 유료버전인 Nginx plus가 따로 존재한다.
그리고 로드밸런시 기법중 일부는 유료버전인 Nginx plus에서만 지원한다.
때문에 본문에서는 오픈소스 Nginx에서 사용할 수 있는 기법만 정리한다.

2. 서버 그룹에 대한 HTTP 트래픽 프록시

Nginx의 HTTP 트래픽 로드 밸런싱(이하 L7)을 사용하려면
먼저 http 컨텍스트 하위 지시문으로 upstream 블록을 사용하여 그룹을 정의해야 한다.
( AWS ALB의 Target Group와 비슷하다고 생각하면 된다. )

주의

  • upstream블록의 하위 지시문에는 server지시문이 존재한다.
  • 해당 지시문은 http 블록의 자식인 server 블록과 다른 지시문이기 때문에 혼동되지 않게 주의해야 한다.

2. 1. upstream를 이해하기 위한 예시

http {
    # 2.1.1. upstream 블록을 사용하여 3개의 서버를 backend란 이름으로 그룹화 한다.
    upstream backend {
        server backend1.example.com; # server 지시문
        server backend2.example.com;
        server 192.0.0.1 backup;
    }

    # 2.1.2. 서버 그룹에 요청을 전달하기 위한 server 블록을 정의한다.
    server {
        location / {
            # proxy_pass가 호출하는 backend는 upstream으로 그룹화한 그룹명이다.
            proxy_pass http://backend; 
        }
    }
}

2.1.1. upstream 블록 그룹화

위의 upstream 블록으로 그룹화된 2개의 서버는 동일한 애플리케이션을 실행하는 인스턴스이다.
그리고 backup 지시문이 붙은 서버는 백업 서버이다.

2.1.2. 가상호스트에서 upstream로 트래픽 전달

server 블록의 자식인 location 블록에 의해 루트(/)로 들어오는 요청을 처리할 수 있다.
요청이 루트(/)로 들어오면 proxy_pass 지시문에 정의된 http://backend 로 전달된다.
여기서 backend는 upstream 블록에 정의된 그룹이다.
즉, 위 지시문은 모든 요청이 proxy_pass 지시문에 정의된 upstream 그룹으로 전달되게 하는 설정이다.

upstream 블록에 로드 밸런싱 알고리즘을 따로 정의하지 않는다면, 기본으로 라운드 로빈 알고리즘적용된다.
그리고 알고리즘에 의해 서버 중 하나로 요청을 전달한다.
(Nginx에서는 유료 방법 2개를 포함한 6개의 로드밸런싱 알고리즘을 지원한다.)

2. 로드 밸런싱 방법(알고리즘) 설명

2.1 라운드 로빈(Round Robin) 알고리즘

요청은 서버 가중치를 고려하여 서버 전체에 고르게 분산된다.
이 방법은 기본적으로 사용되며, 활성화하는 지시문이 없다.

upstream backend {
   # 아무것도 지정하지 않으면 라운드 로빈 알고리즘 활성화
   server backend1.example.com;
   server backend2.example.com;
}

2.2 최소 연결(Least Connections) 알고리즘

서버 가중치를 고려 하여 활성된 연결 수가 가장 적은 서버로 요청이 전송된다.

upstream backend {
    least_conn; # 최소 연결 알고리즘 사용
    server backend1.example.com;
    server backend2.example.com;
}

2.3 IP 해시(IP Hash) 알고리즘

요청이 전송되는 서버는 클라이언트 IP 주소에서 결정된다. 
이 경우 IPv4 주소의 처음 세 옥텟 또는 전체 IPv6 주소가 해시 값을 계산하는 데 사용된다. 
이 방법은 사용할 수 없는 경우를 제외하고 동일한 주소의 요청이 동일한 서버에 도달하도록 보장한다.

upstream backend {
    ip_hash; # IP 해시 알고리즘 사용
    server backend1.example.com;
    server backend2.example.com;
}

부하 분산에서 서버 중 하나를 일시적으로 제거해야 하는 경우 클라이언트 IP 주소의 현재 해싱을 유지하기 위해 down 매개 변수로 해당 서버를 표시할 수 있다.

down 매개 변수를 사용하는 경우 서버에서 처리할 요청은 자동으로 그룹의 다음 서버로 전송된다.

upstream backend {
    server backend1.example.com;
    server backend2.example.com;
        # down이 들어간 서버에는 트래픽이 가지않고 나머지로 트래픽이 넘어간다.
    server backend3.example.com down;
}

2.4 일반 해시(Generic Hash) 알고리즘

요청이 전송되는 서버는 텍스트 문자열, 변수 또는 조합이 될 수 있는 사용자 정의 키에서 결정된다.
예를 들어, 키는 다음 예에서와 같이 짝을 이루는 소스 IP 주소와 포트 또는 URI일 수 있다.

upstream backend {
    # 일반 해시 알고리즘은 $request_uri의 값을 이용하여 해시 값을 만든다.
    hash $request_uri consistent;
    server backend1.example.com;
    server backend2.example.com;
}

지시문에서 hash는 일관된 해시(ketama)로 로드 밸런싱을 활성화한다.
요청은 사용자 정의 해시 키 값을 기반으로 모든 업스트림 서버에 고르게 분산된다.

업스트림 서버가 업스트림 그룹에 추가되거나 제거되면 로드 균형 조정 캐시 서버 또는 상태를 누적하는 기타 응용 프로그램의 경우 캐시 누락을 최소화하는 몇 개의 키만 다시 매핑된다.

2.5 최소시간(Least Time) 알고리즘 - Nginx Plus 전용

각 요청에 대해 NGINX Plus는 평균 대기 시간이 가장 낮고 활성 연결 수가 가장 적은 서버를 선택합니다.
여기서 가장 낮은 평균 대기 시간은 지시문에 대한 다음 매개변수least_time 가 포함된 것을 기반으로 계산됩니다.

  • Nginx 공식문서

2.6 Random 알고리즘 - Nginx Plus 전용

그룹이 서버의 가중치를 고려하여 무작위로 선택된 서버에 요청을 전달하는 로드 밸런싱 방법을 사용하도록 지정합니다.

  • Nginx 공식문서

3. 서버 가중치

기본적으로 Nginx는 라운드 로빈 방식을 사용한다.
그리고 기중치에 따라 그룹안의 서버에게 요청을 배포한다. (가중치는 기본적으로 모두 1이다.)

weight 매개변수를 사용하여 upstream 블록의 하위 server에 가중치를 재정의 할 수 있다.

upstream backend {
    server backend1.example.com weight=5;
    server backend2.example.com;
    server 192.0.0.1 backup;
}

위의 예시를 보면 backend1.example.comweight를 통해 5의 가중치를 받는다.
다른 server의 가중치는 기본적으로 1이다.
결과적으로 backend1.example.com은 5의 가중치 만큼 더 많은 트래픽을 받게 된다.

4. 상태 확인 구성

Nginx는 HTTP 업스트림 서버를 지속적으로 테스트 한다.
그리고 테스트가 실패한 트래픽 전송하지 않게 자동한다.
이후 테스트가 다시 성공하면 다시 트래픽을 전송한다.
(AWS Target Group 헬스체크 같은 기능을 수행한다.)

상세 내용은 HTTP에 대한 상태 확인을 구성하는 방법에 대한 지침은 HTTP 상태 확인을 참조.

5. 여러 작업자 프로세스와 데이터 공유

참고

'{시리즈} > Nginx' 카테고리의 다른 글

7. Nginx 정리 마치며  (0) 2023.11.21
5. 리버스 프록시를 위한 설정 작성 방법  (0) 2023.11.05
4. 웹 서버를 위한 설정 방법  (0) 2023.11.05