[Node.js] PM2(Process Manager) 알아보기
현재 회사에서 운영 중인 프로젝트들 모두 PM2를 이용해 프로세스를 관리하고 있다. PM2 는 코드를 작성하는 데에 직접적인 영향을 주지 않아서 필자는 큰 관심을 가지지 않고 있었고, 타 팀원이 설정해둔 그대로 사용하고 있었다.
그러던 와중에 해당 팀원이 퇴사를 했고(..😭) PM2가 원인으로 생각되는 이슈가 발생해 겸사겸사 공부하게 됐다. 이번 글에서는 이번에 알게 된 PM2 관련 지식을 정리하고자 한다.
PM2란?
PM2 홈페이지에서는 PM2를 다음과 같이 정의하고 있다.
PM2 is a daemon process manager that will help you manage and keep your application online. Getting started with PM2 is straightforward, it is offered as a simple and intuitive CLI, installable via NPM.
PM2는 Node.js 어플리케이션을 쉽게 관리할 수 있게 해주는 Process Manager이다. Node.js 어플리케이션을 cluster mode 로 실행시킨다거나, 메모리가 넘친다거나, 오류로 인해 프로세스가 종료되는 등의 상황에 직면했을 때 각각의 상황을 사용자가 모두 신경 써서 처리해줄 수도 있지만, 너무 복잡하고 신경 써야 할 일들이 많아진다.
PM2를 이용하면 간단한 설정만으로도 이러한 처리를 손쉽게 해결할 수 있다.
PM2 cluster mode
PM2의 cluster 모드는 Node.js의 cluster module을 이용해 기본적으로 싱글 스레드인 Node.js를 멀티 스레드로 구동시켜준다.
싱글 스레드의 경우 구동 중인 서버의 CPU 개수와 상관없이 1개만 사용할 수 있기에 서버의 성능을 제대로 끌어내지 못한다. 반면, 멀티 스레드는 최대 서버 CPU 수만큼(하이퍼스레딩을 지원한다면 x2) 프로세스를 생성해 최대 성능을 끌어낼 수 있다.
PM2에서 cluster mode를 사용하기 위해서는 다음과 같이 설정해주면 된다.
// ecosystem.config.js
module.exports = {
apps : [{
script : "app.js",
instances : "max", // 실행시킬 프로세스의 갯수(max로 입력할 경우 최대 갯수로 설정한다.)
exec_mode : "cluster" // cluster 모드로 어플리케이션을 구동시킨다.
}]
}
PM2 start
PM2 프로세스를 시작하기 위해서는 pm2 start script or 설정 파일명
명령어를 사용하면 된다. 위에서 설정한 값을 기준으로 프로세스를 시작하면 아래 결과를 얻을 수 있다.
➜ pm2 git:(master) ✗ pm2 start ecosystem.config.js
[PM2] Spawning PM2 daemon with pm2_home=/Users/armadillo.ko/.pm2
[PM2] PM2 Successfully daemonized
[PM2][WARN] Applications app not running, starting...
[PM2] App [app] launched (4 instances)
┌─────┬────────┬─────────────┬─────────┬─────────┬──────────┬────────┬──────┬───────────┬──────────┬──────────┬──────────┬──────────┐
│ id │ name │ namespace │ version │ mode │ pid │ uptime │ ↺ │ status │ cpu │ mem │ user │ watching │
├─────┼────────┼─────────────┼─────────┼─────────┼──────────┼────────┼──────┼───────────┼──────────┼──────────┼──────────┼──────────┤
│ 0 │ app │ default │ 0.0.0 │ cluster │ 15660 │ 0s │ 0 │ online │ 17% │ 33.9mb │ arm… │ disabled │
│ 1 │ app │ default │ 0.0.0 │ cluster │ 15661 │ 0s │ 0 │ online │ 21% │ 38.1mb │ arm… │ disabled │
│ 2 │ app │ default │ 0.0.0 │ cluster │ 15663 │ 0s │ 0 │ online │ 12% │ 31.3mb │ arm… │ disabled │
│ 3 │ app │ default │ 0.0.0 │ cluster │ 15668 │ 0s │ 0 │ online │ 0% │ 26.5mb │ arm… │ disabled │
└─────┴────────┴─────────────┴─────────┴─────────┴──────────┴────────┴──────┴───────────┴──────────┴──────────┴──────────┴──────────┘
총 4개의 프로세스가 실행된 것을 확인할 수 있는데, 이건 필자 컴퓨터의 CPU가 듀얼코어이면서 하이퍼 스레딩을 지원하기 때문이다.
시작 시점에 다양한 설정을 할 수 있는데, 이 링크를 참고하면 좋다.
PM2 모니터링
실행된 PM2 프로세스를 모니터링 하려면 pm2 monit
명령어를 입력하면 된다. 해당 명령어를 실행하면 아래 항목들을 실시간으로 확인할 수 있다.
- 각 프로세스의 메모리, CPU 사용률, 현재 상태
- 선택된 프로세스의 로그
- 전체 프로세스의 Heap 사이즈, 사용률
- 어플리케이션 정보
필자는 주로 부하 테스트를 수행할 때 메모리와 CPU 사용량이 어느정도까지 올라가는지 체크하는 용도로 사용하고 있다.
➜ pm2 git:(master) ✗ pm2 monit
┌─ Process List ─────────────────────────────────┐┌── app Logs ────────────────────────────────────────────────────────────────────────────────────────────────────┐
│[ 0] app Mem: 35 MB CPU: 0 % online ││ app > Hello world! │
│[ 1] app Mem: 36 MB CPU: 0 % online ││ app > Hello world! │
│[ 2] app Mem: 35 MB CPU: 0 % online ││ app > Hello world! │
│[ 3] app Mem: 38 MB CPU: 0 % online ││ app > Hello world! │
│ ││ app > Hello world! │
│ ││ app > Hello world! │
│ ││ app > Hello world! │
│ ││ app > Hello world! │
│ ││ app > Hello world! │
│ ││ app > Hello world! │
│ ││ app > Hello world! │
│ ││ app > Hello world! │
│ ││ app > Hello world! │
└────────────────────────────────────────────────┘└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
┌─ Custom Metrics ───────────────────────────────┐┌─ Metadata ───────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Heap Size 9.86 MiB ││ App Name app │
│ Heap Usage 75.65 % ││ Namespace default │
│ Used Heap Size 7.46 MiB ││ Version 0.0.0 │
└────────────────────────────────────────────────┘└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
left/right: switch boards | up/down/mouse: scroll | Ctrl-C: exit To go further check out https://pm2.io/
PM2 reload
PM2 워커 프로세스를 임의로 재시작하거나 특정 조건에서 재시작 시킬 수 있다. 이 때 PM2는 무중단 재시작을 지원한다.
As opposed to restart, which kills and restarts the process, reload achieves a 0-second-downtime reload.
임의로 재시작
pm2 reload all | app-name | process-id
명령어를 통해 재시작이 가능하다. 모든 프로세스, 특정 어플리케이션, 특정 프로세스 아이디를 이용해 재시작이 가능하다.
메모리 limit 재시작
임의 재시작 외에도 프로세스의 메모리가 지정된 제한선을 넘어서면 자동으로 reload시킬 수 있다. 필자가 관리중인 서비스도 모두 메모리 제한을 설정해 두었다.
// ecosystem.config.js
module.exports = {
apps : [{
script : "app.js",
instances : "max",
exec_mode : "cluster",
max_memory_restart: '300M' // 프로세스의 메모리가 300MB에 도달하면 reload 실행
}]
}
PM2를 이용한 무중단 배포
이 부분은 LINE의 기술 블로그에 잘 정리되어 있어 링크를 공유한다.
Comments