V8의 기능을 활용하여 Node.js 위에서 실행되는 애플리케이션의 프로파일을 얻을 수 있다.
구조
[DevTools / node inspect CLI]
│ (WebSocket, JSON-RPC)
▼
┌───────────────┐
│ node::inspector::Agent │ ← 디버거 서버 (포트 9229)
│ └─ NodeInspectorClient │ ← V8 브리지
│ └─ v8_inspector API │ ← V8 디버거 엔진
└───────────────┘
│
▼
[JS 코드 실행부]
동작
타겟 애플리케이션을 --inspect 옵션으로 실행하거나 실행 중 USR1 신호를 보내면
inspect agent 가 실행되어 9229 포트로 디버거 서버를 띄운다.
테스트 방법
- 타겟 애플리케이션 실행: node를 --inspect 옵션으로 실행하거나 실행 중 USR1 신호를 보냄
- kill -USR1 {pid}
- inspector 프로세스 실행: pid 나 host:port 를 명시하여 타겟에 attach
- node inspect [--pid {process id} | 192.168.0.10:9229 ]
- inspector 프로세스에서 profile, profileEnd 커맨드를 순차 실행 후 profiles 로 결과 파일 확인 및 저장
- profiles[{인덱스}].save('{경로}')
결과 파일 읽기
- 전체 구조
{
"nodes": [ ... ], // 함수 호출 트리 (각 노드: 함수 하나)
"samples": [ ... ], // 특정 시점에 실행 중이던 node.id
"startTime": 1093425539501,
"endTime": 1093450780167
}
- nodes 구조 (예시)
{
"id": 34,
"callFrame": {
"functionName": "(익명함수)",
"scriptId": "95",
"url": "file:///Users/jihyechoi/Documents/testcode/my-server.js",
"lineNumber": 13,
"columnNumber": 33
},
"hitCount": 697,
"children": [35, 38],
"positionTicks": [
{"line": 27, "ticks": 2},
{"line": 26, "ticks": 695}
]
}
- functionName 종류
| (idle) | 이벤트 루프가 놀고 있을 때 (대기 시간) |
| (program) | 초기 런타임 세팅 |
| (garbage collector) | GC 중 사용된 CPU |
| processTicksAndRejections | 이벤트 루프의 마이크로태스크 처리 |
| parserOnHeadersComplete | HTTP 요청 파싱 완료 콜백 |
| onconnection / Socket | TCP 연결 수락 및 스트림 설정 |
| emit | Node.js EventEmitter |
| end, _send, _writeRaw | 응답을 네트워크로 전송 중 |
| Readable.read, Writable.write | 스트림 I/O 동작 |
- samples: 샘플링 타이머가 매번 실행 중인 함수의 id를 기록한 것. 많이 등장한 id 의 함수가 CPU를 많이 점유했다는 뜻이다
'기술 조사 > Node.js' 카테고리의 다른 글
| AsyncHooks 를 이용하여 비동기작업과 콜백을 연결하기 (0) | 2025.11.12 |
|---|---|
| Node.js C++ Codebase 영한 번역 (0) | 2025.11.09 |
| Node.js 딥다이브 (2) - libuv 의 I/O 멀티플렉싱 살펴보기 (3) | 2025.05.03 |
| Node.js에서 멀티코어를 활용하기 (8) | 2025.01.01 |
| Node.js 딥다이브 (1) - JavaScript 를 "비동기"로 "실행"하기 위해 해야 할 일 (3) | 2024.11.08 |