NGINX 애플리케이션 성능 향상을 위한 10가지 팁
이번 포스트에서는 NGINX 애플리케이션 성능을 최대 10배까지 향상시키는 10가지 팁을 제공하여 웹 사이트 성능 개선을 도와줄 것입니다.
웹 애플리케이션 의 성능 개선은 이전보다 더욱 중요합니다.
온라인 상에서의 경제활동이 증가함에 따라, 선진국의 경제활동의 5% 이상이 이제는 인터넷에서 이루어지고 있습니다.
또한, 우리는 항상 연결되어 있으며, 빠르게 변화하는 현대 사회에서 사용자들의 기대치가 이전보다 높아졌습니다.
만약 여러분의 사이트가 즉각적으로 응답하지 않거나, 여러분의 앱이 지연없이 작동하지 않으면, 사용자들은 즉시 여러분의 경쟁 사이트로 이동하게 됩니다.
예를 들어, 약 10년 전 아마존에서 진행한 연구는 페이지 로딩 시간이 100ms 감소하면 매출이 1% 증가한다는 것을 입증했습니다.
최근 조사에서는 사이트 소유자의 절반 이상이 애플리케이션 성능이 나쁘기 때문에 매출이나 고객을 상실했다는 사실이 강조되었습니다.
웹 사이트가 얼마나 빨라야 할까요? 페이지 로딩에 걸리는 각 초마다 약 4%의 사용자가 이탈합니다.
최고 전자상거래 사이트는 첫 상호작용 시간을 1~3초로 제공하여 최고의 전환율을 제공합니다.
웹 애플리케이션의 성능 요구치가 높아지고 있으며, 앞으로 더욱 높아질 것으로 보입니다.
이 시리즈는 NGINX의 도움을 받아 검증된 최적화 기술을 활용하여 애플리케이션 성능을 향상시키는 방법을 자세히 설명하며, 이를 통해 보다 안전한 보안을 제공할 수 있는 가능성도 소개합니다.
목차
1. NGINX 리버스 프록시 서버로 애플리케이션 가속화 및 보호
1-1. 왜 리버스 프록시 일까요?
2. NGINX 로드 밸런서 추가
3. NGINX 정적 및 동적 콘텐츠 캐시
3-1. 캐시 외부 구현
4. 데이터 압축
5. NGINX SSL/TLS 최적화
6. NGINX HTTP/2 또는 SPDY 구현
7. 애플리케이션 소프트웨어 버전 업데이트
8. 애플리케이션 성능을 위해 Linux 조정
9. 애플리케이션 성능을 위해 웹 서버 조정
9-1. 리소스 제한
10. 실시간 활동 모니터링을 통한 문제 및 병목 현상 해결
11. NGINX 애플리케이션 성능 향상 결론
11-1. 요약
1. NGINX 리버스 프록시 서버로 애플리케이션 가속화 및 보호
웹 애플리케이션이 단일 컴퓨터에서 실행되는 경우, 성능 문제를 해결하기 위한 해결책은 빠른 프로세서, 많은 RAM, 빠른 디스크 배열 등을 가진 더 빠른 컴퓨터를 구입하는 것처럼 보일 수 있습니다.
그러면 새로운 컴퓨터에서 WordPress 서버, Node.js 애플리케이션, Java 애플리케이션 등을 기존보다 빠르게 실행할 수 있습니다. (데이터베이스 서버에 액세스하는 경우에도 해결책은 간단할 수 있습니다. 더 빠른 두 대의 컴퓨터와 더 빠른 연결을 구입하세요.)
그러나 문제는 머신 속도가 문제가 아닐 수 있다는 것입니다. 웹 애플리케이션은 종종 컴퓨터가 다른 종류의 작업을 전환하면서 느리게 실행됩니다.
수천 개의 연결에서 사용자와 상호 작용하고, 디스크에서 파일을 액세스하고, 애플리케이션 코드를 실행하는 등의 작업을 수행합니다.
애플리케이션 서버는 메모리 부족 상태에 빠지며, 메모리 조각들을 디스크로 Swap 하고 디스크 I/O와 같은 하나의 작업을 기다리는 많은 요청을 대기 상태로 만들 수 있습니다.
하드웨어를 업그레이드하는 대신, 완전히 다른 접근 방식을 사용할 수 있습니다.
리버스 프록시 서버를 추가하여 일부 작업을 언로드하는 것입니다. 리버스 프록시 서버는 애플리케이션을 실행하는 머신 앞에 위치하여 인터넷 트래픽을 처리합니다.
인터넷에 직접 연결되는 것은 리버스 프록시 서버뿐이며, 애플리케이션 서버와의 통신은 빠른 내부 네트워크를 통해 이루어집니다.
1-1. 왜 리버스 프록시일까요?
리버스 프록시 서버를 사용하면 웹 애플리케이션과 상호작용하는 사용자를 기다릴 필요가 없어져서 앱 서버는 인터넷을 통해 전송할 리버스 프록시 서버의 페이지를 만드는 데 집중할 수 있습니다.
클라이언트 응답을 기다릴 필요가 없어진 애플리케이션 서버는 최적화된 벤치마크에서 얻은 속도와 유사한 속도로 작동할 수 있습니다.
리버스 프록시 서버를 추가하면 웹 서버 구성에 유연성이 더해집니다.
예를 들어, 특정 유형의 서버가 과부하 상태인 경우 동일한 유형의 다른 서버를 쉽게 추가할 수 있으며, 서버가 다운된 경우 쉽게 대체할 수 있습니다.
리버스 프록시 서버는 제공하는 유연성 때문에 다른 많은 성능 향상 기능의 선결 조건이 됩니다. 이러한 기능에는 다음과 같은 것들이 있습니다.
- 로드 밸런서 (목차 2 참조) – 로드밸런서는 리버스 프록시 서버에서 실행되어, 여러 애플리케이션 서버에 트래픽을 고르게 분산시킵니다. 로드 밸런서가 있으면 애플리케이션을 변경하지 않고도 애플리케이션 서버를 추가할 수 있습니다.
- 정적 파일 캐싱(목차 3 참조) – 이미지 파일이나 코드 파일과 같이 직접 요청되는 파일은 리버스 프록시 서버에 저장될 수 있으며, 이 파일들은 클라이언트에 직접 전송되어 더 빠르게 서비스되고, 애플리케이션 서버의 부담을 줄여 애플리케이션이 더 빠르게 실행될 수 있습니다.
- 사이트 보안 – 리버스 프록시 서버는 고도의 보안 설정을 구성하고, 공격에 빠르게 대응하여 애플리케이션 서버를 보호할 수 있습니다.
NGINX 소프트웨어는 추가 기능을 갖춘 리버스 프록시 서버로 사용하기 위해 특별히 설계되었습니다. NGINX는 전형적인 서버보다 더 효율적인 이벤트 기반 처리 방식을 사용합니다. NGINX Plus는 애플리케이션 상태 확인, 특수 요청 라우팅, 고급 캐싱 및 지원 등과 같은 고급 리버스 프록시 기능을 추가합니다.

2. NGINX 로드 밸런서 추가
로드 밸런서를 추가하는 것은 사이트의 성능과 보안을 극적으로 개선할 수 있는 상대적으로 간단한 변경사항입니다.
핵심 웹 서버를 더 크고 강력하게 만드는 대신 로드 밸런서를 사용하여 여러 대의 서버에 트래픽을 분산합니다.
애플리케이션이 잘못 작성되었거나 확장하는 데 문제가 있는 경우에도 로드 밸런서를 사용하면 다른 변경 사항 없이도 사용자 경험을 개선할 수 있습니다.
로드 밸런서는 먼저, 리버스 프록시 서버입니다(목차 1 참조) – 인터넷 트래픽을 받아들이고 요청을 다른 서버로 전달합니다.
로드 밸런서는 두 개 이상의 애플리케이션 서버를 지원하여 알고리즘 선택을 사용하여 요청을 서버 간에 분산시킵니다.
가장 간단한 로드 밸런싱 방법은 Round Robin으로, 각 새 요청이 목록의 다음 서버로 전송됩니다.
다른 방법으로는 활성 연결이 가장 적은 서버로 요청을 보내는 것이 있습니다.
NGINX Plus는 세션 지속성이라는 사용자 세션을 동일한 서버에서 유지하는 기능을 제공합니다.
로드 밸런서는 한 서버가 과부하가 걸리는 것을 막아 다른 서버가 트래픽을 기다리는 동안 서버의 과부하를 방지하여 성능을 크게 향상시킬 수 있습니다.
또한 비교적 저렴한 서버를 추가하고 이를 완전히 활용할 수 있으므로 웹 서버 용량을 쉽게 확장할 수 있습니다.
로드 밸런싱할 수 있는 프로토콜에는 HTTP, HTTPS, SPDY, HTTP/2, WebSocket, FastCGI, SCGI, uwsgi, memcached, 그리고 TCP 기반 애플리케이션 및 다른 Layer 4 프로토콜을 포함한 다른 애플리케이션 유형도 있습니다.
성능이 느린 지점과 사용하는 프로토콜을 파악하여 웹 애플리케이션을 분석하세요.
로드 밸런싱에 사용되는 동일한 서버는 SSL Termination, 클라이언트에 의한 HTTP/1.x 및 HTTP/2 지원 및 정적 파일 캐싱과 같은 다른 작업도 처리할 수 있습니다.
NGINX는 종종 로드 밸런싱에 사용됩니다. NGINX Plus는 상용 제품으로, 서버 응답 시간에 따라 로드 라우팅 및 Microsoft의 NTLM 프로토콜에 대한 로드 밸런싱 기능과 같은 보다 특화된 로드 밸런싱 기능을 지원합니다.
3. NGINX 정적 및 동적 콘텐츠 캐시
캐싱은 클라이언트에게 콘텐츠를 빠르게 제공하여 웹 애플리케이션 성능을 향상시킵니다.
캐싱은 콘텐츠를 미리 처리하여 필요할 때 빠른 전달, 빠른 디바이스에 콘텐츠 저장, 클라이언트 근처에 콘텐츠 저장 또는 그 결합 등의 전략을 사용할 수 있습니다.
고려해야 할 두 가지 캐싱 유형이 있습니다.
- 정적 콘텐츠 캐싱 – 이미지 파일 (JPEG, PNG) 및 코드 파일 (CSS, JavaScript)과 같은 변경이 드문 파일을 Edge 서버에 저장하여 메모리나 디스크에서 빠르게 검색할 수 있습니다.
- 동적 콘텐츠 캐싱 – 많은 웹 애플리케이션은 각 페이지 요청마다 새 HTML을 생성합니다.
생성된 HTML의 한 복사본을 짧은 시간 동안 캐싱하여 생성해야 하는 전체 페이지 수를 크게 줄이면서 요구 사항을 충족시키는 충분히 신선한 콘텐츠를 전달할 수 있습니다.
예를 들어 페이지가 초당 10회 조회된다면, 1초 동안 캐싱한다면 페이지 요청의 90%는 캐시에서 처리됩니다. 만약 정적 콘텐츠를 따로 캐시한다면, 심지어 페이지의 새로 생성된 버전조차도 대부분 캐시된 콘텐츠로 이루어질 수 있습니다.
웹 애플리케이션에서 생성된 콘텐츠를 캐시하는 방법에는 세 가지 기본 기술이 있습니다:
- 사용자에게 더 가까운 위치에 콘텐츠 이동 – 콘텐츠를 사용자에게 더 가까운 위치에 복사해 두면 전송 시간이 줄어듭니다.
- 보다 빠른 장치로 콘텐츠 이동 – 콘텐츠를 빠른 장치에 유지하여 더 빠른 검색이 가능합니다.
- 과부하된 기기에서 콘텐츠 이동 – 기계는 종종 특정 작업에서 벤치마크 성능보다 훨씬 느리게 작동하기도 합니다. 다른 기계에 캐싱을 하면 캐시된 리소스와 캐시되지 않은 리소스의 성능이 향상됩니다. 왜냐하면 호스트 기계가 덜 과부하되기 때문입니다.
3-1. 캐시 외부 구현
웹 애플리케이션의 캐싱은 내부에서부터 외부로 구현될 수 있습니다.
먼저 캐싱은 동적 콘텐츠를 위해 사용되어 애플리케이션 서버의 부하를 줄입니다.
그런 다음 캐싱은 정적 콘텐츠 (동적 콘텐츠로서 처리될 수 있는 일시적인 사본을 포함)에 대해서도 적용되어 애플리케이션 서버의 부하를 더욱 덜어줍니다.
마지막으로 캐싱은 애플리케이션 서버에서 더 빠르고/사용자에게 더 가까운 기계로 이동시켜서 애플리케이션 서버의 부담을 줄이고 검색 및 전송 시간을 단축합니다.
개선된 캐싱은 애플리케이션을 매우 빠르게 만들 수 있습니다.
많은 웹 페이지에서 큰 이미지 파일과 같은 정적 데이터가 콘텐츠의 절반 이상을 차지할 수 있습니다.
캐싱하지 않으면 이러한 데이터를 검색하고 전송하는 데 몇 초가 걸릴 수 있지만, 데이터를 로컬 캐시에 저장하면 일부분의 초만에 처리할 수 있습니다.
NGINX와 NGINX Plus에서 캐싱을 설정하는데 사용되는 두 가지 지시어는 proxy_cache_path
와 proxy_cache
입니다.
캐시 위치와 크기, 파일이 캐시에 보관될 최대 시간 및 기타 매개변수를 지정합니다.
제 3의 지시어인 proxy_cache_use_stable
을 사용하면, 공급자 서버가 바쁘거나 다운되어 새로운 컨텐츠를 제공할 수 없는 경우, 캐시가 기간이 만료된 내용을 제공할 수 있도록 지시할 수 있습니다.
이를 통해 사용자는 사이트나 애플리케이션의 가동 시간을 크게 향상시킬 수 있습니다.
NGINX Plus는 캐시 제거(Cache Purge API) 및 실시간 활동 모니터링 대시보드에서 캐시 상태 시작화와 같은 고급 캐싱 기능을 제공합니다.
4. 애플리케이션 데이터 압축
압축은 큰 잠재적인 성능 가속기입니다. 사진 (JPEG 및 PNG), 비디오 (MPEG-4) 및 음악 (MP3)을 위한 신중하게 설계된 고효율 압축 표준이 있습니다. 이러한 각 표준은 파일 크기를 한 단계 이상 줄입니다.
텍스트 데이터 (HTML, CSS 및 JavaScript와 같은 코드를 포함)는 종종 압축되지 않고 전송됩니다.
이 데이터를 압축하면 느린, 또는 제한된 모바일 연결을 갖는 클라이언트의 성능에 불균형적인 영향을 미칠 수 있기 때문입니다. 이를 위해 압축 기술을 사용하는 것이 가능합니다.
이는 텍스트 데이터가 사용자가 페이지와 상호작용 하는데 충분하기 때문입니다.
멀티미디어 데이터는 보조적이거나 장식적일 수 있지만, 텍스트 데이터가 주요한 역할을 합니다.
HTML, JavaScript, CSS 등의 텍스트 기반 콘텐츠의 똑똑한 압축은 대개 대역폭 요구 사항을 30% 이상 줄이고 로드 시간을 줄입니다.
이러한 이유로 텍스트 데이터의 압축은 웹 애플리케이션 성능 향상에 큰 역할을 합니다.
SSL을 사용하는 경우, 압축은 SSL로 인코딩 해야 할 데이터 양을 줄여주므로 데이터를 압축하는데 드는 CPU의 시간을 줄일 수 있습니다.
텍스트 데이터를 압축하는 방법은 다양합니다. 예를 들어, 헤더 데이터에 특별히 적합한 SPDY 및 HTTP/2의 새로운 텍스트 압축 방식을 위한 목차 6을 참조하세요. 또한 NGINX에서 GZIP 압축을 해제할 수 있습니다.
서비스에서 텍스트 데이터를 미리 압축한 후 gzip_static
지시어를 사용하여 압축된 .gz 파일을 직접 제공할 수 있습니다.
5. NGINX SSL/TLS 최적화
SSL/TLS 프로토콜과 이의 후계인 TLS 프로토콜은 이제 더 많은 웹사이트에서 사용되고 있습니다.
SSL/TLS는 서버에서 사용자로 전송되는 데이터를 암호화하여 사이트 보안을 향상시킵니다. 이러한 경향의 일부는 구글이 이제 SSL/TLS의 존재를 검색 엔진 순위에 긍정적인 영향을 미치는 요소로 사용하기 때문일 수 있습니다.
하지만 SSL/TLS의 성능 저하는 많은 사이트에서 문제가 되고 있습니다. SSL/TLS가 웹 사이트 성능을 느리게 만드는 이유는 다음과 같습니다:
- 새로운 연결이 열릴 때마다 암호화 키를 설정하기 위해 필요한 초기 핸드셰이크 (Handshake). 브라우저가 HTTP/1.x를 사용하여 하나의 서버에 여러 연결을 설정하는 방식은 이 문제를 곱셈처럼 증가시킵니다.
- 서버에서 데이터를 암호화하고 클라이언트에서 해독하는 과정에서 발생하는 지속적인 오버헤드 (Overhead)
따라서 HTTP/2와 SPDY의 저자들은 브라우저가 브라우저 세션 당 하나의 연결만 필요로하는 방식으로 이러한 프로토콜을 설계하여 SSL 오버헤드의 주요 원인 중 하나를 크게 줄였습니다. 그러나 현재 SSL/TLS로 전달되는 애플리케이션의 성능을 더욱 향상시키기 위해 더 많은 작업을 할 수 있습니다.
SSL/TLS 최적화 방법은 웹 서버에 따라 다양합니다.
NGINX는 OpenSSL을 사용하여 표준 상용 하드웨어에서 독립된 하드웨어 솔루션과 유사한 성능을 제공합니다.
NGINX SSL 성능은 문서화가 잘 되어있으며, SSL/TLS 암호화 및 복호화 수행에 따른 시간 및 CPU 부담을 최소화 합니다.
SSL/TLS 성능을 향상 시키는 방법에 대해 간단하게 요약하자면, 다음과 같은 기법이 있습니다.
- 세션 캐싱 – ssl_session_cache 지시문을 사용하여 SSL/TLS로 새로운 연결을 보호할 때 사용되는 매개 변수를 캐시합니다.
- 세션 티켓 또는 ID – 티켓이나 ID에 특정 SSL/TLS 세션 정보를 저장하여 새로운 핸드셰이킹 없이 연결을 원활하게 재사용할 수 있습니다.
- OCSP 스탭링 – SSL/TLS 인증서 정보를 캐시하여 핸드셰이킹 시간을 단축합니다.
SSL/TLS Termination를 위해 NGINX 또는 NGINX Plus를 사용할 수도 있습니다. 이 경우 클라이언트 트래픽의 암호화 및 복호화를 처리하고 다른 서버와는 암호화되지 않은 텍스트로 통신합니다. SSL/TLS Termination를 설정하는 방법은 HTTPS 연결 및 암호화된 TCP 연결에 대한 지침을 참조하십시오.
6. NGINX HTTP/2 또는 SPDY 구현
SSL/TLS를 이미 사용하는 사이트의 경우, HTTP/2
SPDY는 연결 당 하나의 핸드셰이크만 필요하므로 성능을 향상시키는 데 매우 유용합니다. SSL/TLS를 아직 사용하지 않는 사이트의 경우, HTTP/2와 SPDY는 응답성 관점에서 보면 일반적으로 성능이 느려지는 SSL/TLS 전환을 상쇄시키는 효과가 있습니다.
Google은 2012년에 HTTP/1.x 위에 더 빠른 성능을 달성하기 위한 방법인 SPDY를 소개했습니다. HTTP/2는 SPDY를 기반으로 한 최근에 승인된 IETF 표준입니다. SPDY는 널리 지원되지만 곧 폐기될 예정이며 HTTP/2로 대체됩니다.
SPDY와 HTTP/2의 주요 기능은 다중 연결 대신 단일 연결을 사용하는 것입니다. 이 단일 연결은 다중 요청 및 응답 조각을 동시에 전송할 수 있도록 다중화됩니다.
이러한 프로토콜이 하나의 연결에서 최대한의 이점을 얻음으로써 브라우저가 HTTP/1.x를 구현하는 데 필요한 여러 연결의 설정 및 관리 오버헤드 (Overhead) 를 피할 수 있습니다. SSL의 경우 단일 연결 사용은 SSL/TLS이 안전한 연결을 설정하기 위해 필요한 시간 소모적인 핸드쉐이킹 (HandShaking)을 최소화하는 데 매우 유용합니다.
SPDY 프로토콜은 SSL/TLS 사용을 요구했지만, HTTP/2는 공식적으로 SSL/TLS를 요구하지 않습니다. 그러나 지금까지 HTTP/2를 지원하는 모든 브라우저는 SSL/TLS가 활성화된 경우에만 사용합니다. 즉, HTTP/2를 지원하는 브라우저는 웹사이트가 SSL을 사용하고 해당 서버가 HTTP/2 트래픽을 수용하는 경우에만 사용됩니다. 그렇지 않으면 브라우저는 HTTP/1.x를 통해 통신합니다.
SPDY 또는 HTTP/2를 구현하면 일반적인 HTTP 성능 최적화, 예를 들어 도메인 샤딩, 리소스 병합 및 이미지 스프라이트와 같은 것이 필요하지 않습니다. 이러한 변경 사항으로 인해 코드와 배포가 간소화되어 관리하기 쉬워집니다.

NGINX는 SPDY 프로토콜을 초기부터 지원해 왔으며, 오늘날 SPDY를 사용하는 대부분의 사이트는 NGINX에서 실행됩니다. NGINX는 2015년부터 NGINX 오픈소스 및 NGINX Plus에서 HTTP/2 지원을 선도하고 있습니다.
시간이 지나면서, NGINX는 대부분의 사이트가 SSL을 완전히 활성화하고 HTTP/2로 이동할 것으로 예상합니다. 이는 보안이 향상되며, 새로운 최적화 기술이 발견되고 구현됨에 따라 더 간단하고 더 잘 작동하는 코드로 이어질 것입니다.
7. 애플리케이션 소프트웨어 업데이트
소프트웨어 스택에서 구성 요소를 선택할 때 안정성과 성능으로 인기 있는 것을 선택하는 것은 애플리케이션 성능을 높이는 간단한 방법 중 하나입니다. 또한, 고품질 컴포넌트의 개발자들은 시간이 지남에 따라 성능 향상 및 버그 수정을 추구하기 때문에 가장 최신의 안정적인 소프트웨어 버전을 사용하는 것이 유리합니다. 새 릴리스는 개발자와 사용자 커뮤니티에서 더 많은 관심을 받습니다.
또한 새로운 빌드는 새로운 하드웨어에 대한 튜닝을 비롯한 새로운 컴파일러 최적화를 활용합니다.
안정적인 새 릴리스는 보통 이전 릴리스보다 호환성이 높고 성능이 더 좋습니다.
또한 소프트웨어 업데이트를 최신 상태로 유지하면 튜닝 최적화, 버그 수정 및 보안 경보를 쉽게 유지할 수 있습니다.
이전 소프트웨어를 사용하면 새로운 기능을 활용할 수 없는 경우가 있습니다.
예를 들어, 위에서 설명한 HTTP/2는 2015년 OpenSSL 1.0.1을 필요로 했습니다. 2016년 중반부터는 HTTPS/2 1.0.2를 필요로 했습니다.
NGINX 사용자는 NGINX 또는 NGINX Plus의 최신 버전으로 이동하여 시작할 수 있습니다. 소켓 샤딩 및 스레드 풀과 같은 새로운 기능을 포함하고 있으며, 계속해서 성능 튜닝이 이루어지고 있습니다. 그 다음, 스택의 더 깊은 소프트웨어를 살펴보고 가능한 경우 최신 버전으로 업그레이드 하세요.
8. 애플리케이션 성능을 위해 Linux 조정
리눅스는 오늘 날 대부분의 웹 서버 구현의 기본 운영체제이며, 인프라의 기반으로서 리눅스는 최대 성능을 위해 어느 정도 조정할 수 있는 중요한 기회를 제공합니다. 기본적으로 많은 리눅스 시스템은 일반적인 데스크톱 워크로드에 맞추어 적은 리소스를 사용하도록 보수적으로 튜닝 되어 있습니다. 이는 웹 애플리케이션 사용 사례가 최대 성능을 위해 어느 정도의 조정이 필요함을 의합니다.
리눅스 최적화는 웹 서버에 맞게 특정되어 있습니다. NGINX를 예로 들면, 리눅스를 더 빠르게 만들기 위해 고려할 수있는 몇 가지 변경사항을 소개합니다.
리눅스 최적화는 웹 서버에 맞게 특정되어 있습니다. NGINX를 예로 들면, 리눅스를 더 빠르게 만들기 위해 고려할 수 있는 몇 가지 변경 사항을 소개합니다.
- 백로그 큐 – 연결이 지연되는 것처럼 보이는 경우, NGINX가 처리를 대기하는 연결의 최대 개수 인 net.core.somaxconn을 늘리는 것을 고려해보세요. 기존 연결 제한이 너무 작은 경우 오류 메시지가 표시되며, 이 매개변수를 점진적으로 늘려 오류 메시지가 나타나지 않도록 할 수 있습니다.
- 파일 디스크립터 – NGINX는 각 연결에 최대 두 개의 파일 디스크립터를 사용합니다. 시스템이 많은 연결을 처리하고 있다면, sys.fs.file_max (시스템 전체 파일 디스크립터 제한)와 nofile (사용자 파일 디스크립터 제한)를 늘려 부하를 지원할 수 있습니다.
- 임시 포트 – 프록시로 사용될 때, NGINX는 각 업스트림 서버에 대해 임시 (“임시”) 포트를 생성합니다. 사용 가능한 포트 수를 늘리려면, net.ipv4.ip_local_port_range로 설정된 포트 값 범위를 늘리면 됩니다. net.ipv4.tcp_fin_timeout 설정을 사용하여 비활성 포트가 재사용되기 전의 시간 초과를 줄여 더 빠른 전환을 가능하게 할 수도 있습니다.
9. 애플리케이션 성능을 위해 웹 서버 조정
어떤 웹 서버를 사용하든, 웹 애플리케이션 성능에 맞게 조정해야 합니다. 다음은 어떤 웹 서버에도 일반적으로 적용되는 권장사항이며,
NGINX에 대한 구체적인 설정도 제공합니다. 주요 최적화 방법은 다음과 같습니다.
- Access logging – 각 요청마다 즉시 디스크에 로그 항목을 작성하는 대신, 항목을 메모리에 버퍼링하고 한 그룹으로 디스크에 작성할 수 있습니다. NGINX의 경우, access_log 지시어에 buffer=size 매개변수를 추가하여 메모리 버퍼가 가득 차면 로그 항목을 디스크에 작성하도록 설정할 수 있습니다.
flush=time 매개변수를 추가하면 지정된 시간이 지난 후 버퍼 내용도 디스크에 작성됩니다. - Buffering – 버퍼링은 응답의 일부를 메모리에 저장하여 클라이언트와의 통신을 더 효율적으로 만듭니다.
메모리에 저장하지 못하는 응답은 디스크에 기록되며 성능 저하를 초래할 수 있습니다. NGINX 버퍼링이 켜져 있으면, proxy_buffer_size 및 proxy_buffers 지시어를 사용하여 버퍼링을 관리할 수 있습니다. - Client keepalives – Keepalive 연결은 오버헤드를 줄이는 데 도움이되며, 특히 SSL/TLS를 사용할 때 유용합니다. NGINX의 경우, 클라이언트가 지정된 연결에서 할 수 있는 최대 keepalive_requests 수를 기본값인 100보다 높이고, keepalive_timeout을 늘려서 keepalive 연결이 더 오래 유지되도록 할 수 있습니다.
이로 인해 이후 요청이 더 빨리 처리됩니다. - Upstream keepalives – 애플리케이션 서버, 데이터베이스 서버 등에 대한 연결인 업스트림 연결도 keepalive 연결에서 이익을 얻을 수 있습니다.
업스트림 연결의 경우 keepalive 값을 늘려서 각 Worker 프로세스마다 열어둘 수 있는 비활성 keepalive 연결 수를 늘릴 수 있습니다. 이렇게 하면 새로운 연결을 여는 데 필요한 시간이 줄어들어 연결 재사용이 증가하게 되므로 성능 향상에 기여합니다.
9-1. 리소스 제한
- Limits – 클라이언트가 사용하는 리소스를 제한하는 것은 성능과 보안을 향상시키는 데 도움이 됩니다. NGINX에서는 limit_conn 및 limit_conn_zone 지시문을 사용하여 특정 소스에서의 연결 수를 제한하고, limit_rate는 대역폭을 제한합니다.
이러한 설정은 합법적인 사용자가 리소스를 “독점”하는 것을 방지하고 공격을 예방하는 데 도움이 됩니다.
limit_req 및 limit_req_zone 지시문은 클라이언트 요청을 제한합니다.
상위 서버에 대한 연결에서는 max_conns 매개변수를 상위 구성 블록의 server 지시문에 사용합니다. 이는 상위 서버의 연결을 제한하여 과부하를 방지합니다.
연결 수 제한에 도달하면 연결 큐를 만들어 일정 시간 동안 지정된 수의 요청을 대기시킵니다. - Worker processes – 워커 프로세스는 요청 처리를 담당합니다. NGINX는 이벤트 기반 모델과 OS 종속 메커니즘을 사용하여 요청을 효율적으로 Worker 프로세스 간에 분배합니다.
권장 사항은 CPU 당 하나의 worker_processes 값을 설정하는 것입니다.
대부분의 시스템에서 worker_connections의 최대 값(기본값은 512)을 필요에 따라 안전하게 높일 수 있으며, 시스템에 가장 적합한 값을 찾기 위해 실험해보세요. - Socket sharding – 일반적으로 단일 소켓 리스너가 모든 Worker 프로세스에게 새로운 연결을 분배합니다.
소켓 샤딩은 각 Worker 프로세스에 대해 소켓 리스너를 만들어 커널이 사용 가능한 상태가 되면 연결을 소켓 리스너에 할당합니다.
이는 멀티코어 시스템에서 락 경합(lock contention)을 줄이고 성능을 향상시킬 수 있습니다. 소켓 샤딩을 활성화하려면 listen 지시어에 reuseport 매개변수를 포함하면 됩니다. - Thread pools – 어떤 컴퓨터 프로세스라도 단일하게 느린 작업에 막힐 수 있습니다.
웹 서버 소프트웨어의 경우, 디스크 액세스는 메모리 내에서 계산이나 복사와 같은 많은 빠른 작업을 차단할 수 있습니다.
쓰레드 풀을 사용하면 느린 작업은 별도의 작업 집합에 할당되고, 메인 처리 루프는 더 빠른 작업을 계속 실행합니다.
디스크 작업이 완료되면 결과가 메인 처리 루프로 돌아갑니다. NGINX에서는 read() 시스템 콜과 sendfile() 두 가지 작업이 쓰레드 풀로 오프로드됩니다.

모든 운영체제나 지원 서비스의 설정을 변경할 때는 하나의 설정만 변경하고 성능을 테스트해야 합니다. 변경 사항이 문제를 일으키거나 사이트 실행 속도를 빠르게 하지 않는 경우, 변경 사항을 되돌려야 합니다.
10. 실시간 활동 모니터링을 통한 문제 및 병목 현상 해결
활용 가능한 높은 성능의 애플리케이션 개발 및 배포 방식은 실제 성능을 실시간으로 지켜보는 것입니다. 특정 장치 내부와 웹 인프라 전체의 활동을 모니터링할 수 있어야 합니다.
사이트 활동 모니터링은 대부분 수동적입니다. 즉, 어떤 일이 일어나는지 알려주고 문제를 발견하고 해결하도록 하는 것입니다.
모니터링은 몇 가지 다른 종류의 문제를 포착할 수 있습니다. 여기에는 다음이 포함됩니다.
- 서버가 다운되었습니다.
- 서버의 연결이 지속적으로 끊깁니다.
- 서버에서 캐시 누락 비율이 높습니다.
- 서버가 올바른 내용을 보내지 않습니다.
New Relic 또는 Dynatrace와 같은 글로벌 애플리케이션 성능 모니터링 도구는 원격 위치에서 페이지 로드 시간을 모니터링 하는 데 도움이 되며, NGINX는 애플리케이션 전달 측면을 모니터링 하는 데 도움이 됩니다.
애플리케이션 성능 데이터는 최적화가 사용자에게 실제로 영향을 미치고 있는지, 그리고 트래픽을 유지하기 위해 인프라 용량을 추가해야 하는지 여부를 알려줍니다.
NGINX Plus는 애플리케이션 인식형 헬스 체크 (Health Checks) 를 추가하여 문제를 신속하게 식별하고 해결할 수 있도록 지원합니다.
이는 정기적으로 반복되는 합성 트랜잭션으로, 문제가 발생할 경우 알림을 보내주는 역할을 합니다.
또한 NGINX Plus는 세션 드레이닝 (Session Drainging) 기능을 갖추고 있어 기존 작업이 완료될 때까지 새로운 연결을 차단하며, 서버가 복구되면 로드 밸런싱 그룹 내에서 서버가 안정화될 때까지 출시 지연 기능을 제공합니다.
헬스 체크 기능을 효과적으로 활용하면 사용자 경험에 부정적인 영향을 미치기 전에 문제를 식별할 수 있으며, 세션 드레이닝과 출시 지연 기능은 서버를 교체하고도 인식된 성능 및 가용성에 부정적인 영향을 미치지 않도록 도와줍니다.
아래 그림은 서버, TCP 연결 및 캐시가 있는 웹 인프라에 대한 내장 NGINX Plus 실시간 활동 모니터링 대시보드를 보여줍니다.

11. NGINX 애플리케이션 성능 향상 결론
웹 애플리케이션에서 실제로 가능한 성능 향상은 상당히 다양하며, 실제 향상은 예산, 투자할 수 있는 시간 및 기존 구현의 공백에 따라 달라집니다. 그렇다면, 자신의 애플리케이션에서 10배의 성능 향상을 어떻게 달성할 수 있을까요?
각 최적화 방법이 어떤 영향을 줄 수 있는지 파악하는 데 도움을 주기 위해, 아래에 각 팁으로 가능한 개선사항을 안내합니다. 그러나 실제 개선 여부는 환경에 따라 다를 수 있습니다.
11-1. 요약
- 리버스 프록시 서버 및 로드 밸런싱 – 부적절한 로드 밸런싱 또는 로드 밸런싱이 없으면 매우 나쁜 성능 문제가 발생할 수 있습니다. NGINX와 같은 리버스 프록시 서버를 추가하면 웹 애플리케이션이 메모리와 디스크 사이에서 스래싱되는 것을 방지할 수 있습니다.
로드 밸런싱을 사용하면 과부하가 걸린 서버에서 처리를 가용한 서버로 이동시키고 스케일링을 쉽게 할 수 있습니다.
이러한 변경 사항은 현재 구현의 최악의 순간과 비교하여 10배의 성능 향상을 쉽게 달성할 수 있으며, 전반적인 성능에 대한 적지만 상당한 성과를 얻을 수 있습니다. - 동적 및 정적 콘텐츠 캐싱 – 과부하된 웹 서버가 애플리케이션 서버로 겹쳐있는 경우 동적 콘텐츠만 캐싱하면 최대 시간대의 성능을 10배 개선할 수 있습니다.
정적 파일에 대한 캐싱은 단일 자릿수 배의 성능 향상을 가져올 수도 있습니다. - 데이터 압축 – 사진의 경우 JPEG, 그래픽의 경우 PNG, 영화의 경우 MPEG-4 및 음악 파일의 경우 MP3와 같은 미디어 파일 압축을 사용하면 성능을 크게 개선할 수 있습니다.
이들이 모두 사용 중이면 코드 및 HTML과 같은 텍스트 데이터 압축도 초기 페이지 로드 시간을 2배 이상 개선할 수 있습니다. - SSL/TLS 최적화 – 안전한 핸드셰이크는 성능에 큰 영향을 미칠 수 있으므로 최적화하면 텍스트 중심 사이트의 초기 응답성을 2배 정도 개선할 수 있습니다. SSL/TLS 아래 미디어 파일 전송 최적화는 전체 사이트 성능에서 작은 성능 개선만 예상됩니다.
- HTTP/2 및 SPDY 구현 – SSL/TLS와 함께 사용될 경우 이러한 프로토콜은 전체 사이트 성능에 대한 점진적인 개선을 가져올 수 있습니다.
- Linux 및 웹 서버 소프트웨어(NGINX 등) 조정 – 버퍼링 최적화, keepalive 연결 사용 및 시간이 많이 소요되는 작업을 별도의 스레드 풀로 오프로드하는 것과 같은 수정을 통해 성능을 크게 향상시킬 수 있습니다.
예를 들어, 스레드 풀은 디스크 집약적인 작업의 속도를 거의 10배 향상시킬 수 있습니다.
이러한 기술을 직접 사용해 보시기 바랍니다. NGINX는 귀하가 달성할 수 있는 애플리케이션 성능 개선의 종류를 듣고 싶습니다.
댓글을 달려면 로그인해야 합니다.