NGINX는 고성능 로드 밸런서, 캐시, 웹 서버로 잘 알려져 있으며, 전 세계에서 트래픽이 가장 많은 웹사이트 중 40% 이상을 지원합니다. 대부분의 사용 사례에서는 NGINX와 Linux의 기본 설정만으로도 잘 작동하지만, 최적의 성능을 달성하려면 약간의 튜닝이 필요할 때도 있습니다. 이 블로그 게시물에서는 시스템을 튜닝할 때 고려해야 할 몇 가지 NGINX 및 Linux 설정을 살펴봅니다.
거의 모든 설정을 튜닝할 수 있지만, 이 글에서는 튜닝했을 때 가장 많은 사용자에게 도움이 되는 몇 가지 설정에 중점을 둡니다. NGINX와 Linux를 깊이 이해하고 있거나 당사의 지원 또는 프로페셔널 서비스 팀의 안내를 받은 경우에만 변경하도록 권장하는 설정도 있으며, 여기서는 이러한 설정을 다루지 않습니다. 프로페셔널 서비스 팀은 세계에서 가장 트래픽이 많은 여러 웹사이트와 협력하여 NGINX의 성능을 극대화해 왔으며, 고객이 NGINX 또는 NGINX Plus 배포 환경을 최대한 활용할 수 있도록 지원해 드립니다.
소개
NGINX 아키텍처와 구성 개념에 대한 기본적인 이해가 있다고 가정합니다. 이 글은 NGINX 문서의 내용을 그대로 반복하기보다는 다양한 옵션을 간략히 살펴보고 관련 문서 링크를 제공합니다.
튜닝할 때는 한 번에 하나의 설정만 변경하고, 변경 후에도 성능이 향상되지 않으면 기본값으로 되돌리는 것이 좋습니다.
일부 운영 체제 설정값에 따라 NGINX 구성을 조정하는 방법이 달라지므로, 먼저 Linux 튜닝에 대해 살펴보겠습니다.
Linux 구성 튜닝
최신 Linux 커널(2.6 이상)의 설정은 대부분의 용도에 적합하지만, 일부 설정을 변경하면 도움이 될 수 있습니다. 커널 로그에서 설정값이 너무 낮음을 나타내는 오류 메시지가 있는지 확인하고, 안내에 따라 조정하십시오. 여기서는 일반적인 워크로드에서 조정 효과가 가장 클 것으로 예상되는 설정만 다룹니다. 이러한 설정을 조정하는 방법에 대한 자세한 내용은 사용 중인 Linux의 설명서를 참조하십시오.
백로그 큐
다음 설정은 연결 및 연결이 대기열에 추가되는 방식과 관련이 있습니다. 수신 연결이 많고 성능이 고르지 않은 경우(예: 일부 연결이 지연되는 것처럼 보이는 경우) 이러한 설정을 변경하면 도움이 될 수 있습니다.
net.core.somaxconn– NGINX가 수락할 수 있도록 대기열에 넣을 수 있는 최대 연결 수입니다. 기본값은 대개 매우 낮지만 NGINX가 연결을 매우 빠르게 수락하므로 일반적으로는 문제가 없습니다. 다만 웹사이트에 트래픽이 많은 경우에는 이 값을 늘리는 것이 좋습니다. 커널 로그의 오류 메시지에 이 값이 너무 작다고 표시되면 오류가 더 이상 발생하지 않을 때까지 값을 늘리십시오.참고: 이 값을 512보다 크게 설정하는 경우 NGINX의backlog매개변수를listen지시문에 맞게 변경하십시오.net.core.netdev_max_backlog– 패킷이 CPU로 전달되기 전에 네트워크 카드에서 버퍼링되는 속도입니다. 이 값을 늘리면 대역폭이 높은 시스템의 성능을 향상할 수 있습니다. 커널 로그에서 이 설정과 관련된 오류를 확인하고, 값 변경에 대한 지침은 네트워크 카드 설명서를 참조하세요.
파일 디스크립터
파일 디스크립터는 연결 및 열린 파일 등을 나타내는 데 사용되는 운영 체제 리소스입니다. NGINX는 연결당 최대 2개의 파일 디스크립터를 사용할 수 있습니다. 예를 들어 NGINX가 프록시 역할을 하는 경우 일반적으로 클라이언트 연결에 하나의 파일 디스크립터를 사용하고 프록시 대상 서버와의 연결에 또 하나를 사용합니다. 단, HTTP 연결 유지를 사용하면 이 비율은 훨씬 낮아집니다. 많은 연결을 처리하는 시스템에서는 다음 설정을 조정해야 할 수 있습니다:
sys.fs.file-max– 시스템 전체의 파일 디스크립터 제한nofile– 사용자 파일 설명자 한도이며, /etc/security/limits.conf 파일에서 설정합니다
임시 포트
NGINX가 프록시로 작동할 때 업스트림 서버에 대한 각 연결은 임시 포트, 즉 동적 포트를 사용합니다. 이 설정을 변경해야 할 수도 있습니다:
net.ipv4.ip_local_port_range– 포트 값 범위의 시작과 끝입니다. 포트가 부족해지는 경우 범위를 늘리십시오. 일반적으로 포트 범위는 1024~65000으로 설정합니다.
NGINX 구성 최적화
다음은 성능에 영향을 줄 수 있는 몇 가지 NGINX 지시어입니다. 앞서 설명한 대로, 여기서는 사용자가 직접 조정해도 안전한 지시어만 다룹니다. NGINX 팀의 안내 없이 다른 지시어의 설정을 변경하지 않는 것이 좋습니다.
워커 프로세스
NGINX는 여러 워커 프로세스를 실행할 수 있으며, 각 프로세스는 다수의 동시 연결을 처리할 수 있습니다. 다음 지시어를 사용하여 워커 프로세스 수와 연결 처리 방식을 제어할 수 있습니다:
worker_processes– NGINX 워커 프로세스의 수입니다(기본값은 1). 대부분의 경우 CPU 코어당 하나의 워커 프로세스를 실행하는 것이 효과적이며, 이를 위해 이 지시어를auto로 설정하는 것이 좋습니다. 워커 프로세스에서 디스크 I/O를 많이 수행해야 하는 경우처럼 이 수를 늘려야 할 때도 있습니다.worker_connections– 각 워커 프로세스가 동시에 처리할 수 있는 최대 연결 수입니다. 기본값은 512이지만, 대부분의 시스템에는 더 많은 연결을 지원할 수 있는 충분한 리소스가 있습니다. 적절한 설정값은 서버 규모와 트래픽 특성에 따라 달라지며, 테스트를 통해 확인할 수 있습니다.
Keepalive 연결
Keepalive 연결은 연결을 열고 닫는 데 필요한 CPU 및 네트워크 오버헤드를 줄여 성능에 큰 영향을 줄 수 있습니다. NGINX는 모든 클라이언트 연결을 종료하고 업스트림 서버에 별도의 독립적인 연결을 생성합니다. NGINX는 클라이언트와 업스트림 서버 모두에 대해 Keepalive를 지원합니다. 다음 지시어는 클라이언트 Keepalive와 관련이 있습니다:
keepalive_requests– 클라이언트가 단일 keepalive 연결을 통해 수행할 수 있는 요청 수입니다. 기본값은 100이지만, 일반적으로 단일 클라이언트에서 많은 요청을 전송하는 부하 생성 도구로 테스트할 때는 훨씬 큰 값이 특히 유용할 수 있습니다.keepalive_timeout– 유휴 keepalive 연결을 열린 상태로 유지하는 시간입니다.
다음 지시어는 업스트림 연결 유지와 관련이 있습니다:
keepalive– 각 워커 프로세스에서 업스트림 서버에 대해 열린 상태로 유지되는 유휴 keepalive 연결 수입니다. 기본값은 없습니다.
업스트림 서버에 대한 keepalive 연결을 활성화하려면 구성에 다음 지시문도 포함해야 합니다:
proxy_http_version 1.1;proxy_set_header Connection "";액세스 로깅
모든 요청을 로깅하면 CPU와 I/O 리소스가 모두 소모됩니다. 이러한 영향을 줄이는 한 가지 방법은 액세스 로그 버퍼링을 활성화하는 것입니다. 버퍼링을 사용하면 각 로그 항목마다 별도의 쓰기 작업을 수행하는 대신 NGINX가 여러 항목을 버퍼에 모아 한 번의 작업으로 파일에 함께 기록합니다.
액세스 로그 버퍼링을 활성화하려면 buffer=size 매개변수를 access_log 지시문에 포함합니다. 버퍼가 size 값에 도달하면 NGINX가 버퍼의 내용을 로그에 기록합니다. 지정된 시간이 지난 후 NGINX가 버퍼를 기록하도록 하려면 flush=time 매개변수를 포함합니다. 두 매개변수를 모두 설정하면 다음 로그 항목이 버퍼에 들어갈 수 없거나 버퍼의 항목이 지정된 시간보다 오래된 경우에 각각 NGINX가 해당 항목을 로그 파일에 기록합니다. 워커 프로세스가 로그 파일을 다시 열거나 종료될 때도 로그 항목이 기록됩니다. 액세스 로깅을 완전히 비활성화하려면 off 매개변수를 access_log 지시문에 포함합니다.
Sendfile
운영 체제의 sendfile() 시스템 호출은 한 파일 디스크립터에서 다른 파일 디스크립터로 데이터를 복사하며, 이때 제로 카피가 구현되는 경우가 많아 TCP 데이터 전송 속도를 높일 수 있습니다. NGINX에서 이를 사용하도록 설정하려면 sendfile 지시어를 http 컨텍스트나 server 또는 location 컨텍스트에 포함하세요. 그러면 NGINX는 사용자 공간으로의 컨텍스트 전환 없이 캐시되었거나 디스크에 저장된 콘텐츠를 소켓으로 전송할 수 있으므로 쓰기 작업이 매우 빨라지고 CPU 사이클도 적게 소모됩니다. 단, sendfile()로 복사된 데이터는 사용자 공간을 우회하므로 일반적인 NGINX 처리 체인과 gzip처럼 콘텐츠를 변경하는 필터의 적용을 받지 않습니다. 구성 컨텍스트에 sendfile 지시어와 콘텐츠 변경 필터를 활성화하는 지시어가 모두 포함된 경우 NGINX는 해당 컨텍스트에서 sendfile을 자동으로 비활성화합니다.
제한 사항
클라이언트가 지나치게 많은 리소스를 사용하지 못하도록 다양한 제한을 설정할 수 있습니다. 리소스를 과도하게 사용하면 시스템 성능뿐만 아니라 보안과 사용자 경험에도 악영향을 줄 수 있습니다. 다음은 이와 관련된 몇 가지 지시어입니다:
limit_conn및limit_conn_zone– 예를 들어 단일 IP 주소에서 NGINX가 허용하는 클라이언트 연결 수를 제한합니다. 이를 설정하면 개별 클라이언트가 너무 많은 연결을 열어 할당된 몫보다 많은 리소스를 소비하는 것을 방지할 수 있습니다.limit_rate– 연결별로 클라이언트에 응답이 전송되는 속도를 제한합니다(따라서 여러 연결을 여는 클라이언트는 각 연결에서 이만큼의 대역폭을 사용할 수 있습니다). 제한을 설정하면 특정 클라이언트로 인해 시스템에 과부하가 발생하는 것을 방지하여 모든 클라이언트에 더욱 균등한 서비스 품질을 제공할 수 있습니다.limit_req및limit_req_zone– NGINX에서 처리되는 요청 속도를 제한하며, 이는limit_rate를 설정하는 것과 동일한 이점을 제공합니다. 또한 요청 속도를 사람이 사용하기에는 적절하지만 요청을 대량으로 보내 애플리케이션을 마비시키려는 프로그램에는 너무 느린 수준으로 제한하여 보안을 강화할 수 있으며, 특히 로그인 페이지에서 효과적입니다(예: DDoS 공격을 수행하는 봇).max_conns매개변수는server지시문에 사용되며,upstream구성 블록에서 업스트림 그룹의 서버가 허용하는 최대 동시 연결 수를 설정합니다. 제한을 두면 업스트림 서버의 과부하를 방지하는 데 도움이 됩니다. 값을 0(기본값)으로 설정하면 제한이 없습니다.queue(NGINX Plus) – 업스트림 그룹에서 사용 가능한 모든 서버가max_conns제한에 도달했을 때 요청이 대기하는 큐를 생성합니다. 이 지시어는 큐의 최대 요청 수와 오류가 반환되기 전까지의 최대 대기 시간(기본값 60초)을 선택적으로 설정합니다. 이 지시어를 생략하면 요청이 큐에 추가되지 않습니다.
캐싱과 압축으로 성능 향상
웹 애플리케이션의 성능을 높이는 데 사용할 수 있는 NGINX의 몇 가지 추가 기능은 엄밀히 말해 튜닝에 해당하지는 않지만, 성능에 상당한 영향을 미칠 수 있으므로 언급할 가치가 있습니다. 여기에는 캐싱과 압축이 포함됩니다.
캐싱
웹 서버 또는 애플리케이션 서버 집합의 부하를 분산하는 NGINX 인스턴스에서 캐싱을 활성화하면 클라이언트에 대한 응답 시간을 크게 단축하는 동시에 백엔드 서버의 부하도 대폭 줄일 수 있습니다. 캐싱은 그 자체로 별도로 다뤄야 할 주제이므로 여기서는 설명하지 않겠습니다. 자세한 내용은 NGINX Plus 관리 가이드를 참조하세요.
압축
클라이언트로 전송되는 응답을 압축하면 크기를 크게 줄여 네트워크 대역폭 사용량을 절감할 수 있습니다. 하지만 데이터 압축에는 CPU 리소스가 소모되므로 대역폭 사용량을 줄이는 것이 실질적으로 유용한 경우에 사용하는 것이 가장 좋습니다. JPEG 파일처럼 이미 압축된 객체에는 압축을 사용 설정하지 않아야 합니다. 자세한 내용은 NGINX Plus 관리 가이드를 참조하세요.
자세한 내용은 다음을 참조하세요:
- NGINX 벤치마킹: 정확도 향상 및 유의미한 결과 (온디맨드 웨비나)
- NGINX 참조 문서(nginx.org)
- NGINX 모델 비교
- NGINX Plus 기술 사양
NGINX Plus를 사용해 보려면 지금 30일 무료 평가판을 시작하거나 문의하여 데모를 신청하세요.
작성자 소개

관련 블로그 게시물
시청하기: KubeCon North America 2023에서의 NGINX Gateway Fabric
이 영상에서는 KubeCon의 NGINX 부스를 찾아가, 저희가 공개한 Kubernetes Gateway API 구현을 살펴봅니다.
F5 NGINX로 대규모 WAF 플릿을 확인하고 관리하는 2가지 방법
앱 보안을 강화하는 두 가지 방법을 소개합니다. NGINX Management Suite를 통해 WAF 운영에 대한 가시성을 높이고, NGINX App Protect WAF를 활용해 코드형 보안을 구현하는 것입니다.
Ingress 컨트롤러 선택 가이드, 4부: NGINX Ingress Controller 옵션
개발 주체, 개발 철학, 프로덕션 환경 준비도, 보안 및 지원을 기준으로 어떤 NGINX Ingress 컨트롤러가 가장 적합한지 알아보세요.
진화하는 공격 환경에 NGINX App Protect Denial of Service가 적응하는 방법
NGINX App Protect Denial of Service(DoS)가 계층 7 DoS 공격을 방어하기 위해 완화 방법을 실시간으로 조정하는 방식을 설명합니다. 정상적인 사용자 행동과 서버 상태에 대한 모델을 생성하여 공격을 나타내는 이상 징후를 감지하고 맞춤형 완화 시그니처를 적용할 수 있습니다.
NGINX Instance Manager를 활용한 대규모 구성 업데이트 및 인증서 관리
NGINX Instance Manager 버전 1.0에는 두 가지 새로운 기능이 도입되었습니다. NGINX 인스턴스에 태그와 사용자 역할을 지정하면 전체 그룹에 구성을 한 번에 적용할 수 있습니다. 인증서 검사는 만료 예정인 인증서를 감지하여 서비스 중단을 방지할 수 있도록 인증서를 교체할 수 있게 해줍니다.
Netflix가 자사 CDN의 핵심으로 NGINX를 선택한 이유
Netflix가 글로벌 콘텐츠 전송 네트워크인 Open Connect의 스트리밍 미디어 기술로 NGINX를 선택한 이유를 NGINX 개발자 Gleb Smirnoff에게서 알아보세요.