변수는 NGINX 구성의 중요하지만 때때로 간과되는 측면입니다. 약 150개의 변수를 사용할 수 있으므로 구성의 모든 부분을 강화할 수 있는 변수가 있습니다. 이 블로그 게시물에서는 NGINX 변수를 사용하여 애플리케이션 추적 및 애플리케이션 성능 관리(APM)를 수행하는 방법을 논의합니다. 특히 애플리케이션의 성능 병목 현상을 찾는 데 중점을 둡니다. 이 게시물은 NGINX 오픈 소스와 NGINX Plus에 모두 적용됩니다. 간략하게 설명하기 위해 두 버전 사이에 차이가 있는 경우를 제외하고는 전체적으로 NGINX Plus라고 지칭하겠습니다.
샘플 애플리케이션 제공 환경에서 NGINX Plus는 애플리케이션의 역방향 프록시로 작동합니다. 애플리케이션 자체는 웹 프런트엔드로 구성되며, 그 뒤에는 여러 개의 마이크로서비스가 있습니다.
NGINX Plus R10(및 NGINX 1.11.0)은 $request_id
변수를 도입했습니다. 이 변수는 32개의 16진수 문자로 이루어진 무작위 생성 문자열로, HTTP 요청이 도착할 때마다 자동으로 지정됩니다(예: 444535f9378a3dfa1b8604bc9e05a303
). 이 기만적으로 간단한 메커니즘은 추적 및 문제 해결을 위한 강력한 도구를 제공합니다. NGINX Plus와 모든 백엔드 서비스가 $request_id
값을 전달하도록 구성하면 모든 요청을 종단 간에 추적할 수 있습니다. 이 샘플 구성은 프런트엔드 NGINX Plus 서버용입니다.
업스트림 app_server { server 10.0.0.1:80;
}
server {
listen 80;
add_header X-Request-ID $request_id; # 클라이언트로 돌아가기
location / {
proxy_pass http://app_server;
proxy_set_header X-Request-ID $request_id; # 앱 서버로 전달
}
}
요청 추적을 위해 NGINX Plus를 구성하려면 먼저 업스트림
블록에서 애플리케이션 서버의 네트워크 위치를 정의합니다. 단순화를 위해 여기서는 하나의 애플리케이션 서버
만 보여드리지만, 일반적으로 고가용성 및 부하 분산을 위해 여러 개의 애플리케이션 서버를 사용합니다.
애플리케이션 서버
블록은 NGINX Plus가 들어오는 HTTP 요청을 처리하는 방법을 정의합니다. listen
지시어는 NGINX Plus에게 HTTP 트래픽의 기본값인 포트 80에서 수신하도록 지시하지만, 프로덕션 구성에서는 일반적으로 SSL/TLS를 사용하여 전송 중인 데이터를 보호합니다 .
add_header
지시문은 $request_id
값을 응답의 사용자 정의 헤더로 클라이언트로 다시 전송합니다. 이 기능은 테스트에 유용하며, 모바일 앱과 같이 자체 로그를 생성하는 클라이언트 애플리케이션에도 유용하여 클라이언트 측 오류를 서버 로그와 정확하게 일치시킬 수 있습니다.
마지막으로 위치
블록은 전체 애플리케이션 공간( / )에 적용되고 proxy_pass
지시문은 모든 요청을 애플리케이션 서버로 프록시합니다. proxy_set_header
지시문은 애플리케이션에 전달되는 HTTP 헤더를 추가하여 프록시 요청을 수정합니다. 이 경우에는 X-Request-ID
라는 새로운 헤더를 만들고 여기에 $request_id
변수의 값을 할당합니다. 그래서 우리 애플리케이션은 NGINX Plus에서 생성한 요청 ID를 수신합니다.
$request_id
엔드투엔드 로깅애플리케이션 추적의 목표는 애플리케이션 성능 관리의 일환으로 요청 처리 라이프사이클에서 성능 병목 현상을 식별하는 것입니다. 예상치 못하거나 불합리한 지연이 발생한 경우 나중에 이를 분석할 수 있도록 처리 중에 중요한 이벤트를 기록하여 이를 수행합니다.
먼저 프런트엔드 NGINX Plus 서버를 구성하여 access_trace.log 파일에 사용되는 사용자 정의 로깅 형식인 trace
에 $request_id를
포함하도록 합니다.
log_format 추적 '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" "$http_user_agent" ' '"$http_x_forwarded_for" $request_id '; 업스트림 app_server { server 10.0.0.1; } server { listen 80; add_header X-Request-ID $request_id; # 클라이언트 위치로 돌아가기 / { proxy_pass http://app_server; proxy_set_header X-Request-ID $request_id; # 앱 서버로 전달 access_log /var/log/nginx/access_trace.log 추적 ; # 로그 $request_id } }
요청 ID를 애플리케이션에 전달하는 것은 좋지만, 애플리케이션에서 이를 활용하지 않는 한 애플리케이션 추적에 실제로 도움이 되지 않습니다. 이 예제에서는 uWSGI 가 관리하는 Python 애플리케이션이 있습니다. 애플리케이션 진입점을 수정하여 Request ID를 로깅 변수로 가져오겠습니다.
uwsgi 에서 set_logvar 가져오기 def main (environ, start_response): set_logvar ( 'requestid' , environ[ 'X_REQUEST_ID' ])
그런 다음 uWSGI 구성을 수정하여 표준 로그 파일에 요청 ID를 포함할 수 있습니다.
로그 형식 = %(addr) - %(user) [%(ltime)] "%(method) %(uri) %(proto)" %(status) %(size) "%(referer)" "%(uagent)" %(requestid)
이런 구성을 통해 이제는 여러 시스템에서 단일 요청에 연결할 수 있는 로그 파일을 생성할 수 있습니다.
NGINX의 로그 항목:
172.17.0.1 - - [2016년 8월 2일:14:26:50 +0000] "GET / HTTP/1.1" 200 90 "-" "-" "-" 5f222ae5938482c32a822dbf15e19f0f
애플리케이션의 로그 항목:
192.168.91.1 - - [2016년 8월 2일:14:26:50 +0000] "GET / HTTP/1.0" 200 123 "-" "-" 5f222ae5938482c32a822dbf15e19f0f
Splunk 와 Kibana 와 같은 도구를 사용하면 트랜잭션을 요청 ID 필드와 일치시켜 애플리케이션 서버의 성능 병목 현상을 파악할 수 있습니다. 예를 들어, 완료하는 데 2초 이상 걸린 요청을 검색할 수 있습니다. 그러나 일반 타임스탬프에서 1초라는 기본 시간 해상도는 대부분의 실제 분석에는 부족합니다.
요청을 처음부터 끝까지 정확하게 측정하려면 밀리초 수준의 정밀도를 갖춘 타임스탬프가 필요합니다. 로그 항목에 $msec
변수를 포함시키면 각 항목의 타임스탬프에 대한 밀리초 단위의 해상도를 얻을 수 있습니다. 애플리케이션 로그에 밀리초 타임스탬프를 추가하면 2초가 걸리는 요청이 아닌, 200밀리초 이상 걸리는 요청을 찾을 수 있습니다.
하지만 그때에도 우리는 전체적인 그림을 파악할 수 없습니다. 왜냐하면 NGINX Plus는 각 요청을 처리한 후에만 $msec
타임스탬프를 기록하기 때문입니다. 다행히도 밀리초 단위의 정밀도를 갖춘 NGINX Plus 타이밍 변수가 여러 개 있어서 처리 자체에 대한 더 많은 통찰력을 얻을 수 있습니다.
$request_time
– NGINX Plus가 클라이언트로부터 첫 번째 바이트를 읽을 때부터 시작하여 NGINX Plus가 응답 본문의 마지막 바이트를 보낼 때까지의 전체 요청 시간입니다.$upstream_connect_time
– 업스트림 서버와 연결을 설정하는 데 소요된 시간$upstream_header_time
– 업스트림 서버에 연결을 설정하고 응답 헤더의 첫 번째 바이트를 수신하는 사이의 시간$upstream_response_time
– 업스트림 서버에 연결을 설정하고 응답 본문의 마지막 바이트를 수신하는 사이의 시간이러한 타이밍 변수에 대한 자세한 내용은 애플리케이션 성능 모니터링을 위한 NGINX 로깅 사용을 참조하세요.
이러한 모든 고정밀 타이밍 변수를 추적
로그 형식에 포함하도록 log_format
지시문을 확장해 보겠습니다.
log_format 추적 '$remote_addr - $remote_user [$time_local] "$request" $status ' '$body_bytes_sent "$http_referer" "$http_user_agent" ' '"$http_x_forwarded_for" $request_id $msec $request_time ' '$upstream_connect_time $upstream_header_time $upstream_response_time' ;
우리가 선호하는 로그 분석 도구를 사용하여 변수 값을 추출하고 다음 계산을 수행하여 NGINX Plus가 애플리케이션 서버에 연결하기 전에 요청을 처리하는 데 걸린 시간을 확인할 수 있습니다.
NGINX Plus 처리 시간 = $request_time - $upstream_connect_time - $upstream_response_time
$upstream_response_time
의 가장 높은 값을 검색하여 해당 값이 특정 URI나 업스트림 서버와 연관되어 있는지 확인할 수도 있습니다. 그런 다음 동일한 요청 ID를 가진 애플리케이션 로그 항목과 비교하여 추가로 확인할 수 있습니다.
새로운 $request_id
변수와 일부 또는 전체 밀리초 정밀도 변수를 활용하면 애플리케이션의 성능 병목 현상에 대한 훌륭한 통찰력을 얻을 수 있으며, 무거운 에이전트와 플러그인을 사용하지 않고도 애플리케이션 성능 관리를 개선할 수 있습니다.
NGINX Plus로 애플리케이션 추적을 직접 시도해 보세요. 오늘 무료 30일 체험판을 시작하거나, 사용 사례에 대해 논의하려면 저희에게 문의하세요 .
"이 블로그 게시물에는 더 이상 사용할 수 없거나 더 이상 지원되지 않는 제품이 참조될 수 있습니다. 사용 가능한 F5 NGINX 제품과 솔루션에 대한 최신 정보를 보려면 NGINX 제품군을 살펴보세요. NGINX는 이제 F5의 일부가 되었습니다. 이전의 모든 NGINX.com 링크는 F5.com의 유사한 NGINX 콘텐츠로 리디렉션됩니다."