NGINX Plus 및 NGINX의 임시 포트 고갈 해결
NGINX 및 NGINX Plus 는 매우 강력한 HTTP, TCP 및 UDP 로드 밸런서입니다. 대량의 요청을 프록싱하고 많은 수의 동시 연결을 유지하는 데 매우 효율적입니다. 그러나 이러한 특성으로 인해 NGINX 및 NGINX Plus는 특히 일시적인 포트 고갈(OS에서 새 로컬 소켓을 설정하기 위해 할당된 포트 번호가 부족하기 때문에 새 연결을 생성할 수 없는 상태)의 영향을 받습니다. (임시 포트 고갈은 두 제품 모두에 적용되지만 간결함을 위해 이 포스트의 나머지 부분에서는 NGINX Plus만 언급하겠습니다.)
이 포스트에서는 TCP 연결의 구성 요소와 연결이 설정되기 전에 해당 내용이 결정되는 방법을 검토합니다. 그런 다음 NGINX Plus가 임시 포트 고갈의 영향을 받는 시기를 확인하는 방법을 보여줍니다. 마지막으로 Linux 커널 조정과 NGINX Plus 지시문을 모두 사용하여 이러한 제한 사항을 해결하기 위한 전략에 대해 논의합니다.
목차
1. 네트워크 소켓에 대한 간략한 개요
2. 임시 포트 고갈 인식
3. 커널을 조정하여 사용 가능한 임시 포트 수 늘리기
4. NGINX Plus에서 Keepalive 연결 활성화
5. 정의된 로컬 IP 주소 목록에 연결을 동적으로 바인딩
6. 결론
1. 네트워크 소켓에 대한 간략한 개요
TCP를 통해 연결이 설정되면 로컬 및 원격 호스트 모두에 소켓이 생성됩니다. 그런 다음 이러한 소켓을 연결하여 원격 IP 주소 및 포트와 함께 로컬 IP 주소 및 포트로 구성된 고유한 4-tuple로 설명되는 소켓 쌍을 만듭니다.
원격(Remote) IP 주소와 포트는 연결의 서버 측에 속하며 연결을 시작하기 전에 클라이언트가 결정해야 합니다. 대부분의 경우 클라이언트는 연결에 사용할 로컬 IP 주소를 자동으로 선택하지만 연결을 설정하는 소프트웨어에서 선택하는 경우도 있습니다. 마지막으로 로컬 포트는 운영체제에서 사용할 수 있는 정의된 범위에서 임의로 선택됩니다. 포트는 연결 기간 동안에만 클라이언트와 연결되므로 임시 포트라고 합니다. 연결이 종료되면 임시 포트를 재사용할 수 있습니다.
2. 임시 포트 고갈 인식
소개에서 언급된 대로, NGINX Plus는 본성상 일시적인 포트 고갈과 그로 인한 문제에 영향을 받을 수 있습니다. NGINX Plus가 Upstream 서버로 요청을 프록시하는 경우, 그 소켓 생성 프로세스에서 클라이언트 역할을 하며, 기본 동작은 해당 요청을 위한 소켓을 자동으로 로컬 IP 주소와 호스트에서 사용 가능한 일시적인 포트에 바인딩하는 것입니다. 연결 속도가 높아 기존 오픈된 소켓이 닫히기 전에 대기 상태로 이동하는 소켓이 빠르게 발생한다면, 사용 가능한 포트가 고갈되어 새로운 소켓을 생성할 수 없게 됩니다. 이는 운영체제와 NGINX Plus에서 모두 오류가 발생하게 됩니다. 아래는 NGINX Plus Error 로그에 나타나는 결과 예시입니다.
2016/03/18 09:08:37 [crit] 1888#1888: *13 connect() to 10.2.2.77:8081 failed (99: Cannot assign requested address) while connecting to upstream, client: 10.2.2.42, server: , request: "GET / HTTP/1.1", upstream: "http://10.2.2.77:8081/", host: "10.2.2.77"
또한 포트 고갈은 Upstream 서버가 아닌 NGINX Plus에서 발생하는 500개의 Error를 급증시킵니다. 다음은 NGINX Plus Access Log의 샘플 항목입니다.
10.2.2.42 - - [18/Mar/2016:09:14:20 -0700] "GET / HTTP/1.1" 500 192 "-" "curl/7.35.0"
NGINX Plus 서버에서 TIME-WAIT 상태의 소켓 수를 확인하려면 Linux 셸에서 다음 ss 명령을 실행합니다. 이 예에서는 TIME-WAIT 상태로 열려 있는 143개의 소켓이 있음을 보여줍니다. 이 예에서는 wc 명령을 사용하여 명령 출력의 행 수를 나열하여 개수를 얻습니다.
# ss -a | grep TIME-WAIT | wc -l
143
3. 커널을 조정하여 사용 가능한 임시 포트 수 늘리기
임시 포트 소모를 줄이는 한 가지 방법은 Linux 커널 net.ipv4.ip_local_port_range
설정을 사용하는 것입니다. 기본 범위는 가장 일반적으로 32768에서 61000 사이입니다.
임시 포트가 부족한 경우 범위를 기본값에서 1024~65000으로 변경하면 사용 가능한 임시 포트 수를 두 배로 늘릴 수 있습니다.
4. NGINX Plus 에서 Keepalive 연결 활성화
임시 포트 고갈을 줄이는 또 다른 방법은 NGINX Plus와 Upstream 서버 간의 keepalive 연결을 활성화하는 것입니다. 가장 간단한 HTTP 구현에서 클라이언트는 새 연결을 열고 요청을 작성하고 응답을 읽은 다음 연결을 닫아 관련 리소스를 해제합니다.

keepalive 연결은 클라이언트가 응답을 읽은 후 열린 상태로 유지되므로 후속 요청에 다시 사용할 수 있습니다.

keepalive 지시문을 사용하여 NGINX Plus에서 Upstream 서버로의 keepalive 연결을 활성화하여 각 Worker 프로세스의 캐시에 보존되는 Upstream 서버에 대한 유휴 keepalive 연결의 최대 수를 정의합니다. 이 숫자를 초과하면 최근에 가장 적게 사용된 연결이 닫힙니다. keepalive가 없으면 오버헤드가 추가되고 연결과 임시 포트 모두 비효율적입니다.
다음 샘플 구성은 백엔드라는 Upstream 블록에 정의된 서버에 대해 최소 128개의 keepalive 연결을 유지하도록 NGINX Plus에 지시합니다.
upstream backend {
server 10.0.0.100:1234;
server 10.0.0.101:1234;
keepalive 128;
}
Upstream 서버에 대한 keepalive 연결을 활성화할 때 proxy_http_version 지시문을 사용하여 NGINX Plus에 HTTP 버전 1.1을 사용하도록 지시하고 proxy_set_header 지시문을 사용하여 Connection이라는 헤더를 제거해야 합니다. 두 지시문 모두 http, server 또는 location 구성 블록에 배치할 수 있습니다.
5. 정의된 로컬 IP 주소 목록에 연결을 동적으로 바인딩
커널을 최적화하고 keepalive 연결을 활성화하면 임시 포트 가용성 및 사용을 훨씬 더 많이 제어할 수 있지만 이러한 변경 사항으로는 임시 포트의 과도한 사용을 방지하기에 충분하지 않은 특정 상황이 있습니다. 이 경우 고정 로컬 IP 주소에 대한 연결 비율을 바인딩할 수 있는 몇 가지 NGINX Plus 지시문 및 매개 변수를 사용할 수 있습니다. 이렇게 하면 사용 가능한 임시 포트 수에 구성에 정의된 IP 주소 수를 효과적으로 곱할 수 있습니다. 이를 위해 proxy_bind
및 split_clients
지시문을 사용합니다.
아래의 구성 예에서 location 블록의 proxy_bind 지시문은 $split_ip
변수의 값에 따라 각 요청 중에 로컬 IP 주소를 설정합니다. 이 변수를 해시 함수를 사용하여 해당 값을 결정하는 split_clients
블록에서 생성된 값으로 동적으로 설정합니다.
split_clients 지시문의 첫 번째 매개변수는 각 요청 중에 MurmurHash2 함수를 사용하여 해시되는 문자열(“$remote_addr$remote_port”)입니다. 두 번째 매개변수($split_ip)는 첫 번째 매개변수의 해시를 기반으로 동적으로 설정한 변수입니다.
중괄호 안의 명령문은 해시 테이블을 “버킷”으로 나누고 각 버킷에는 해시의 백분율이 포함됩니다. 여기서는 테이블을 같은 크기의 버킷 10개로 나누지만 버킷을 얼마든지 만들 수 있고 모두 같은 크기일 필요는 없습니다. (마지막 버킷의 백분율은 특정 숫자가 아닌 항상 별표[*]로 표시됩니다. 해시 수가 지정된 백분율로 균등하게 나누어지지 않을 수 있기 때문입니다.)
가능한 해시 값의 범위는 0에서 4294967295까지이므로 우리의 경우 각 버킷에는 약 429496700개의 값(전체의 10%)이 포함됩니다. 에. $split_ip
변수는 $remote_addr$remote_port
문자열의 해시가 포함된 버킷과 연결된 IP 주소로 설정됩니다. 구체적인 예로 해시 값 150000000은 네 번째 버킷에 속하므로 이 경우 $split_ip
변수는 동적으로 10.0.0.213으로 설정됩니다.
http {
upstream backend {
server 10.0.0.100:1234;
server 10.0.0.101:1234;
}
server {
# ...
location / {
# ...
proxy_pass http://backend;
proxy_bind $split_ip;
proxy_set_header X-Forwarded-For $remote_addr;
}
}
split_clients "$remote_addr$remote_port" $split_ip {
10% 10.0.0.210;
10% 10.0.0.211;
10% 10.0.0.212;
10% 10.0.0.213;
10% 10.0.0.214;
10% 10.0.0.215;
10% 10.0.0.216;
10% 10.0.0.217;
10% 10.0.0.218;
* 10.0.0.219;
}
}
6. NGINX Plus 포트 고갈 해결 결론
임시 포트 수에 대한 Linux 커널 설정을 조정하면 보다 효율적인 가용성 및 사용이 제공됩니다. NGINX Plus에서 Upstream 서버로의 keepalive 연결을 활성화하면 임시 포트를 더 효율적으로 사용할 수 있습니다. 마지막으로 NGINX Plus 구성에서 split_clients
및 proxy_bind
지시문을 사용하면 나가는 연결을 정의된 로컬 IP 주소 목록에 동적으로 바인딩하여 NGINX Plus에서 사용할 수 있는 임시 포트의 수를 크게 늘릴 수 있습니다.
NGINX Plus를 사용해 보려면 지금 무료 30일 평가판을 시작하거나 당사에 연락하여 사용 사례에 대해 문의하십시오.
사용 사례에 대해 최신 소식을 빠르게 전달받고 싶으시면 아래 뉴스레터를 구독하세요.
댓글을 달려면 로그인해야 합니다.