PM2란 무엇인가: Node.js 프로세스 관리 완벽 가이드

LightNode
작성자 LightNode ·

소개

프로세스 관리는 프로덕션 환경에서 Node.js 애플리케이션을 운영하는 데 있어 매우 중요한 요소이며, PM2는 이 분야에서 가장 강력하고 널리 사용되는 솔루션 중 하나로 자리 잡았습니다. 견고한 프로세스 관리자이자 프로덕션 런타임인 PM2는 현대 Node.js 생태계에서 필수 도구가 되었습니다.

PM2(Process Manager 2)는 Node.js 애플리케이션을 위해 특별히 설계된 고급 프로세스 관리자이지만, 다른 유형의 애플리케이션도 관리할 수 있습니다. 개발자와 운영팀이 애플리케이션을 효과적으로 유지하고 확장할 수 있도록 돕는 포괄적인 기능 세트를 제공합니다. 기본적인 프로세스 관리부터 고급 모니터링 기능까지, PM2는 프로덕션 환경에서 Node.js 애플리케이션을 운영할 때 직면하는 많은 문제를 해결합니다.

Node.js 애플리케이션에서 프로세스 관리의 중요성은 아무리 강조해도 지나치지 않습니다. Node.js 애플리케이션은 기본적으로 단일 스레드에서 실행되므로 충돌에 취약하며 재시작을 위해 수동 개입이 필요합니다. 또한, 현대 애플리케이션은 증가하는 부하를 효율적으로 처리하기 위해 여러 CPU 코어에 걸쳐 확장해야 합니다. 이때 PM2가 자동 프로세스 관리, 부하 분산, 모니터링 기능을 제공하여 프로덕션 수준의 애플리케이션에 필수적인 역할을 합니다.

프로덕션 환경에서 PM2는 다음과 같은 중요한 인프라 구성 요소 역할을 합니다:

  • 충돌 후 자동 애플리케이션 재시작
  • 여러 CPU 코어에 걸친 부하 분산
  • 내장 모니터링 및 로깅
  • 무중단 업데이트
  • 환경 관리
  • 프로세스 클러스터링

PM2 이해하기

정의 및 핵심 기능

PM2는 Keymetrics 팀(현재 PM2)에서 개발 및 유지하는 오픈 소스 Node.js 애플리케이션용 프로덕션 프로세스 관리자입니다. 데몬 프로세스 관리자로서 개발자가 애플리케이션을 24시간 365일 온라인 상태로 유지할 수 있도록 돕습니다. PM2는 Node.js 애플리케이션을 프로세스 관리 계층으로 감싸서 프로덕션 환경에서 애플리케이션 운영의 복잡한 측면을 처리합니다.

역사 및 개발

2013년에 처음 출시된 PM2는 프로덕션 환경에서 Node.js 애플리케이션의 증가하는 요구를 해결하기 위해 만들어졌습니다. 이후 npm에서 수백만 번 다운로드되며 Node.js 생태계에서 가장 인기 있는 프로세스 관리자 중 하나로 성장했고, 활발한 커뮤니티가 형성되었습니다. "PM2"라는 이름은 1세대 솔루션에서 얻은 교훈을 바탕으로 한 2세대 프로세스 관리자임을 의미합니다.

왜 PM2를 선택해야 할까?

Forever, Nodemon, SystemD 같은 다른 프로세스 관리자와 비교했을 때 PM2가 돋보이는 이유는 다음과 같습니다:

  1. 포괄적인 기능 세트: 기본 프로세스 관리부터 고급 모니터링 및 배포 도구까지 프로덕션 준비가 완료된 완전한 기능을 제공합니다.

  2. 활발한 개발: 정기적인 업데이트와 강력한 커뮤니티 지원으로 현대 애플리케이션 요구사항에 맞춰 지속적으로 발전합니다.

  3. 쉬운 통합: 인기 개발 도구 및 플랫폼과 원활하게 통합되어 현대 개발 워크플로우에 자연스럽게 어울립니다.

  4. 프로덕션 준비 완료: 스타트업부터 대기업까지 다양한 규모의 회사에서 검증되고 사용되고 있습니다.

주요 장점

개발팀에게 PM2가 제공하는 주요 이점은 다음과 같습니다:

  1. 간소화된 프로세스 관리: 개발자는 코드 작성에 집중하고 PM2가 프로세스 관리의 복잡함을 처리합니다.

  2. 향상된 애플리케이션 신뢰성: 자동 재시작 기능과 상태 모니터링으로 애플리케이션이 항상 온라인 상태를 유지합니다.

  3. 성능 향상: 내장된 부하 분산 및 클러스터링 기능으로 서버 자원을 효율적으로 활용합니다.

  4. 상세한 인사이트: 포괄적인 모니터링 및 로깅 기능으로 애플리케이션 동작과 성능을 투명하게 파악할 수 있습니다.

  5. 개발 워크플로우 통합: 다양한 배포 전략과 환경을 지원하며 현대 개발 워크플로우에 자연스럽게 녹아듭니다.

핵심 기능 및 역량

프로세스 관리

PM2의 프로세스 관리 기능은 그 기능의 기반을 이룹니다. 주요 프로세스 관리 기능은 다음과 같습니다:

  • 애플리케이션 데몬화: PM2는 애플리케이션을 데몬 프로세스로 실행하여 서버에서 로그아웃해도 백그라운드에서 계속 실행되도록 보장합니다.

  • 프로세스 수명주기 관리: pm2 start, pm2 stop, pm2 restart 같은 간단한 명령어로 프로세스 시작, 중지, 재시작, 재로딩을 자동으로 처리합니다.

  • 자동 재시작: 애플리케이션이 충돌하거나 예기치 않게 종료되면 PM2가 자동으로 재시작하여 최대 가동 시간을 보장합니다.

부하 분산

PM2는 여러 CPU 코어에 애플리케이션 부하를 분산하는 내장 부하 분산 기능을 제공합니다:

  • 클러스터 모드: Node.js 클러스터 모듈을 사용해 단일 명령어로 여러 인스턴스를 쉽게 생성할 수 있습니다: pm2 start app.js -i max.

  • 스마트 부하 분배: PM2는 애플리케이션의 모든 인스턴스에 요청을 자동으로 분산하여 서버 자원 활용을 극대화합니다.

  • 인스턴스 관리: 부하 요구에 따라 애플리케이션 인스턴스 수를 동적으로 조절할 수 있습니다.

로그 관리

포괄적인 로깅 기능으로 개발자가 애플리케이션 동작을 추적하고 문제를 해결할 수 있습니다:

  • 중앙 집중식 로그 관리: 모든 애플리케이션 로그가 자동으로 수집되어 중앙 위치에 저장됩니다.

  • 로그 순환: 내장 로그 순환 지원으로 로그 파일이 과도한 디스크 공간을 차지하지 않도록 합니다.

  • 실시간 로그 모니터링: pm2 logs 명령어와 다양한 필터링 옵션으로 실시간 로그를 확인할 수 있습니다.

모니터링 기능

PM2는 팀이 최적의 애플리케이션 성능을 유지할 수 있도록 강력한 모니터링 기능을 제공합니다:

  • 자원 모니터링: 각 프로세스의 CPU 사용량, 메모리 소비량 등 주요 지표를 추적합니다.

  • 성능 지표: 요청률, 응답 시간 등 애플리케이션 특화 지표를 모니터링합니다.

  • 건강 상태 점검: 정기적인 건강 상태 점검으로 애플리케이션이 정상적으로 응답하는지 확인합니다.

무중단 재로딩

PM2는 서비스 중단 없이 애플리케이션 업데이트를 가능하게 합니다:

  • 우아한 재로딩: pm2 reload 명령어로 사용자 연결을 끊지 않고 애플리케이션 코드를 업데이트합니다.

  • 롤링 재시작: 여러 인스턴스 실행 시 PM2가 롤링 재시작을 수행하여 서비스 가용성을 유지합니다.

  • 버전 관리: 애플리케이션 버전을 추적하고 문제가 발생하면 쉽게 롤백할 수 있습니다.

PM2 시작하기

설치 과정

PM2 설치는 Node 패키지 매니저(npm)를 사용해 간단히 할 수 있습니다. 전역 설치로 시스템 전체에서 PM2를 사용할 수 있습니다:

npm install pm2 -g

Yarn을 선호하는 사용자는 다음을 사용하세요:

yarn global add pm2

기본 명령어 및 사용법

PM2는 애플리케이션 관리를 위한 직관적인 명령줄 인터페이스를 제공합니다:

  1. 애플리케이션 시작:
# 기본 시작
pm2 start app.js

# 특정 이름으로 시작
pm2 start app.js --name "my-app"

# 클러스터 모드로 시작
pm2 start app.js -i 4
  1. 프로세스 관리:
# 모든 프로세스 목록 보기
pm2 list

# 애플리케이션 중지
pm2 stop app-name

# 애플리케이션 재시작
pm2 restart app-name

# 애플리케이션 삭제
pm2 delete app-name

프로세스 구성

PM2는 복잡한 배포를 위해 구성 파일(에코시스템 파일)을 지원합니다:

// ecosystem.config.js
module.exports = {
  apps: [{
    name: "my-app",
    script: "./app.js",
    instances: 4,
    exec_mode: "cluster",
    watch: true,
    env: {
      NODE_ENV: "development",
    },
    env_production: {
      NODE_ENV: "production",
    }
  }]
}

구성 파일을 사용해 애플리케이션을 시작하세요:

pm2 start ecosystem.config.js

환경 관리

PM2는 다양한 환경 구성을 쉽게 관리할 수 있게 합니다:

  1. 환경 변수:
  • 에코시스템 파일에서 환경별 변수를 설정
  • --env 플래그로 환경 전환
pm2 start ecosystem.config.js --env production
  1. 구성 파일:
  • 환경별 별도 구성 파일 유지
  • 다양한 배포 시나리오에 맞는 환경별 설정 사용
  1. 런타임 구성:
  • 실행 중 환경 변수 수정 가능
  • 재시작 없이 애플리케이션 구성 업데이트

고급 기능

클러스터 모드

PM2의 클러스터 모드는 정교한 애플리케이션 확장 기능을 제공합니다:

// 클러스터 모드 구성
module.exports = {
  apps: [{
    script: 'app.js',
    instances: 'max',     // 또는 특정 숫자
    exec_mode: 'cluster',
    instance_var: 'INSTANCE_ID',
    wait_ready: true,
    listen_timeout: 3000
  }]
}

주요 클러스터 기능:

  • 인스턴스 간 자동 부하 분산
  • 무중단 재로딩
  • 인스턴스 장애 복구
  • CPU 코어 최적화

컨테이너 통합

PM2는 컨테이너화된 환경과 원활하게 작동합니다:

  1. 도커 통합:
  • 공식 도커 이미지 제공
  • 컨테이너화된 프로세스 관리
  • 헬스 체크 엔드포인트
  • 컨테이너 인지 모니터링
  1. 쿠버네티스 지원:
  • 파드 내 프로세스 관리
  • 컨테이너 수명주기 통합
  • 자원 최적화

배포 워크플로우

PM2는 강력한 배포 기능을 제공합니다:

# 배포 구성 설정
pm2 ecosystem

# 프로덕션 배포
pm2 deploy production

# 필요 시 롤백
pm2 deploy production revert 1

배포 기능:

  • 다중 서버 배포
  • 자동화된 배포 스크립트
  • 버전 관리
  • 롤백 기능
  • 배포 전/후 훅

모니터링 대시보드

PM2는 내장 웹 인터페이스를 통해 포괄적인 모니터링을 제공합니다:

  1. 실시간 지표:
  • CPU 및 메모리 사용량
  • 요청률
  • 오류율
  • 사용자 정의 지표
  1. 시스템 모니터링:
  • 서버 상태 점검
  • 자원 활용도
  • 네트워크 통계
  • 디스크 사용량

로그 순환

고급 로그 관리 기능:

module.exports = {
  apps: [{
    name: "app",
    script: "./app.js",
    log_date_format: "YYYY-MM-DD HH:mm Z",
    error_file: "./logs/error.log",
    out_file: "./logs/out.log",
    log_file: "./logs/combined.log",
    max_size: "10M",
    max_restarts: 10
  }]
}

모범 사례

구성 권장 사항

프로덕션 환경에서 PM2를 사용할 때 다음 구성 모범 사례를 따르는 것이 중요합니다:

  1. 애플리케이션 구성:
  • 명령줄 매개변수 대신 항상 에코시스템 구성 파일 사용
  • 애플리케이션에 적절한 메모리 제한 설정
  • 적절한 오류 처리 및 로깅 구성
  • 프로세스에 의미 있는 이름 사용

잘 구성된 에코시스템 파일 예시:

module.exports = {
  apps: [{
    name: 'production-app',
    script: './app.js',
    instances: 'max',
    max_memory_restart: '1G',
    max_restarts: 10,
    watch: false,
    error_file: './logs/error.log',
    out_file: './logs/output.log',
    time: true
  }]
}

보안 고려사항

적절한 보안 조치 구현이 필수적입니다:

  1. 프로세스 권한:
  • 최소 권한으로 프로세스 실행
  • 애플리케이션별 별도 사용자 계정 사용
  • 적절한 파일 권한 설정
  1. 환경 변수:
  • 민감한 데이터를 버전 관리에 절대 커밋하지 않음
  • 환경별 구성 파일 사용
  • 안전한 비밀 관리 구현
  1. 네트워크 보안:
  • 적절한 방화벽 규칙 구성
  • 속도 제한(rate limiting) 구현
  • 안전한 통신 프로토콜 사용

성능 최적화

최대 성능을 위해 PM2 설정을 최적화하세요:

  1. 자원 관리:
  • 메모리 제한 모니터링 및 조정
  • CPU 코어에 맞는 인스턴스 수 최적화
  • 적절한 부하 분산 전략 구현
  1. 애플리케이션 확장:
  • 클러스터 모드 효과적으로 사용
  • 필요 시 수평 확장 구현
  • 부하 패턴에 따라 모니터링 및 조정

피해야 할 일반적인 실수

  1. 프로세스 관리:
  • 애플리케이션 로그 무시하지 않기
  • 너무 많은 인스턴스 실행 피하기
  • 모니터링 및 알림 소홀히 하지 않기
  1. 구성 오류:
  • 환경 변수 미설정
  • 잘못된 경로 구성
  • 오류 처리 누락
  1. 배포 문제:
  • 배포 스크립트 테스트하지 않음
  • 롤백 절차 무시
  • 배포 중 모니터링 부족
What is PM2?

자주 묻는 질문 (FAQ)

1. 파일이 변경될 때 애플리케이션을 어떻게 재시작하나요?

답변: PM2의 watch 기능을 사용할 수 있습니다:

# 명령줄에서 사용
pm2 start app.js --watch

# 또는 ecosystem.config.js에서
module.exports = {
  apps: [{
    script: 'app.js',
    watch: true,
    ignore_watch: ['node_modules', 'logs']
  }]
}

2. 특정 애플리케이션의 로그를 어떻게 볼 수 있나요?

답변: PM2는 여러 로깅 명령어를 제공합니다:

# 모든 로그 보기
pm2 logs

# 특정 앱 로그 보기
pm2 logs app-name

# 최근 N줄 보기
pm2 logs --lines 100

3. 애플리케이션이 예상보다 많은 메모리를 사용하는 이유는 무엇인가요?

답변: 여러 원인이 있을 수 있습니다:

  • 애플리케이션 내 메모리 누수
  • 너무 많은 인스턴스 실행
  • 부적절한 가비지 컬렉션

해결책: PM2의 메모리 제한 기능 사용:

{
  "name": "app",
  "script": "app.js",
  "max_memory_restart": "1G"
}

4. 개발과 프로덕션에서 다른 구성을 어떻게 실행하나요?

답변: 환경별 구성을 사용하세요:

module.exports = {
  apps: [{
    script: 'app.js',
    env: {
      NODE_ENV: 'development',
      PORT: 3000
    },
    env_production: {
      NODE_ENV: 'production',
      PORT: 80
    }
  }]
}

5. 시스템 재부팅 후 PM2를 자동 시작하려면 어떻게 하나요?

답변: startup 명령어를 사용하세요:

# 시작 스크립트 생성
pm2 startup

# 현재 프로세스 목록 저장
pm2 save

6. PM2 자체를 어떻게 업데이트하나요?

답변: 다음 단계를 따르세요:

# 최신 PM2 버전 설치
npm install pm2@latest -g

# 메모리 내 PM2 업데이트
pm2 update

7. 왜 내 Node.js 애플리케이션이 모든 CPU 코어를 사용하지 않나요?

답변: Node.js는 기본적으로 단일 스레드입니다. PM2의 클러스터 모드를 사용하세요:

# 명령줄에서 사용
pm2 start app.js -i max

# 또는 ecosystem.config.js에서
module.exports = {
  apps: [{
    script: 'app.js',
    instances: 'max',
    exec_mode: 'cluster'
  }]
}

8. 애플리케이션 성능을 어떻게 모니터링하나요?

답변: PM2의 모니터링 도구를 사용하세요:

# 기본 모니터링
pm2 monit

# 웹 기반 대시보드
pm2 plus

# 상태 개요
pm2 status

9. 애플리케이션 충돌을 어떻게 처리하나요?

답변: PM2가 충돌한 애플리케이션을 자동으로 재시작하지만, 특정 동작을 구성할 수도 있습니다:

module.exports = {
  apps: [{
    script: 'app.js',
    max_restarts: 10,
    min_uptime: "1m",
    restart_delay: 5000
  }]
}

10. 디스크 공간 문제를 방지하기 위해 로그 파일을 어떻게 순환하나요?

답변: 에코시스템 파일에서 로그 순환을 구성하세요:

module.exports = {
  apps: [{
    script: 'app.js',
    max_size: "10M",
    out_file: "./logs/out.log",
    error_file: "./logs/error.log",
    merge_logs: true,
    time: true
  }]
}