NGINX 성능 튜닝은 웹사이트에서 고가용성을 보장하는 데 중요한 연습입니다. NGINX를 웹 서버 또는 역방향 프록시로 사용하여 로드 밸런싱 및/또는 HTTP 캐싱을 수행하는 경우 이 블로그를 읽고 NGINX를 빠르고 성능 좋게 유지하기 위해 튜닝하는 방법에 대한 팁을 얻으세요.
NGINX 성능 튜닝이 중요한 이유
일반적으로 성능 튜닝은 비즈니스 자산의 투자 수익을 극대화하고 서비스의 높은 수준의 가용성을 유지하는 데 중요합니다. NGINX의 경우 튜닝은 사이트가 속도 및 지연에 대한 성능 벤치마크를 충족하고 초과하는 데 도움이 됩니다. NGINX 성능 튜닝은 일회성 작업이 아니라는 점을 기억하는 것이 중요합니다. 웹사이트나 애플리케이션 부하가 처음 추정하거나 계획한 것과 달라질 수 있으므로 성능을 극대화하기 위해 재평가하고 조정해야 할 수도 있습니다.
NGINX를 조정하기 전에
애플리케이션을 조정하기 전에 성능과 애플리케이션 사용 사례에 대한 현재 기준을 이해해야 합니다. 시스템 리소스를 프로파일링하고 반환된 콘텐츠 유형을 살펴보는 것으로 시작할 수 있습니다. 브라우저 개발자 도구, dstat(시각화할 수 있는 CSV 파일로 파이프됨)와 같은 시스템 성능 도구, Apache Bench 가 도움이 될 수 있으며 NGINX 로그를 검토하는 것도 도움이 될 수 있습니다.
프로파일링의 한 가지 이점은 핵심 성과 및 위험 지표를 확립할 수 있다는 것입니다. 애플리케이션이 어느 수준의 요청에서 성능이 저하되고 SLA를 위반할 가능성이 있는지 확인할 수 있습니다. 다양한 하드웨어(더 많은 CPU, 더 많은 RAM 및 캐싱용 디스크) 및 다양한 버전의 NGINX에서 튜닝 결과를 테스트하려면 여러 NGINX 인스턴스를 사용하는 것이 좋습니다.
SELinux나 AppArmor가 권장되지만, 이는 추가적인 성능 영향을 초래할 수 있다는 점을 알아두십시오. 이는 성능 테스트 중에 확인해야 할 사항입니다. 클라이언트가 HTTP 1.1, HTTP/2 또는 HTTP/3 프로토콜을 사용할지 여부를 결정합니다. 클라이언트 애플리케이션의 유형에 따라 HTTP/2 또는 HTTP/3을 사용하면 왕복이 줄어들어 지연 시간이 개선됩니다.
NGINX 작업자 프로세스 수정
기본적으로 NGINX는 작업자 프로세스 수에 하드웨어 CPU 코어 수를 사용합니다. 이는 각 작업자를 CPU 코어에 고정하고 Linux 커널을 통한 저수준 연결 관리 중에 컨텍스트 전환을 최소화하기 위해 수행됩니다. 하지만 다음 구성 지침을 사용하면 작업자 프로세스의 수를 조정할 수 있습니다.
worker_processes : 작업자 프로세스의 수를 정의합니다.
CPU 대 워커 프로세스의 이상적인 비율은 커널 네트워크 스택 대기열에서 연결과 이벤트를 가져오는 방식을 활용합니다. 그러나 일부 작업 부하와 처리량이 매우 높은 최신 프로세서가 많을 경우 워커 프로세스 수가 CPU 코어 수를 초과할 수 있습니다.
다시 말해, 더 많은 수의 작업자 프로세스는 CPU에서 활성 프로세스에서 프로세스로 컨텍스트를 전환하는 데 따른 페널티와 상관없이 이점이 될 수 있습니다. 이를 결정하는 방법은 벤치마킹이지만, 요청당 트래픽이 적을수록 연결 시간이 짧아지고 컨텍스트 전환의 영향이 작아질 가능성이 큽니다.
NGINX Worker 연결 관리
작업자 프로세스(및 CPU 코어)당 사용할 연결 수는 콘텐츠 및 작업 부하 테스트에 따라 결정해야 합니다. 다음 구성 지침은 작업자 프로세스당 연결 수를 설정합니다. 기본값은 512입니다.
worker_connections : 작업자 프로세스가 동시에 열 수 있는 최대 연결 수를 설정합니다.
여기서 TLS 처리가 CPU 부하를 증가시킨다는 점을 명심하세요. 상호 TLS가 있는 많은 수의 연결은 단일 코어를 로드할 가능성이 더 높습니다. 마찬가지로 콘텐츠 압축을 사용하면 작업자 프로세스 CPU 사용량이 증가합니다. 요청된 모든 데이터를 수신한 직후에 연결이 닫히도록 하려면 lingering_close 지시문을 비활성화하지 마세요.
NGINX를 로드 밸런서로 구성
NGINX를 프런트엔드 로드 밸런서로 사용하면 백엔드 서버 그룹 간에 효율적인 로드 분산이 가능합니다. 이렇게 하면 건강한 것으로 확인된 백엔드 서버에만 요청을 보내 고가용성을 보장합니다. 연결은 가중 라운드 로빈 방식으로 분산됩니다. 예를 들어, 더 많은 연결을 더 빠른 하드웨어가 있는 서버로 라우팅할 수 있습니다. 또는 연결은 가장 적은 수의 연결을 가진 백엔드 서버로 라우팅될 수 있습니다 .
NGINX의 오픈 소스 버전은 수동적 상태 확인을 사용하여 백엔드 서비스가 작동하고 연결을 수신할 준비가 되었는지 모니터링합니다. 수동적 상태 확인 메커니즘을 사용하여 NGINX는 연결이 발생하는 대로 연결을 모니터링하고 실패한 연결을 재개하려고 시도합니다. 연결이 실패하기 시작하면 백엔드 서비스는 사용할 수 없음으로 표시됩니다.
다음과 같은 구성 가능한 설정에 따라 업스트림 서비스는 사용할 수 없음으로 표시됩니다.
fail_timeout : 서버를 사용할 수 없음으로 표시하기 위해 실패한 시도 횟수에 대한 시간과, 서버가 사용할 수 없음으로 표시되는 시간(기본값은 10초)을 설정합니다.
max_fails : fail_timeout 기간 동안 서버를 사용할 수 없음으로 표시하기 위해 발생해야 하는 실패 시도 횟수를 설정합니다(기본값은 1회).
부하 분산은 ngx_http_upstream_module 을 사용하여 수행되며 해당 지시어로 구성됩니다.
멀티 백엔드 설정에서 해결해야 할 다음 문제는 세션 지속성입니다. 이는 스티키 세션 친화성 구성 지시문을 사용하여 달성됩니다.
정적 콘텐츠 캐시 및 압축
캐싱은 서버 측과 클라이언트 측으로 분류할 수 있습니다. 데이터를 가져오는 데 필요한 왕복 횟수가 적을수록 더 빨리 로드하거나 재사용할 수 있습니다.
- Proxy_Cache : 프록시 캐싱에 사용할 공유 메모리와 저장소를 정의합니다. proxy_cache_path 및 proxy_cache_key와 같은 동일한 트리의 지시문은 캐시할 위치와 패턴을 정의합니다.
- FastCGI 캐싱 : 마이크로 캐싱은 일정 데이터, RSS 피드, 일일 통계, 상태 페이지 등과 같이 자주 변경되지 않는 동적 콘텐츠에 가장 유용합니다.
- 클라이언트 측 캐시: 웹 서버는 클라이언트 측 캐싱에 대한 부분적인 제어만 할 수 있습니다. 하지만 HTTP 클라이언트에 캐싱 권장 사항과 함께 HTTP 응답 헤더를 제공할 수 있습니다.
- 캐시 제어 헤더 값: “Cache-Control public;”– HTTP 클라이언트와 모든 중간 프록시가 리소스를 캐시할 수 있도록 허용합니다. 제가 추천하는 옵션입니다. “Cache-Control private;”– HTTP 클라이언트 측에만 캐시하고 중간 프록시에는 캐시하지 않습니다. “Max-age”– 리소스를 캐시하는 데 걸리는 시간을 나타내는 초 단위 값입니다.
- Gzip 응답 압축 : 응답을 압축하면 콘텐츠 전송에 사용되는 시간이 줄어듭니다. 이를 통해 사용자 경험이 향상되고 잠재적으로 미터링된 연결에서 대역폭 비용이 줄어듭니다. JPEG와 같이 일부 콘텐츠 유형은 이미 압축되었을 수 있습니다.
NGINX 로깅 및 버퍼링에 주의하세요
액세스 및 오류 로그는 서버 측에서 문제 해결을 위한 첫 번째 단계입니다. 이러한 로그는 구성 오류, 액세스되는 리소스, HTTP 상태 코드 및 페이로드 크기를 보여줍니다. 버퍼 또는 gzip 매개변수를 사용하여 로그 버퍼링을 활성화합니다. 버퍼링이 활성화되면 데이터가 로그 파일에 기록됩니다.
다음 로그 줄이 버퍼에 맞지 않는 경우
flush버퍼링된 데이터가 매개변수(1.3.10, 1.2.7) 에 의해 지정된 것보다 오래된 경우
작업자 프로세스가 로그 파일을 다시 열거 나 종료될 때.
다음이 ngx_http_log_module포함됩니다:
액세스 로그 :access_log logs/access.log combined;
로그 형식 :log_format combined “…”;
다음이 ngx_core_module포함됩니다:
오류 로그:error_log logs/error.log error;
다음이 ngx_http_rewrite_module포함됩니다:
다시 쓰기 로그:rewrite_log off;
다음이 ngx_http_session_log_module포함됩니다:
세션 로그:session_log off;
기타 로깅 팁
로깅 및 애플리케이션 성능 테스트를 위해 프로덕션에서와 같이 최소한의 로깅을 사용하는 위치 블록과 디버그 목적으로 최대 로깅을 사용하는 또 다른 위치 블록을 설정합니다. 이렇게 하면 일부 요청을 자세히 분석하고 다른 요청은 최소한의 오버헤드로 처리할 수 있습니다. 이렇게 하면 서버 리소스를 보존할 수 있습니다. 원격 로깅을 사용하여 아키텍처의 여러 엔드포인트에서 정보를 집계합니다.
Nginx 웹서버 최적화 설정에 대해서 자세하게 알아보았습니다. 이와 같은 환경설정 하나가 실제 웹서비스 운영시 속도 측면에서 큰 영향을 미칠수도 있는것인데요. 현재 운영하는 웹서버의 상태를 파악하고 본문 내용에서 언급한 각 설정들을 참고하여 최적화 하는데 도움을 얻으시길 바랍니다.