CDN 에서 NGINX와 업스트림 서버 간의 트래픽 로깅
해당 포스트에서는 CDN 에서 NGINX 와 업스트림 서버 간 로깅 의 역할을 다룹니다. 로깅은 인터넷 통신에서 흔히 발생하는 다양한 문제를 찾는데 필수적인 도구를 제공합니다.
CDN, 혹은 실행 중인 플랫폼에 관계없이 로깅은 빅데이터 처리, 통계, 감사, 클라이언트 보고서 및 트랜잭션은 물론 Client-Server 통신 및 가능한 문제 디버깅을 위한 핵심 요구 사항인 경우가 많습니다.

클라이언트와 웹 서버 간의 직접 연결을 통한 로깅
Client-Web Server 통신의 로깅은 브라우저 버전, 클라이언트의 네트워크 및 액세스 중인 파일과 관련된 가능한 문제를 디버깅 하는데 큰 도움이 됩니다. 그러나 여기서 끝이 아닙니다.
전적으로 플랫폼과 요구 사항에 따라 로깅할 내용은 무한한 가능성이 있습니다.
목차
1. NGINX의 CDN 로깅 아키텍처
2. 업스트림 CDN 로깅 솔루션
3. 업스트림에서 로깅 된 값
4. 발생한 문제
5. CDN 77에서 사용되는 NGINX 기능
6. 결론
6-1. CDN 77 소개
1. NGINX의 CDN 로깅 아키텍처
리버스 프록시, 로드 밸런서 또는 CDN (Content Delivery Network, 콘텐츠 전송 네트워크)을 실행할 때는 클라이언트와 서버 사이의 통신 흐름에 또 다른 노드를 추가합니다.
리버스 프록시와 같이 데이터를 조작하는 중간 서버는 종종 예기치 못한 문제를 발생시킬 수 있습니다.
NGINX 는 리버스 프록시로서 클라이언트와 웹 서버 (또는 다른 애플리케이션 서버) 사이의 연결을 클라이언트에서 연결을 종료하고 서버로의 새 연결을 생성하여 두 개의 개별 연결로 변환합니다.
두 개의 연결로 “분할” 하면 로깅을 위한 두 개의 개별 Context도 생성되며 NGINX 는 약간 다르게 로깅을 지원합니다.
- 클라이언트와 리버스 프록시 간의 트래픽에 대해서는 NGINX가 에러 로그(Error Log)와 액세스 로그(Access Log)를 모두 제공합니다.
액세스 로그는 에러가 아닌 처리 이벤트와 동작을 기록합니다. - 에러 로그는
error_log
지시문을 사용하여 활성화할 수 있으며, 기록할 에러의 심각도 수준을 설정할 수 있습니다. - 액세스 로그는
access_log
지시문을 사용하여 활성화할 수 있습니다. 관련된 log_format 지시문을 사용하면 로그에 포함될 정보의 종류와 로그 항목의 형식을 사용자 정의할 수 있습니다. 로그를 파일 또는syslog
에 작성할 수 있습니다. - 리버스 프록시와 CDN, 웹 또는 앱 서버(NGINX에서 업스트림 서버라고 함) 간의 트래픽에 대해서는 NGINX가 에러 로그를 지원합니다. 그러나 이 트래픽에 대한 액세스 로깅은 지원하지 않습니다.
- 프록시 서버와 업스트림 서버 간의 에러가 아닌 이벤트를 확인하기 위해서는 에러 로그에서 심각도 수준을 디버그로 설정해야 합니다.
이 설정의 단점은 대량의 데이터가 로그로 기록된다는 점입니다. 이로 인해 요청 처리 속도가 느려지고, 매우 큰 파일이 생성되어 저장 공간을 빠르게 차지할 수 있습니다. (디버깅 지원이 기본적으로 활성화되지 않으므로 configure 명령에 –with-debug 인자를 사용하여 NGINX를 다시 컴파일해야 함에 유의해야 합니다.)
2. 업스트림 CDN 로깅 솔루션
CDN 제공 업체로서, NGINX는 종종 업스트림 서버와 리버스 프록시 서버, 그리고 클라이언트 간의 올바른 통신이 이루어지지 않는 경우를 마주칩니다.
에러 로그의 디버그 수준 메세지만으로는 업스트림 서버와 관련된 문제를 해결하는 데 필요한 정보를 항상 제공하지 못하는 경우가 있습니다.
이러한 CDN 문제에 대한 해결책은 상당히 명확했습니다.
리버스 프록시와 업스트림 서버 간의 통신에서 핵심 정보만을 수집하는 기능을 추가하여 업스트림 액세스 로그를 생성하는 것입니다.

일반적인 아이디어는 NGINX가 업스트림 서버로의 요청이 이루어질 때마다 NGINX의 함수를 호출하도록 하는 것입니다.
이를 통해 NGINX는 업스트림 로깅 과 관련된 모든 로직을 함수 자체에 프로그래밍 할 수 있습니다.
표준 ngx_http_upstream_module
은 업스트림 요청을 처리하며, 함수를 호출하는데 필요합니다.
해당 모듈은 이러한 기능을 지원하지 않으므로 필요할 때 콜백을 활성화하도록 패치했습니다.
로깅 자체는 패치된 업스트림 모듈에 추가한 로그 콜백 기능을 사용하는 별도의 모듈에서 처리됩니다.
새 모듈은 로깅 기능을 구성하기 위해 upstream_log
지시어를 정의합니다.
이 지시어는 access_log
지시어와 동일한 parser를 사용하므로 데이터는 파일에 기록되거나 소켓을 통해 syslog 서버로 전송할 수 있습니다.
NGINX가 부팅 중 nginx.conf에서 upstream_log 지시어를 읽을 때 두 개의 함수가 호출됩니다.
ngx_http_upstream_log_set_log
은 지시어를 구문 분석하고,ngx_log_set_log
을 내부적으로 사용하여 로그 구조체(ngx_log_t) 자체를 준비합니다.- 후처리 단계에서
ngx_http_upstream_log_init
함수가 호출되며, 이 함수는 주요 로깅 함수를 업스트림 모듈에 등록합니다.
이렇게 하면 요청이 업스트림으로 프록시 되어야 할 때 모든 것이 준비됩니다.
업스트림 모듈은 업스트림 서버에 대한 연결을 시작하고, 패치된 부분은 로깅 함수가 호출되어 요청 세부 정보를 기록합니다.
로그 형식은 업스트림 모듈에 고정되어 있습니다. log_format
지시문을 사용하여 구성에 대한 지원을 추가할 수 있는 옵션도 있지만, 해당 사용 사례에는 필요하지 않습니다.
3. 업스트림에서 로깅 된 값
로깅 기능은 업스트림 서버와의 연결이 종료된 직후에 호출됩니다. 인수는 현재 처리된 요청(ngx_http_request_t
구조)에 대한 포인터로, 함수가 구조의 모든 데이터에 액세스하고 기록할 수 있도록 합니다. 업스트림 필드(ngx_http_upstream_t
에 대한 포인터)는 업스트림 요청에 대한 데이터를 포함하므로 특히 중요합니다.
NGINX는 주로 다음과 같은 정보에 관심이 있습니다.
- Origin 응답 상태 코드
- 요청의 지속 시간
- 응답 또는 호스트 헤더의 HTTP 헤더 값
전체 요청 구조에 대한 액세스는 다양한 정보를 기록할 수 있기 때문에 모듈 유연성을 제공합니다.
4. 발생한 문제
처음에는 ngx_http_core_module
에 기능을 구현했습니다. 이는 프로토타입에는 충분했지만, 향후 업데이트와 수정을 복잡하게 만들 수 있는 깔끔하지 않은 해결책이었습니다. 결국, 업스트림 로깅 함수를 독립적인 모듈로 분리했습니다.
물론 구현상의 문제도 있었습니다. 특히 ngx_snprintf
대신 C 라이브러리 함수 sprintf
를 사용하는 등 일부 위치에서 ngx_str_t
문자열을 잘못 처리했습니다. 이로 인해 정의되지 않은 데이터가 업스트림 로그에 기록되거나 Worker 스레드에서 세그먼트 에러가 발생할 수 있습니다. 이러한 문제는 Valgrind 및 AddressSanitizer와 같은 도구를 사용한 광범위한 디버깅 및 테스트 후에 해결되었습니다.
5. CDN 77에서 사용되는 NGINX 기능
CDN 77이 NGINX를 사용하는 주된 이유는 캐싱 기능 때문입니다. CDN 서버는 클라이언트와 웹 서버(업스트림 서버) 사이에 도입된 노드로, 클라이언트 요청을 전달하고 업스트림 서버에서 적절한 파일을 요청합니다.
파일이 캐시되면 동일한 위치에서 동일한 파일을 요청하는 다른 사용자에게 전달됩니다.
“로컬 서비스 파일”은 NGINX가 요청을 수신할 때 서버의 디스크에서 파일을 제공하도록 하기 위해 사용하는 기능 중 하나입니다.
보안 캐싱을 위해서는 몇 가지 추가 기능과 구성이 필요합니다.
컨텐츠를 적절하게 보호하기 위해 특정 IP 주소에 대해 생성할 수 있는 SSL(TLS 1.3 with 0-RTT) 또는 보안 토큰을 사용합니다.
우리가 사용하는 다른 기능에는 클라이언트에 대한 사용자 정의 에러 페이지, OCSP 스테이플링의 기본 NGINX 구현, 필요한 PHP 프로세스 수를 줄이기 위한 PHP용 FastCGI가 포함됩니다.
6. 결론
업스트림 로깅은 다양한 문제를 디버깅하는데 도움이 되었을 뿐만 아니라 NGINX의 핵심 기능에 대해 더 깊이 파고들 수 있는 좋은 기회를 제공했으며 NGINX가 수행한 수많은 다른 프로젝트를 단순화했습니다.
6-1. CDN 77 소개
CDN 77은 전 세계적으로 콘텐츠를 보다 효율적이고 편리하게 제공합니다.
30개 이상의 데이터 센터를 통해 전 세계에서 콘텐츠를 효과적으로 캐싱하고 제공할 수 있습니다. 여기에는 웹 사이트의 정적 콘텐츠, 소프트웨어 배포, 주문형 비디오 (VoD) 및 전용 스트리밍 엔진을 사용하는 HLS 또는 MPEG-DASH와 은 다양한 프로토콜을 통한 라이브 스트리밍이 포함됩니다.
아래 뉴스레터를 구독하고 NGINX STORE의 최신 소식들을 발 빠르게 받아보세요.
댓글을 달려면 로그인해야 합니다.