Node.js 모니터링 시스템 구축과 트러블 슈팅 사례(Part 1 — 모니터링 환경구축)

안녕하세요 NAVER BIZ CIC의 Ad Service Dev2 입니다.
저희는 네이버/라인 보장형 광고 DSP와 LINE Flyer 서비스를 담당하고 있는 조직입니다.

저희 팀에서는 여러 서비스를 운영하고 있는데요. 그중에서 오늘 다룰 내용은 Node.js 서버의 모니터링에 대해서 소개하고자 합니다.

모니터링 관련된 포스트는 총 3편에 걸쳐 다룰 예정입니다.

1. Node.js 모니터링 환경구축(VM 환경)

2. Node.js 모니터링 시스템을 활용한 트러블 슈팅

3. K8S 환경을 위한 추가 가이드

이 글은 첫 번째 글로, 저희가 운영 중인 LINE Flyer 서비스에서 사용했었던 VM 환경 기반의 Node.js 모니터링 환경 구축에 대해서 다룰 예정입니다.
(현재는 K8S로 전환 중이라 세 번째 글에서 K8S 환경에 대한 내용을 다룰 예정입니다.)

모니터링 시스템 필요성

모니터링(Monitoring)이란 어떤 대상을 감시, 관찰한다는 뜻으로써 IT 서비스에서의 모니터링 시스템이란 운영 중인 서비스를 지속적으로 감시, 관찰하여 예기치 못한 상황과 오류를 대비하고 극복을 하기 위해서 사용합니다.

모니터링에 대한 종류는 다음과 같이 4가지로 정의 할 수 있습니다.

  • 알림(Alerting) : 비정상 수치가 측정 될 시 즉시 파악
  • 디버깅(Debugging) : 비정상 수치 분석을 통한 근본 원인 규명
  • 추세 파악(Trending) : 시스템이 어떻게 사용되며 시간에 따라 변화가 되는지 확인
  • 플러밍(Plumbing) : 측정되고 있는 수치를 활용해 다른 플랫폼에서 활용(ex: K8S HPA 기준 수치에 사용)

이러한 모니터링 종류를 통하여 운영자가 얻을 수 있는 이점은 아래와 같습니다

  • 사전 분석을 통한 장애 방지
  • 장애 발생 감지를 통한 다운 타임 감소
  • 성능 문제 파악을 통한 서비스 최적화
  • 데이터 기반 분석을 통한 체계적인 관리

이와 같은 이유로 인해 모니터링 시스템은 꼭 필요하기 때문에 저희가 운영 중인 서비스에도 모니터링 시스템을 적용하게 되었으며, 상단에 설명한 대부분의 기능이 있는 프로메테우스(Prometheus)를 선택하게 되었습니다.

프로메테우스(Prometheus)?

프로메테우스(Prometheus)는 SoundCloud사에서 만든 매트릭 기반의 오픈소스 모니터링 및 알림 시스템입니다.

프로메테우스가 유일한 모니터링 도구는 아니지만, 프로메테우스는 매트릭 기반 모니터링 기능에 집중되어 있으며, 단순하지만 강력한 데이터 모델과 쿼리 언어(PromQL)가 있어 이를 활용하여 애플리케이션과 인프라 성능을 분석할 수 있습니다.

프로메테우스는 매트릭을 측정하는 것에 집중하고, 매트릭 이외에 다른 기능(ex: 시각화)은 다른 더 적절한 도구가 처리하도록 남겨 줍니다.

프로메테우스가 Target System에서 메트릭을 수집하는 방식은 풀링(Pulling) 방식을 사용합니다. 프로메테우스가 주기적으로 Exporter로부터 메트릭 읽어와서 수집하는 방식입니다.

이글에서는 프로메테우스 설치에 대한 방법을 설명하지 않으며, 프로메테우스가 설치되어있다는 가정하에 Node.js 서버와 연동하는 방법에 대해서 설명하겠습니다.

프로메테우스 Architecture

프로메테우스 Exporter란?

프로메테우스는 풀링(Pulling) 방식을 이용해서 타겟 서버의 메트릭을 수집하기 때문에, 타겟 서버에서는 프로메테우스가 인식할 수 있는 데이터 구조로 변경한 매트릭 수치들을 볼 수 있는 기능을 제공해줘야 합니다.

Exporter는 이러한 기능을 수행하며, 사용자가 직접 만들 수도 있지만, 대부분은 Third-party Exporter를 사용하며 이글에서는 Node.js와 호환되는 Exporter를 사용할 예정입니다.

프로메테우스 x Node.js

Node.js exporter 소개

prom-client (https://github.com/siimon/prom-client)

  • Node.js에서 Prometheus metric을 생성 및 집계 할 수 있도록 도와주는 라이브러리
  • 대부분의 Node.js exporter 라이브러리는 해당 라이브러리 기반으로 만들어져있습니다.

express-prom-bundle (https://github.com/jochen-schweizer/express-prom-bundle)

  • Express/koaJS 에서 exporter 관련 기능을 쉽게 커스텀 할 수 있도록 기본 Metrics 및 routing 설정이 포함된 라이브러리
  • prom-client를 기반을 통해서 만들어져 있습니다.

이글에서는 상단의 2개의 exporter 중에 express-prom-bundle 라이브러리 기반으로 샘플 코드를 작성할 예정입니다.

PM2 환경에서 Node.js에 exporter 적용시 문제점

Node.js은 Main theread는 싱글 스레드 기반이다 보니 서버에서 Node.js 인스턴스를 띄울 때는 보통 PM2(https://pm2.keymetrics.io/)라는 Node.js 프로세스 관리툴을 이용해서 cluster mode로 CPU 개수에 맞게끔 Node.js 인스턴스를 띄우는 경우가 많습니다.

그런데 PM2로 cluster mode 사용 시 Node.js exporter를 사용하게 되면 실제 수치보다 적게 측정이 되는 현상 발생합니다.

PM2 cluster mode에서 수치가 적게 측정되는 원인

하단의 “PM2 cluster mode를 통해 구성한 Node.js 서버 구성도” 이미지를 보면 프로메테우스 풀링 요청을 PM2에서 로드벨런싱하여 랜덤한 node instace에 전달이 될 수 밖에 없는 구조인 것을 확인할 수 있습니다.

PM2 cluster mode를 통해 구성한 Node.js 서버 구성도

따라서 하단 이미지처럼 서버에서 실행되고 있는 node.js 인스턴스들의 metrics을 집계할 수 있는 기능이 필요합니다.

pm2-message

PM2 환경에서 Node.js 인스턴스들의 metric들을 수집하려면 직접 구현하거나, 오픈소스 라이브러리를 사용하는 방법이 있을 수 있습니다.

저희 팀에서는 직접 구현보다는 추후 유지보수를 위해 pm2-message라는 라이브러리를 사용하는 것을 결정하였습니다.

pm2-message 라이브러리는 PM2 간의 인스턴스 통신(IPC, RPC 사용)을 통해 모든 인스턴스의 metric을 집계하는 기능을 제공하고 있습니다.

하단의 이미지에서는 pm2-message가 동작하는 방식을 설명하고 있습니다.

metric 요청을 받은 node.js 인스턴스에서 다른 인스턴스들의 metric 값들과 자신의 metric을 합쳐서 응답

pm2-message와 express-prom-bundle를 활용한 예제 코드

Custom metric 추가와 같은 커스텀 없이 기본 기능을 사용하고자 하는 분들을 위해 기본 샘플 코드를 작성하였습니다. 하단 코드를 통하여 기본기능을 빠르게 적용하실 수 있습니다.

Prometheus config에 target 서버 설정 추가

Exporter 설정이 완료가 되면 프로메테우스 서버에 Exporter 설정이 되어있는 타겟서버를 추가를 해야합니다.

해당 설정 예제는 VM에 Node.js 배포를 기준으로 작성되었습니다.
(K8S는 세번째 글에서 설명 예정입니다)

Prometheus 연동 완료

상단의 흐름대로 작업을 진행하였다면, 프로메테우스 서버와 Node.js 서버의 연동이 완료되었습니다.

프로메테우스 연동이 완료되셨다면 다음에 이어질 그라파나 시각화 플랫폼 내용을 진행하시면 시각화 그래프까지 보실 수 있습니다.

그라파나(Grafana)?

프로메테우스는 메트릭 이외에 다른 기능은 더 적절한 도구가 처리하도록 남겨 두었기 때문에 시각화 플랫폼은 그라파나 플랫폼이 필요합니다.

그라파나는 다양한 지표들의 분석을 도와주는 오픈소스 메트릭 데이터 시각화 도구로 메트릭 분석 플랫폼을 지향하고 있습니다.

이글에서는 그라파나 설치에 대한 방법을 설명하지 않으며, 프로메테우스, 그라파나가 설치되어있다는 가정하에 프로메테우스 서버와 연동하는 방법에 대해서 설명하겠습니다.

Grafana x Prometheus

1. Data Source 추가

  • Prometheus URL 입력

2. 패널에 각 metric 대한 설정 추가

  • 시각화 하고 싶은 metric을 prometheus query를 이용하여 조합

Prometheus query에 대한 자세한 설명은 https://prometheus.io/docs/prometheus/latest/querying/functions/ 를 참고

다른 사용자들이 만든 패널/대시보드 템플릿를 사용하고 싶다면?

하단의 NodeJS Application Dashboard 템플릿을 사용하면 custom metric을 제외한 대부분의 metric을 시각화해서 보여주기 때문에 처음 사용하는 사용자라면 하단 템플릿 기반으로 작업하기를 추천드립니다.

상단의 과정들을 진행하셨다면 하단과 같은 Node.js 서버 모니터링 시스템 구축이 완료가 되셨을 것으로 보입니다.

마치며

이번 글에서는 VM 환경 기반의 pm2 x Node.js 모니터링 환경 구축에 대해서 이야기했습니다.

다음 글에서는 실제 구축한 모니터링 시스템의 각각의 metric에 대한 설명과 해당 metric 들을 활용하여 Memory Leak 감지, 외부 API 오류 감지 등의 다양한 트러블 슈팅 방법을 이야기 하고자 합니다.

--

--