Clinic.js Concepts

Aiden·2023년 3월 27일
1

API 성능 측정 테스트를 위해 쓸만한 툴들을 리서치하던 중 측정 결과를 모니터링하고 간편하게 시각화해주는 Clinic.js 라는 툴을 발견하게 되었다.

테스트를 위한 API Shooting 은 autocannon 을 지원하여 CLI 로 간편하게 요청을 전송할 수 있었고, 이외에 K6, artillery 와 같은 다양한 API Testing 툴을 함께 사용하여 병렬적인 요청 혹은 램프업(Ramp-up), 램프다운(Ramp-down) 등의 다양한 상황을 재현하여 테스트할 수도 있었다.

뿐만 아니라, 부하나 병목이 발생하는 지점에 대해 Code Level 의 메트릭까지 그래프로 시각화하여 제공되기 때문에 문제 발생의 원인을 빠르고 정확하게 파악할 수 있다는 점도 큰 장점이었다.

따라서 Node 환경에서 간편하게 성능 테스트를 수행하고 자세한 결과를 받아보고 싶다면 Clinic.js 가 좋은 선택지가 될 수 있을 것이다.

오늘은 Clinic.js 의 공식문서를 읽어보며 짧게 정리한 글을 포스팅하고, 추후에 이를 참고하여 테스트를 수행, 병목 발생 지점을 실제로 개선하는 과정까지를 포스팅할 예정이다.


Clinic.js

Clinic.js 는 Node.js 애플리케이션의 다양한 성능 관련 지표를 그래프로 시각화하여 이슈를 진단하고, 병목지점을 손쉽게 찾아낼 수 있도록 아래 네 가지의 서비스를 제공하고 있다.

  • Clinic.js Doctor
  • Clinic.js Flame
  • Clinic.js Bubbleprof
  • Clinic.js Heap Profiler

Clinic.js Homepage

아래에서는 위 서비스들의 개념에 대해 정리하고, 간단한 데모 시연을 준비했다.
메트릭에 대한 자세한 설명과 이를 통한 인사이트는 공식문서에 친절하게 설명되어 있다.


🏥 Clinic.js Doctor

Node.js 애플리케이션의 성능 이슈를 진단하는 서비스

  1. 아래 네 가지의 메트릭을 시각화하여 보여준다.
  • CPU Usage (%)
  • Memory Usage (MB)
    • RSS(Resident Set Size)
    • THA(Total Heap Allocated)
    • Heap Used
  • Event Loop Delay (ms)
  • Active Handles

이 때 CPU 사용량은 멀티코어의 경우 100% 를 넘게 될 수 있으며, 특정 시점에 급격히 떨어진 CPU 사용량은 특정 I/O 작업에 의해 CPU 작업이 Block 되었을 가능성이 있다.

Memory Usage 그래프에서 RSS 는 해당 프로세스에서 할당된 모든 메모리 공간을 나타낸다. 따라서 RSS 는 항상 가장 큰 값을 가져야 하며, RSS 와 THA 의 사이는 Stack 과 같은 Non-heap memory 가 될 것이다.
Heap Used 는 할당된 Heap memory 중에서 해당 시점에 실제로 사용 중인 Heap 공간을 나타내는 지표다.

Event Loop Delay 는 특정 자바스크립트 동기 코드에 의해 Event Loop 가 Block 된 시간을 나타낸다. 이를 통해, 비효율적인 동기 코드가 애플리케이션에 존재하는지 확인할 수 있다.

마지막으로 Active Handles 는 현재 시점에 활성화된 I/O 작업의 수를 나타낸다. libuv 에 의해 수행되어 아직 결과를 기다리고 있는 비동기 작업만을 포함한다.

  1. 가장 상단의 Alert Bar 를 통해 애플리케이션의 주요 이슈를 요약하여 보여준다.

  2. Recommendations Panel 을 통해 애플리케이션 진단 결과와 Next Steps, Reference 를 보여준다.
    여기서 Next Steps 는 사용자가 취해야할 적절한 Action 을 의미한다.

    Reference 를 통해 포착된 이슈에 대한 정보를 얻을 수 있으며 개선을 위한 새로운 인사이트를 찾아낼 수도 있다.


🔥 Clinic.js Flame

Code Level 에서 애플리케이션의 Bottlenecks 혹은 Hot Function 을 찾을 수 있도록 시각화를 제공하는 서비스

  1. Flame Graph 를 통해 아래의 세 가지 정보를 제공한다.
  • 호출되는 함수 (Stack)

  • CPU 에 의해 각 함수가 관찰된 시간 (Block Width)
    CPU 점유 시간이 긴 함수일수록 각 Block 의 넓이는 넓어진다.

  • 스택의 최상단에서 각 함수가 관찰된 총 시간 (Brightness)
    스택의 최상단에서 실행되는 시간이 길수록, Block 의 밝기는 밝아진다.
    가장 오래 실행되는 함수는 첫번째, 가장 왼쪽에 표시되며, 이는 Node.js Event Loop 를 오랜 시간 Block 하고 있다는 것을 의미한다.

위 세 가지 메트릭을 통해 애플리케이션에서 서로를 호출하는 함수 간 관계, 각 함수의 CPU 점유 시간, 스택의 최상단에서 실행 중인 함수 등의 정보를 알아낼 수 있다.

  1. Info Panel 을 통해 아래 다섯가지 정보를 제공한다.
  • Stack bar
  • Selection controls
  • Search box
  • Code Info
  • Options Menu

🫧 Clinic.js Bubbleprof

Node.js 애플리케이션의 비동기 Flow 를 시각화하여, 비동기 프로세스 실행 시 Delay 를 측정하는 서비스

  1. 비동기 Operations 를 각각의 버블로 그룹화하여 시각화한다.

  2. 버블의 크기는 비동기 Operations 의 수행 시간을 나타낸다.
    더 많은 시간이 소요될수록 버블의 크기는 크게 표현된다.

  3. 버블 사이를 잇는 라인 길이는 두 Operation 간 Latency 를 나타낸다.
    Latency 가 길수록 두 버블 간 라인의 길이는 길게 표현된다.

  4. 버블 혹은 라인의 색상은 비동기 Operation 의 타입을 나타낸다.

  5. 버블 내부의 비동기 Operation 의 Stack Trace 도 제공한다.

  6. Search Bar 와 비동기 Operation 의 타임라인을 제공한다.

    Search Bar 에서는 앞선 서비스들과 동일하게, 원하는 파일 혹은 함수명으로 메트릭 결과를 필터링하여 확인할 수 있다.


🔍 Clinic.js HeapProfiler

Profiled Time 동안의 메모리 할당 정보를 Flamegraph 로 시각화하여 제공하는 서비스

  1. Flamegraph 는 크게 아래 세 가지 정보를 제공한다.
  • 호출되는 함수 (Stack)
  • 각 함수 별 할당된 메모리
  • Heap 에 많은 메모리를 할당한 함수
  1. Allocation Info, Controls, Option menu 를 제공한다.

How to use

1. Install Clinic.js

npm install -g clinic
# 설치 확인
clinic doctor --help

2. Install Autocannon

Clinic.js 가 애플리케이션을 모니터링하는 동안, 서버에 API 요청을 수행할 툴을 설치한다.
공식문서에서는 autocannon 과 함께 사용하는 방법을 소개하고 있으므로, 동일하게 autocannon 을 설치해주었다.

npm install -g autocannon
# 설치 확인
autocannon --version

3. Execution

실행 명령은 다음과 같다.

clinic doctor --on-port 'autocannon localhost:$PORT/api/url/users' -- node dist/main.js
  • clinic doctor → doctor 서비스 실행 명령
  • --on-port → 서버가 Port 를 Listening 한 뒤에, 이후 스크립트를 실행
  • $PORT → 서버가 Listening 하는 첫 번째 Port
  • -- node dist/main.js → 프로파일링 대상 서버를 실행하는 명령

다시 말해 위 명령은 총 세 가지의 프로세스를 실행하는 명령이다.

  • Clinic.js doctor
  • Autocannon
  • Node server

🔴 Caution

TypeScript 환경에서 Clinic.js 를 사용하기 위해서는 Transpiling 된 JS 파일을 타겟하여 실행하여야 한다. 따라서 dist 디렉토리 내 main.js 파일을 실행 대상 파일로 지정하였다.


명령을 실행하면, 서버가 시작되고 아래와 같은 autocannon 메트릭이 출력된다.

각 테이블은 다음과 같다.

  • 첫 번째 테이블은 Percentile 별로 Request Latency 정보를 제공한다.
  • 두 번째 테이블은 Percentile 별로 Throughput 정보를 제공한다.
    Autocannon Repository

이후, 서버는 자동으로 종료되고 Clinic.js Doctor 의 진단 결과가 담긴 HTML 페이지가 로드된다.

4. Analysis

로드된 HTML 페이지의 최상단, Issue Summary 를 확인해보면, CPU Usage 가 비정상적으로 낮은 것과 관련하여 I/O Operation 이슈가 탐지되었다는 진단 결과를 확인할 수 있다.

아래 Recommendations Panel 에서 더욱 자세한 진단 결과를 살펴볼 수 있으며, 이에 따른 Next Step 은 물론, 관련된 Reference 까지 제공하고 있다.

Clinic.js Doctor 의 진단 결과는 다음과 같다.

  • CPU Usage 가 일정하지 않고 비교적 낮은 경향을 보이고 있으므로 장시간의 비동기 작업이 존재하는 것으로 보이며, 따라서 Node.js 가 아닌 특정 I/O Operation 에 Bottleneck 이 발생했을 가능성이 있다.
  • clinic bubbleprof 명령을 통해 비동기 Delay 가 발생하고 있는지 확인이 필요하다.

이제 Doctor 의 진단 결과를 참고하여 Next Step 을 따라 문제를 파악하고, 해당 이슈를 해결하여 성능 개선을 시도할 수 있게 되었다.

Bubbleprof 나 Flame 과 같은 다른 서비스들 또한 doctor 와 동일한 명령으로 수행할 수 있다.

clinic bubbleprof --on-port 'autocannon localhost:$PORT/api/url/users' -- node dist/main.js

지금까지 Clinic.js 가 제공하는 서비스들에 대해 간단하게 정리해보았다.
각각의 메트릭으로부터 인사이트를 추출하는 과정과 이슈가 발생한 지점을 개선하는 과정은 실제로 큰 차이가 있기 때문에 별도의 포스트로 작성하기로 했다.

Clinic.js 에서 제공하는 각 메트릭들을 학습하여 그래프를 읽어내고, 문제가 되는 지점을 찾아 실제로 개선하는 연습은 그 자체로 값진 경험이고 좋은 학습 방향이 될 것 같다.

0개의 댓글