ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • PM2를 이용하기 전 학습(클러스터, 모니터링)
    Node.js 2021. 6. 15. 10:11

    먼저 PM2가 무엇일까요?

    PM2는 Node.js 애플리케이션의 프로세스 관리를 위해 사용하며, 아래와 같은 이점을 얻을 수 있습니다.

     

    • 프로그램의 예상치 못한 종료 시 자동 재시작
    • 무중단 서비스
    • Cluster mode
    • Monitoring

     

    노데몬과 같이 소스 수정에 감지하여 자동 리컴파일 하기

     

    ## pm2 start ./ecosystem.config.js --watch  

     

     

     

    상태 확인

    돌아가는 상태를 확인하고 싶다면 status 명령을 사용하면 되고

    프로세스 삭제

    돌아가고 있는 프로세스를 죽이고 싶다면 delete 명령어에 프로세스 id를 찍어주면 된다.

    kill로 다 죽일 수도 있다.

    클러스터 모드

    근데 저렇게 실행만 해서는 별 의미가 없다.

    그럼 fork모드로만 실행이 되는데, 그대로 싱글스레드로만 동작하기 때문이다.

    코어들을 최대한 활용하기 위해서는 클러스터 모드로 실행해야 하는데, 그러면 전용 설정파일을 추가해야 한다.

    이름은 무조건 ecosystem.config.js여야 한다.

    그리고 대강 다음과 같이 작성해주면 된다.

    pm2로 원래 소스파일이 아니라, 이 설정파일을 실행시키고, 이 설정파일에서 script로 원래 소스파일을 넣어주는 것이다.

    이 상태로 다시 config 파일을 실행시키면

    이제 제대로 동작한다!

    프로세스 추가

    나는 욕심이 많아서 프로세스를 더 뽑게 하고 싶다! 하면 scale 명령어를 사용하면 된다.

    이렇게 하면 myapp에 프로세스를 2개 추가할 수 있다.

     

     

    무중단 배포를 하고 싶다면 pm2로 reload를 하면 된다고 했었다.

    reload의 무중단 배포는 다음과 같은 과정으로 이루어진다.

    1. 기존에 존재하던 프로세스를 old_app으로 이동시킨다. 일단은 계속 동작한다.

    2. 새로 적용된 코드로 새 프로세스 new_app을 올린다. (ready)

    3. 이제부터 들어오는 요청은 new_app으로만 들어온다.

    4. 하지만 old_app도 남은 처리를 하긴 해야 서비스가 끊기지 않는다. 그래서 일단은 동작한다.

    5. 근데 old_app도 죽이긴 죽여야 한다. 그래서 시간이 충분히 지난 것 같으면 old_app에 SIGINT라는 신호를 준다.

    6. old_app은 SIGINT 신호를 받으면 재량껏 자살한다.

    7. 근데 SIGINT를 보내고 일정 시간이 지났는데도 old_app이 죽지 않는다면, SIGKILL 신호를 보내서 강제로 죽게 한다.

    근데 이게, 간단한 상황에서는 알아서 잘 처리해주긴 하지만, 꼼꼼하게 설정하지 않는다면 언제 어떤 끊김 현상이 일어날지 모른다.

    주의점1: 새 앱이 완전히 동작하기 전에 올라가서 요청을 받을 경우

    갱신된 앱을 new_app으로 올리더라도, new_app이 완전하게 실행되기 전에는 잠깐 서비스가 끊길 수도 있다.

    new_app이라는 별개의 프로세스가 언제 제대로 동작할지 pm2가 어떻게 알겠는가?

    다행히 그걸 해결하기 위한 설정값으로 wait_ready란 것이 있다. 해당 앱에서 ready라는 메세지를 보낼때까지는 old_app에 요청을 보내는 것이다.

    이렇게 true로 설정해놓고

    동작이 완료될때 process.send로 ready 메세지를 찍어주면 된다.

    그럼 된다.

    주의점2: old_app이 요청 처리 중에 죽을 경우

    위에서 old_app은 일정한 시간이 지난 후엔 SIGKILL을 받고 죽게 된다고 했었다.

    근데 처리작업이 좀 길어져서 SIGKILL을 받을때까지 처리를 완료하지 못한다면?? 이 또한 서비스의 구멍이 될 수 있다.

    이런 상황을 방지하고 싶다면, SIGKILL을 보내기까지의 딜레이를 좀 넉넉하게 잡고, 코드에서는 SIGINT를 받으면 바로 종료할 수 있도록 해주면 된다.

    딜레이부터 늘려보자.

    속성은 kill_timeout이다. 디폴트 값은 1600이라고 한다.

    그리고 이렇게 이벤트를 걸어준다.

    그럼 된다.

    주의점3: Http Keep-Alive가 사용될 경우

    고려할게 참 많다.

    Keep-Alive가 사용중일 때는 app.close만으로 클라이언트와의 연결이 완전히 해제되지 않는다.

    그래서 다음과 같이 추가적인 처리를 해줘야 한다.

    SIGINT에서 잘못썼는데, false가 아니라 true값을 넣어야 한다.

     

     

     

     

     

    [출처] [Node.js] PM2와 무중단 배포|작성자 경직

Designed by Tistory.