cloud/idea

pm2 대신 사용할수있는 fileSystem 기반 프로세스 관리 프로그램을 만들어 보자 (cluster, nodejs)

yjlee06 2024. 4. 17. 20:16
반응형

 

개발 동기

기존 pm2를 사용하여 여러 프로세스를 손쉽게 관리할 수 있었으나

서비스 규모가 커지면서 프로세스간 통신무중단 서비스를 제공하기 위해

자체적으로 프로세스 관리 프로그램(이하 pm)을 만들어야겠다고 생각하였다.

 

1. 프로세스 관리 프로그램을 만들기 위한 준비

fs 와 cluster 라이브러리 설치

 

 

2. pm 구동 과정


1. versions.json 파일에 프로세스에 올릴 대상인 파일의 이름과 버전을 작성한다.
2. 해당 json 파일의 이름과 fileSystem(이하 fs)에서 매칭되는 파일의 path를 가져온다.

3. 해당 path의 개수만큼 프로세스를 생성하고 생성된 프로세스에 각각 파일 path와 역할을 전송한다.

4. 파일 path와 역할을 받은 프로세스는 작업을 수행(client에서 넘어온 이벤트 처리 및

다른 프로세스에서 요청한 정보 처리) 한다.

 

여기서 role은 무엇인가?

role은 해당 프로세스가 다른 프로세스와 통신할 때 사용하게 된다.

프로세스 간 통신이라 하지만 해당 환경 자체로는 child_process 끼리 통신은 불가능하기에

parent_process를 통해 통신을 하게 된다. 여기서 role은 통신할 target을 대략적으로 지정할 수 있게 해 준다.

 

개발하면서 통신할 target을 지정하는 경우는 2가지이다.

1. 이용자에게 최신 버전 프로세스를 적용할 경우

2. 이전 프로세스를 이용해야 하는 상황일 경우

 

해당 role은 첫 번째인 대략적인 target을 지정할 때 사용될 수 있다. 

두 번째는 process id를 통하여 구현해야 한다.

 

또한 생성된 프로세스들은 client event listen용도로만 사용되는 것이 아닌

타 process의 이벤트 처리를 같이 하는 용도(ex. 스트리밍, 머신러닝)로 사용될 수 있다.

 

 3. pm 연결 끊김 프로세스 관리 과정 (setinterval를 활용한 주기적인 확인)

img

versions.json과 parent_process에서 가지고 있는 process version 데이터를 비교하여 다를 시에 현재 같은 버전명으로(파일 이름) 생성된 프로세스가 2개 이상일 경우 프로세스가 과도하게 생성되는 것을 방지하고자 다음 주기까지 기다린다.

 

만약 해당 과정 중 disconnect가 되어있는 프로세스가 발견될 경우 새로운 프로세스를 즉시 만든다.

 

4. 신규 버전 프로세스 업데이트

img

프로세스 생성과정은 일부 생략하였다. (위와 동일)

 

프로세스가 생성된 순간부터 이전 프로세스는 shutdown 명령어를 받게 되고

이 순간부터 해당 프로세스는 기존 client 외 다른 client를 모두 패스한다.
(패스된 클라이언트는 모두 신규 client 처리됨)

그리고 해당 프로세스를 이용하는 client수가 0이 되었을 때

해당 process parent process는 shutdown 요청을 다시 보내게 되고(최종 확인)

parent process는 shutdown을 진행한다.

 

 

자체 제작 pm의 주의할 점

실제로 테스트해본 결과 zero downtime 구현 테스트는 성공하였으나 parent_process에서 문제가 발생 시 하위 프로세스들이 모두 죽기에 parent_process는 최대한 간결하면서 버그를 생기지 않게 하는 방향으로 해야 한다.

 

위에 pm2를 사용하여해 볼려고도 하였으나 child process가 존재하는 상태에서는 돌아가지 않는 듯하다.

 

결론

child process 간 통신 및 child, parent 간 통신 모두 parent process를 거치기에

프로그램의 응집력을 높일 수 있었으며

ROLE, process Id를 이용하여 보내는 child process에서

target child process를 쉽게 파악할 수 있었다.

 

많은 유저를 분산시켜서 받는 목적이 아닌

하나하나의 프로세스 버전 관리에 목적을 두어

일반적인 상황에서는 맞지 않을 수도 있겠으나

소규모 프로젝트와 같이 대규모 사용자를 처리하지 않는 프로젝트에

상대적으로 적합한 거 같다.

 

또한 프로그램 로직에서 일부분만 수정한다면

여러 프로세스의 버전을 컨트롤할 수 있는 프로그램 또한

만들 수 있기에 확장성 또한 기대할 수 있다.