NGINX API Gateway – L7 Load Balancer 설정

API Gateway 의 핵심기능 중 하나는 API Backend로의 로드 밸런싱 기능이고, 여러 애플리케이션 인스턴스에 걸친 부하 분산은 리소스 사용량 최적화, 처리량 극대화, 지연 감소, 장애 조치 구성에 흔히 사용하는 기술입니다.

NGINX API Gateway를 매우 효율적인 L7(HTTP/HTTPS) Load Balancer로 사용하여 트래픽을 여러 API Backend 애플리케이션 서버로 분산하고, NGINX로 API 애플리케이션의 성능, 확장성, 가독성을 개선할 수 있습니다.

목차

1. 부하 분산 방법
2. 기본 부하 분산 구성
3. 최소 연결 부하 분산
4. 세션 지속성
5. 가중치가 부여된 부하 분산
6. API Backend 헬스 체크
7. 추가 설명

1. 부하 분산 방법

NGINX API Gateway에서는 다음과 같은 부하 분산 메커니즘(방법)을 지원합니다.

  • 라운드 로빈 — 애플리케이션 서버에 대한 요청을 순환 방식으로 분산합니다.
  • 최소 연결 — 다음 요청을 활성화된 연결이 가장 적은 서버에 할당합니다.
  • ip-해시 — 해시-함수를 사용하여 (클라이언트 IP 주소에 따라) 다음 요청에 대해 선택할 서버를 결정합니다.

2. 기본 부하 분산 구성

NGINX API Gateway를 사용한 부하 분산에서 가장 간단한 구성은 다음과 같을 수 있습니다.

http {
    upstream api_app1 {
        server srv1.example.com;
        server srv2.example.com;
        server srv3.example.com;
    }
 
    server {
        listen 80;
 
        location / {
            proxy_pass http://api_app1;
        }
    }
}

위의 예시에는 srv1-srv3에서 실행되는 동일한 애플리케이션의 인스턴스 3개가 있습니다. 부하 분산 방법을 명시적으로 구성하지 않는다면 순환 방식(round-robin)이 기본값이 됩니다. 모든 요청은 서버 그룹 api_app1에 프록시되고, NGINX는 HTTP 부하 분산을 적용하여 요청을 분배합니다.

NGINX에서 리버스 프록시를 구현하는 방법에는 HTTP, HTTPS, FastCGI, uwsgi, SCGI, 멤캐시트, gRPC에 대한 부하 분산이 포함됩니다.

HTTP 대신 HTTPS에 대한 부하 분산을 구성하려면 “https”를 프로토콜로 사용하세요.

FastCGI, uwsgi, SCGI, 멤캐시트 또는 gRPC에 대한 부하 분산을 설정하려면 각각 fastcgi_pass, uwsgi_pass, scgi_pass, memcached_pass, grpc_pass 명령을 사용하세요.

3. 최소 연결 부하 분산

다른 부하 분산 방법으로는 최소 연결이 있습니다. 최소 연결을 사용하면 일부 요청의 완료 시간이 더 오래 걸릴 때 애플리케이션 인스턴스의 부하를 더욱 균등하게 제어할 수 있습니다.

최소 연결 부하 분산을 사용할 경우, NGINX는 사용 중인 애플리케이션 서버에 과도한 요청으로 부담을 주지 않고 새로운 요청은 더욱 한산한 서버로 분배합니다.

NGINX의 최소 연결 부하 분산은 least_conn 명령을 서버 그룹 구성에서 사용할 때 활성화됩니다.

upstream api_app1 {
    least_conn;
    server srv1.example.com;
    server srv2.example.com;
    server srv3.example.com;
}

4. 세션 지속성

순환 또는 최소 연결 부하 분산에서는 차후의 각 클라이언트 요청을 다른 서버로 분배할 수 있습니다. 동일한 클라이언트가 항상 동일한 서버에 연결된다는 보장은 없습니다.

클라이언트를 특정 애플리케이션 서버에 연결해야 하는 경우, 즉 클라이언트 세션이 항상 특정 서버를 선택하도록 “연결”하거나 “유지”해야 하는 경우, ip-해시 부하 분산 메커니즘을 사용할 수 있습니다.

ip-해시에서 클라이언트의 IP 주소를 해싱 키로 사용하여 서버 그룹에서 어떤 서버를 클라이언트의 요청에 대해 선택해야 하는지 알 수 있습니다. 이 방법을 사용하면 동일한 클라이언트에서 보내는 요청이 항상 동일한 서버로 전송됩니다. 단, 이 서버를 사용할 수 없는 경우에는 예외입니다.

ip-해시 부하 분산을 구성하려면 ip_hash 명령을 서버(업스트림) 그룹 구성에 추가합니다.

upstream api_app1 {
    ip_hash;
    server srv1.example.com;
    server srv2.example.com;
    server srv3.example.com;
}

5. 가중치가 부여된 부하 분산

서버 가중치를 사용하여 NGINX 부하 분산 알고리즘의 영향력을 높일 수 있습니다.

위의 예시에서 서버 가중치는 구성되지 않습니다. 즉, 모든 지정된 서버가 특정 부하 분산 방법에 대해 똑같은 자격으로 취급됩니다.

특히, 순환 부하 분산은 서버에 대체로 균등하게 요청이 분산됩니다. 단, 요청이 충분해야 하고 균일하고 매우 빠르게 처리되어야 합니다.

서버에 weight 매개변수를 지정하면 가중치가 부하 분산 결정에 반영됩니다.

upstream api_app1 {
    server srv1.example.com weight=3;
    server srv2.example.com;
    server srv3.example.com;
}

이 구성을 사용하면 새로운 요청 5개를 보낼 때마다 다음과 같이 애플리케이션 인스턴스에 분산됩니다. 요청 3개는 srv1에 분배되고, 1개는 srv2로 분배되며, 1개는 srv3에 분됩니다.

NGINX의 최신 버전에서는 최소 연결과 ip-해시 부하 분산에도 이렇게 가중치를 사용할 수 있습니다.

6. API Backend 헬스체크

NGINX의 리버스 프록시 구현에는 밴드 내(또는 수동) 서버 상태 검사가 포함됩니다. 특정 서버의 응답이 오류와 함께 실패하면 NGINX가 이 서버를 실패로 표시하고, 한동안 이후의 인바운드 요청에 대한 서버로 선택하지 않습니다.

max_fails 명령은 fail_timeout 시간 내에 서버와의 통신이 연속적으로 실패하는 횟수를 설정합니다. 기본적으로 max_fails는 1로 설정됩니다. 0으로 설정되면 이 서버에 대해서는 상태 검사가 비활성화됩니다. fail_timeout 매개변수도 서버를 실패 상태로 표시하는 시간을 정의합니다. 서버 실패 후 fail_timeout 시간이 지나면 NGINX가 라이브 클라이언트의 요청으로 서버를 서서히 탐색하기 시작합니다. 탐색이 성공하면 서버가 활성 상태로 표시됩니다.

7. 추가 설명

또한, NGINX에는 API 서버 부하 분산을 제어하는 명령과 매개변수가 다양하게 제공됩니다(예: proxy_next_upstream, backup, down, keepalive).

마지막으로 서버 그룹의 애플리케이션 부하 분산, 애플리케이션 상태 검사, 활동 모니터링, Restful API를 통한 동적 재구성은 NGINX Plus 구독에서 제공합니다.