Nginx stub_status로 서버 상태 모니터링 이해하기

조회수: 0

Nginx를 웹 프록시나 로드밸런서로 쓰다 보면 어느 순간부터 요청이 쌓이는지, 동시 접속이 얼마나 올라왔는지 빠르게 확인해야 할 때가 많다. 이때 로그를 열어보거나 별도 에이전트를 까는 대신, Nginx가 기본으로 제공하는 stub_status 모듈만 잘 활용해도 의외로 많은 정보를 얻을 수 있다.
stub_status 모듈은 Nginx 프로세스가 관리하는 전체 HTTP 연결과 요청에 대한 기본적인 통계를 간단한 텍스트 페이지로 제공하는 역할을 한다.(nginx.org)

단일 서버뿐 아니라 여러 대의 Nginx 서버를 운영할 때도 공통된 상태 페이지를 만들어 두면, 장애 징후를 빠르게 감지하고 모니터링 도구와 연동하기가 훨씬 수월해진다.

stub_status 모듈이 하는 일

stub_status 모듈을 켜면 특정 URL에 접속했을 때 Nginx의 현재 상태를 요약한 짧은 텍스트를 돌려준다. 여기에는 대략 다음과 같은 정보가 들어 있다.(nginx.org)

  • 현재 활성 연결 수
  • 지금까지 처리한 연결과 요청 수
  • 요청을 읽는 중인 연결 수
  • 응답을 쓰는 중인 연결 수
  • 다음 요청을 기다리는 keep alive 연결 수

이 정보만으로도

  • 동시 접속이 급격히 늘어나는지
  • 요청이 제대로 처리되고 있는지
  • 특정 시점에 서버가 버거워하는지

를 빠르게 감지할 수 있다. 무엇보다 응답이 단순 텍스트라서 curl 한 번만 날려도 쉽게 파싱할 수 있고, 여러 모니터링 도구에서 기본으로 지원한다.(Elastic)

stub_status 모듈 활성화 여부 확인

stub_status는 모든 빌드에 무조건 포함되는 모듈은 아니다. 소스에서 직접 컴파일했다면 configure 옵션에 http_stub_status_module을 넣어야 한다.(nginx.org)

현재 Nginx가 이 모듈을 가지고 있는지 확인하려면 다음 명령으로 빌드 옵션을 확인하면 된다.

nginx -V 2>&1 | grep with-http_stub_status_module
  • 결과에 with-http_stub_status_module 문자열이 보이면 모듈이 포함된 것이다.
  • 아무것도 출력되지 않는다면 소스를 다시 컴파일해야 한다. 이때 configure 옵션에 with-http_stub_status_module을 추가하면 된다.(support.huaweicloud.com)

배포판에서 제공하는 패키지 Nginx를 설치했다면 대부분 이 모듈이 이미 포함되어 있는 경우가 많아 위 명령으로 쉽게 확인할 수 있다.(Customer Self-Service Portal)

Nginx 설정 파일에 stub_status 추가

모듈이 활성화되어 있다면 이제 상태 페이지를 열어 줄 location 블록만 하나 만들어 주면 된다. 기본적인 예시는 다음과 같다.(nginx.org)

server {
    listen 80;
    server_name example.com;

    location /nginx_status {
        stub_status;
        allow 127.0.0.1;
        deny all;
        access_log off;
    }
}

핵심은 세 가지 정도다.

  • location 경로
    보통 nginx_status 혹은 status 같은 짧은 경로를 쓴다. 운영 환경에서는 외부에 노출하고 싶지 않다면 내부망에서만 접근 가능한 별도 서버 블록을 두는 것도 방법이다.(Google Cloud Documentation)
  • stub_status 디렉티브
    on 없이 쓰더라도 최신 문서 기준으로는 해당 location에서 상태 페이지를 활성화하는 역할을 한다.(nginx.org)
  • allow deny로 접근 제한
    상태 정보를 아무나 볼 수 있도록 열어 두는 것은 보안상 좋지 않다. 최소한 루프백이나 내부 모니터링 서버 IP만 허용하도록 막는 편이 안전하다.(O’Reilly Media)

설정을 저장했다면 nginx -t로 문법을 검사하고, 문제가 없으면 서비스를 재시작하거나 reload 해서 적용하면 된다.

stub_status 출력 항목 해석

이제 브라우저나 curl로 nginx_status 경로를 호출하면 짧은 상태 정보가 나온다. 출력 형식은 텍스트 몇 줄뿐이지만, 각 숫자를 어떻게 해석하느냐에 따라 얻을 수 있는 정보가 달라진다. 대표적인 항목을 하나씩 살펴보면 다음과 같다.(sysdig.com)

Active connections 값 읽기

가장 위에 있는 Active connections 행은 현재 Nginx 프로세스가 관리 중인 전체 연결 수다. 여기에는

  • 요청을 처리 중인 연결
  • 요청을 기다리는 keep alive 연결
  • 헤더를 읽는 중인 연결

이 모두 포함된다.

평소 트래픽이 안정적인 서비스라면 시간대별로 이 값의 범위가 어느 정도인지 감을 잡아 두는 것이 중요하다. 갑자기 평소의 두세 배 이상으로 튀어 오른다면

  • 특정 캠페인이나 외부 유입 증가
  • 슬로우 백엔드로 인해 처리 지연
  • 악성 트래픽 혹은 간단한 디도스

같은 상황을 의심해 볼 수 있다. 반대로 요청 수는 크게 늘지 않았는데 Active connections만 비정상적으로 높아져 있다면 연결이 끊기지 않고 쌓이고 있다는 의미일 수도 있다.

accepts handled requests 의미

중간에 세 숫자가 한 줄에 찍힌다. 순서대로

  • accepts
  • handled
  • requests

를 뜻한다.(sysdig.com)

  • accepts는 Nginx가 소켓 레벨에서 받아들인 전체 연결 수
  • handled는 실제로 처리까지 이어진 연결 수
  • requests는 HTTP 요청 수

를 의미한다.

일반적인 운영 환경에서는 accepts와 handled 값이 거의 같게 간다. handled가 유난히 적다면 커넥션 제한이나 에러 처리로 인해 연결을 곧바로 닫는 경우가 많다는 뜻이 될 수 있다.

requests는 keep alive 환경에서 특히 의미가 크다. 하나의 연결에서 여러 요청을 처리하므로 연결 수보다 요청 수가 더 빠르게 증가하는 것이 자연스럽다. 일정 기간 동안 requests 증가량을 나눠 초당 요청 수를 대략 계산해 보는 것도 트래픽 추세를 파악하는 좋은 방법이다.

Reading Writing Waiting 상태 구분

마지막 줄에는 Reading Writing Waiting 세 값이 표시된다.(sysdig.com)

  • Reading은 클라이언트로부터 요청 헤더를 읽는 중인 연결 수
  • Writing은 클라이언트에게 응답을 쓰는 중인 연결 수
  • Waiting은 요청을 다 처리한 뒤 다음 요청을 기다리는 keep alive 상태의 연결 수

로 볼 수 있다.

운영하면서 자주 보게 되는 패턴은 다음과 같다.

  • Writing이 비정상적으로 크고 Active connections도 높다면
    백엔드 응답 지연이나 느린 클라이언트 때문에 응답을 오래 보내고 있을 확률이 크다.
  • Reading이 많으면서 CPU 사용률이 기대보다 높지 않다면
    느린 업로드나 대용량 요청으로 인해 요청을 받는 데 시간이 오래 걸리는 상황일 수 있다.
  • Waiting이 지나치게 많다면
    keep alive 설정이 과도하게 긴지, 혹은 프론트단 로드밸런서와의 연결 정책을 조정해야 하는지 검토해 볼 수 있다.

이 값들을 시계열로 모아 보면 Nginx가 어디에서 시간을 보내는지, 병목이 어느 구간에서 발생하는지 시각적으로 파악하기 좋다.

보안을 고려한 stub_status 위치 설계

stub_status 페이지는 내부 정보를 적나라하게 보여주기 때문에 접근 제어 없이 외부에 열어 두는 것은 피하는 편이 좋다. 실제 운영 환경에서는 보통 아래 패턴 중 하나를 선택한다.(Google Cloud Documentation)

  • 루프백에서만 접근 허용
    allow 127.0.0.1을 두고 모니터링 에이전트는 로컬에서만 호출한다. 컨테이너 환경에서는 사이드카나 에이전트가 같은 네임스페이스에서 호출하게 구성한다.
  • 별도 내부 전용 서버 블록
    사내 모니터링용 도메인이나 내부망 전용 IP에 server 블록을 만들어 해당 블록에서만 stub_status를 연다.
  • 방화벽과 함께 이중으로 차단
    Nginx 설정에서 allow deny로 한 번, 외부 방화벽에서 모니터링 서버만 접근하도록 한 번 더 제한한다.

상태 페이지는 응답이 매우 가벼워 공격 표면이 크지는 않지만, 트래픽 패턴을 노출할 수 있다는 점에서 가급적 내부에서만 접근하도록 설계하는 편이 안전하다.

모니터링 도구와 stub_status 연동 방법

stub_status의 가장 큰 장점은 포맷이 단순해서 여러 모니터링 도구에서 기본으로 지원한다는 점이다. 예를 들어

  • Elastic Metricbeat의 nginx stubstatus 메트릭셋
  • 구글 Cloud Logging 에이전트
  • Zabbix 템플릿
  • Prometheus용 Nginx Exporter

등이 모두 stub_status 페이지를 주기적으로 긁어 와서 그래프로 보여주고 알람을 낼 수 있도록 지원한다.(Elastic)

직접 연동할 때는 보통 다음 흐름으로 진행한다.

  1. 상태 페이지 URL을 확정하고 접근 제어를 설정한다.
  2. 모니터링 에이전트에서 해당 URL을 주기적으로 호출하도록 설정한다.
  3. Active connections나 Writing 값이 특정 기준을 넘으면 알람을 보내도록 임계치를 정한다.
  4. 요청 수 증가량을 기반으로 초당 요청 수, 분당 요청 수 같은 파생 지표를 만들어 대시보드에 노출한다.

단일 서버에서만 봐도 유용하지만, 여러 Nginx 인스턴스의 stub_status를 한 화면에 모아 보면 어떤 노드에 부하가 집중되는지 금방 드러난다.

장애 분석에서 stub_status 활용 팁

실제 장애 상황에서 stub_status는 로그보다 먼저 확인해 볼 만한 빠른 체크 포인트가 된다. 예를 들어

  • 사이트가 느리다고 신고가 들어왔을 때
    nginx_status를 열어 Active connections와 Writing 값을 먼저 본다. Writing이 평소보다 많이 올라가 있으면 백엔드를 의심하고, Reading이 높으면 업로드나 클라이언트 쪽 문제도 함께 살펴본다.
  • 간헐적인 타임아웃이 발생할 때
    타임아웃이 발생하는 시간대에 stub_status 값을 수집해 보면, 특정 시간대에만 연결 수가 폭주하는지, 아니면 전체적으로 천천히 쌓이는지 패턴이 보인다.
  • 로드밸런서 뒤의 여러 Nginx 노드 중 한 대만 느려질 때
    각 노드의 Active connections와 Waiting 값만 비교해 봐도 어느 노드에 세션이 몰려 있는지 쉽게 알 수 있다. 세션 스티키 정책이나 헬스체크 상태를 함께 점검해 볼 수 있다.

중요한 것은 평소에도 주기적으로 값을 모으면서 정상 범위를 눈에 익혀 두는 것이다. 그래야 실제 문제가 발생했을 때 숫자가 어느 정도면 비정상인지 바로 감이 온다.

마무리 정리

Nginx stub_status는

  • 별도 에이전트 설치 없이
  • 단순한 텍스트 페이지 한 개만으로

현재 서버의 연결 수와 요청량을 가볍게 들여다볼 수 있는 도구다.

모듈이 활성화되어 있는지 확인하고, 제한된 경로에 stub_status location을 하나 만들어 두는 것만으로도 기본적인 Nginx 모니터링 체계를 갖출 수 있다. 그 위에 모니터링 시스템을 올리면 지표를 시계열로 분석하고 알람까지 설정할 수 있다.

평소 stub_status 지표를 꾸준히 관찰하면서 트래픽 패턴과 정상 범위를 익혀 두면, 어느 날 갑자기 서버가 느려졌을 때도 숫자 몇 개만 보고 대략적인 상황을 빠르게 짚어낼 수 있다. 이것이 결국 안정적인 웹 서비스 운영으로 이어진다.