블로그 | NGINX

NGINX 및 NGINX Plus를 사용한 로드 밸런싱, 2부

NGINX-F5-수평-검정-유형-RGB의 일부
오웬 개렛 썸네일
오웬 개렛
2014년 3월 17일 게시

NGINX 및 NGINX Plus를 사용한 부하 분산, 1부 에서는 간단한 HTTP 프록시를 설정하여 여러 웹 서버에 걸쳐 트래픽 부하를 분산했습니다. 이 문서에서는 NGINX Plus 에서 사용할 수 있는 추가 기능인 keepalives를 통한 성능 최적화, 상태 점검 , 세션 지속성 , 리디렉션 , 콘텐츠 다시 쓰기에 대해 살펴보겠습니다.

NGINX 및 NGINX Plus의 부하 분산 기능에 대한 자세한 내용은 NGINX Plus 관리자 가이드를 확인하세요.

편집기 – NGINX Plus 릴리스 5 이상은 TCP 기반 애플리케이션의 부하를 분산할 수도 있습니다. 릴리스 6 에서는 상태 점검, 동적 재구성, SSL 종료 등의 기능이 추가되어 TCP 부하 분산 기능이 크게 확장되었습니다. NGINX Plus 릴리스 7 이상에서는 TCP 로드 밸런서가 HTTP 로드 밸런서와 모든 기능이 동일합니다. UDP 부하 분산 에 대한 지원은 릴리스 9에서 도입되었습니다.

http 컨텍스트 대신 스트림 컨텍스트에서 TCP 및 UDP 부하 분산을 구성합니다 . 사용 가능한 지시어와 매개변수는 HTTP와 TCP/UDP의 본질적인 차이로 인해 다소 다릅니다. 자세한 내용은 HTTPTCP/UDP 업스트림 모듈에 대한 설명서를 참조하세요.

간단한 검토

검토해 보면, 이는 이전 문서에서 구축한 구성입니다.

server { listen 80;

location / {
proxy_pass http://backend;

# 'Host' 헤더를 클라이언트 요청의 값으로 다시 쓰거나
    # 또는 기본 서버 이름
    proxy_set_header Host $host;

# 또는 config에 값을 넣습니다.
# proxy_set_header Host www.example.com;
} 
}

upstream backend {
zone backend 64k; # NGINX Plus의 공유 메모리 사용
least_conn;

server webserver1 weight=1;
server webserver2 weight=4;
}

이 문서에서는 부하 분산의 효율성을 개선하는 NGINX 및 NGINX Plus를 구성하는 몇 가지 간단한 방법을 살펴보겠습니다.

HTTP Keepalives

NGINX 또는 NGINX Plus와 업스트림 서버 간에 HTTP keepalive를 활성화하면 성능이 향상되고(대기 시간이 단축됨) NGINX에서 임시 포트가 소진될 가능성이 줄어듭니다.

HTTP 프로토콜은 기본 TCP 연결을 사용하여 HTTP 요청을 전송하고 HTTP 응답을 수신합니다. HTTP keepalive 연결은 이러한 TCP 연결을 재사용할 수 있게 하므로 각 요청에 대해 연결을 만들고 파괴하는 오버헤드를 피할 수 있습니다.

티씨피카

NGINX는 전체 프록시이며 클라이언트(프런트엔드 keepalive 연결)로부터의 연결과 서버(업스트림 keepalive 연결)로의 연결을 독립적으로 관리합니다.

NGINX는 Keepalive 연결의 "캐시"를 유지합니다. 이는 업스트림 서버에 대한 유휴 Keepalive 연결 세트이며, 업스트림에 요청을 전달해야 할 때 새 TCP 연결을 만드는 대신 캐시에서 이미 설정된 Keepalive 연결을 사용합니다. 이를 통해 NGINX와 업스트림 서버 간 트랜잭션에 대한 지연 시간이 줄어들고, 임시 포트가 사용되는 속도가 느려져 NGINX가 대량의 트래픽을 흡수하고 부하를 분산할 수 있습니다. 트래픽이 급증하면 캐시를 비울 수 있으며, 이 경우 NGINX는 업스트림 서버에 새로운 HTTP 연결을 설정합니다.

다른 부하 분산 도구에서는 이 기술을 멀티플렉싱 , 연결 풀링 , 연결 재사용 또는 OneConnect 라고도 합니다.

구성에 proxy_http_version , proxy_set_headerkeepalive 지침을 포함하여 keepalive 연결 캐시를 구성합니다.

서버 { listen 80; location / { proxy_pass http://backend; proxy_http_version 1.1 ; proxy_set_header Connection "" ; } } 업스트림 백엔드 { 서버 웹서버1; 서버 웹서버2; # 업스트림 서버 그룹에 최대 20개의 유휴 연결을 유지합니다 . keepalive 20 ; }

 

건강 검진

상태 점검을 활성화하면 부하 분산 서비스의 안정성이 향상되고, 최종 사용자에게 오류 메시지가 표시될 가능성이 줄어들며, 일반적인 유지 관리 작업도 원활하게 수행할 수 있습니다.

NGINX Plus의 상태 점검 기능을 사용하면 업스트림 서버의 장애를 감지할 수 있습니다. NGINX Plus는 "합성 트랜잭션"을 사용하여 각 서버를 조사하고 health_check 지시문에서 구성한 매개변수(그리고 match 매개변수를 포함하는 경우 연관된 match 구성 블록)에 대해 응답을 확인합니다.

server { listen 80; location / { proxy_pass http://backend; health_check interval=2s fails=1 passed=5 uri=/test.php match=statusok ; # health check는 다른 프록시 설정을 상속합니다 proxy_set_header Host www.foo.com; } } match statusok { # /test.php health check status 200 에 사용됩니다 ; header Content-Type = text/html ; body ~ "Server[0-9]+ is alive" ; }

상태 검사는 부모 위치 블록에서 일부 매개변수를 상속받습니다. 구성에서 런타임 변수를 사용하면 문제가 발생할 수 있습니다. 예를 들어, 다음 구성은 클라이언트 요청에서 Host 헤더의 값을 추출하기 때문에 실제 HTTP 트래픽에 적합합니다. 아마도 상태 검사에 사용되는 합성 트랜잭션에서는 작동하지 않을 것입니다. 왜냐하면 호스트 헤더가 설정되지 않았기 때문입니다. 즉, 합성 트랜잭션에서는 호스트 헤더가 사용되지 않습니다.

location / { proxy_pass http://backend;

# 이 상태 검사는 작동하지 않을 수 있습니다...
health_check interval=2s fails=1 passed=5 uri=/test.php match=statusok;

# 요청에서 'Host' 헤더 추출
proxy_set_header Host $host;
}

좋은 해결책 중 하나는 상태 확인 트랜잭션에서 사용되는 모든 매개변수를 정적으로 정의하는 더미 위치 블록을 만드는 것입니다.

location /internal-health-check1 { internal; # 외부 요청이 이 location 블록과 일치하지 않도록 합니다.

proxy_pass http://backend;

health_check interval=2s fails=1 passed=5 uri=/test.php match=statusok;

# 요청 매개변수를 명시적으로 설정합니다. 런타임 변수는 사용하지 마세요.
proxy_set_header Host www.example.com;
}

자세한 내용은 NGINX Plus 관리자 가이드를 확인하세요.

세션 지속성

세션 지속성을 사용하면 클러스터에 배포할 수 없는 애플리케이션도 부하를 분산하고 안정적으로 확장할 수 있습니다. 세션 상태를 저장하고 복제하는 애플리케이션은 더 효율적으로 작동하고 최종 사용자 성능이 향상됩니다.

특정 애플리케이션은 때때로 업스트림 서버에 상태 정보를 저장하기도 합니다. 예를 들어, 사용자가 가상 쇼핑 카트에 품목을 넣거나 업로드된 이미지를 편집할 때입니다. 이런 경우에는 해당 사용자의 모든 후속 요청을 동일한 서버로 보내는 것이 좋습니다.

세션 지속성은 요청을 어디로 라우팅해야 하는지 지정하는 반면, 로드 밸런싱은 NGINX가 최적의 업스트림 서버를 선택할 수 있는 자유를 제공합니다. 두 프로세스는 NGINX Plus의 세션 지속성 기능을 사용하여 공존할 수 있습니다.

   요청이 세션 지속성 규칙과 일치하는 경우
그런 다음 대상 업스트림 서버를 사용합니다.
그렇지 않으면 부하 분산 알고리즘을 적용하여 업스트림 서버를 선택합니다.

대상 서버를 사용할 수 없어 세션 지속성 결정이 실패하면 NGINX Plus는 부하 분산 결정을 내립니다.

가장 간단한 세션 지속성 방법은 " 스티키 쿠키 " 접근 방식으로, NGINX Plus는 첫 번째 응답에 스티키 업스트림 서버를 식별하는 쿠키를 삽입합니다.

스티키 쿠키 srv_id 만료=1h 도메인=.example.com 경로=/;

대체 " sticky route " 방식에서 NGINX는 JSESSIONID 쿠키와 같은 요청 매개변수를 기반으로 업스트림 서버를 선택합니다.

업스트림 백엔드 { server backend1.example.com route=a ; server backend2.example.com route=b ; # 첫 번째 비어 있지 않은 변수를 선택합니다. 'a' 또는 'b'를 포함해야 합니다. 스티키 경로 $route_cookie $route_uri ; }

자세한 내용은 NGINX Plus 관리자 가이드를 확인하세요.

HTTP 리디렉션 다시 쓰기

일부 리디렉션이 끊어지는 경우, 특히 프록시에서 실제 업스트림 서버로 리디렉션되는 경우 HTTP 리디렉션을 다시 작성하세요.

업스트림 서버로 프록시하는 경우 서버는 로컬 주소에 애플리케이션을 게시하지만 사용자는 다른 주소, 즉 프록시 주소를 통해 애플리케이션에 액세스합니다. 이러한 주소는 일반적으로 도메인 이름으로 확인되며, 서버와 프록시에 서로 다른 도메인이 있는 경우 문제가 발생할 수 있습니다.

예를 들어, 테스트 환경에서는 프록시를 직접(IP 주소로) 또는 localhost 로 지정할 수 있습니다. 그러나 업스트림 서버는 실제 도메인 이름(예: www.nginx.com )을 수신할 수도 있습니다. 업스트림 서버가 리디렉션 메시지를 발행하면( 3xx 상태 및 위치 헤더를 사용하거나 새로 고침 헤더를 사용하는 경우) 해당 메시지에 서버의 실제 도메인이 포함될 수 있습니다.

NGINX는 이 문제의 가장 일반적인 인스턴스를 가로채서 수정하려고 시도합니다. 특정한 재작성을 강제하기 위한 전체 제어가 필요한 경우 다음과 같이 proxy_redirect 지시문을 사용하세요.

프록시_리디렉션 http://staging.mysite.com/ http://$host/;

HTTP 응답 다시 쓰기

때로는 HTTP 응답의 내용을 다시 작성해야 합니다. 아마도 위의 예처럼 응답에는 프록시가 아닌 다른 서버를 참조하는 절대 링크가 포함되어 있을 수 있습니다.

sub_filter 지시어를 사용하여 적용할 다시 쓰기를 정의할 수 있습니다.

하위 필터 /블로그/ /블로그-스테이징/;
하위 필터 한 번 꺼짐;

매우 흔한 함정 중 하나는 HTTP 압축 사용입니다. 클라이언트가 압축 데이터를 허용할 수 있다는 신호를 보내고 서버가 응답을 압축하는 경우, NGINX는 응답을 검사하거나 수정할 수 없습니다. 가장 간단한 방법은 클라이언트 요청에서 Accept-Encoding 헤더를 빈 문자열( "" )로 설정하여 제거하는 것입니다.

proxy_set_header 수락 인코딩 "";

완전한 예

이 문서에서 논의된 모든 기술을 사용하는 부하 분산 구성에 대한 템플릿은 다음과 같습니다. NGINX Plus에서 사용 가능한 고급 기능은 주황색으로 강조 표시됩니다.

[편집기 - 다음 구성은 라이브 활동 모니터링 및 업스트림 그룹의 동적 구성을 위해 NGINX Plus API를 사용하도록 업데이트되었으며 원래 사용되었던 별도 모듈을 대체했습니다.]

서버 { listen 80; location / { proxy_pass http://backend; proxy_http_version 1.1; proxy_set_header Connection ""; proxy_set_header Accept-Encoding ""; proxy_redirect http://staging.example.com/ http://$host/; # 클라이언트 요청의 값으로 Host 헤더를 다시 작성 proxy_set_header Host $host; # staging.example.com에 대한 모든 참조를 인라인으로 바꿉니다 sub_filter http://staging.example.com/ /; sub_filter_once off; } location /internal-health-check1 { internal; # 외부 요청이 이 location block과 일치하지 않도록 합니다 proxy_pass http://backend; health_check interval=2s fails=1 passed=5 uri=/test.php match=statusok ; # 요청 매개변수를 명시적으로 설정합니다. 런타임 변수는 사용하지 마세요 proxy_set_header Host www.example.com; } upstream backend { zone backend 64k ; # NGINX Plus의 공유 메모리를 사용합니다 least_conn; keepalive 20; # 이 업스트림 그룹에 세션 지속성을 적용합니다 sticky 쿠키 srv_id expires=1h domain=.example.com path=/servlet ; server webserver1 weight=1; server webserver2 weight=4; } match statusok { # /test.php 상태 확인에 사용됩니다 status 200 ; header Content-Type = text/html ; body ~ "Server[0-9]+ is alive" ; } server { listen 8080; root /usr/share/nginx/html; location = /api { api write=on ; # 라이브 활동 모니터링 및 # 업스트림 그룹의 동적 구성 allow 127.0.0.1; # 로컬호스트에서의 액세스 허용 deny all; # 그 밖의 모든 곳에서의 액세스 거부 } }

NGINX Plus의 모든 뛰어난 로드 밸런싱 기능을 직접 사용해 보세요. 오늘 무료 30일 체험판을 시작하거나 저희에게 연락하여 사용 사례에 대해 논의해 보세요 .


"이 블로그 게시물에는 더 이상 사용할 수 없거나 더 이상 지원되지 않는 제품이 참조될 수 있습니다. 사용 가능한 F5 NGINX 제품과 솔루션에 대한 최신 정보를 보려면 NGINX 제품군을 살펴보세요. NGINX는 이제 F5의 일부가 되었습니다. 이전의 모든 NGINX.com 링크는 F5.com의 유사한 NGINX 콘텐츠로 리디렉션됩니다."