티스토리 뷰

생각 보다 많은 오류가 났던 pm2적용시키기..

그래도 다음엔 같은 오류가 나지 않게 하기 위해 한번 오늘 겪었던 모든 오류와 생각을 정리해봤다.

 

일단 pm2를 AWS의 EC2에서는 사용하여 서버를 끄더라도 계속 작동이 되도록 사용해 보았다.

하지만 어느 회사던지 하나의 서버로만 작동하진 않는다.

그래서 우리는 서버를 분산하여 데이터의 과부화라던지 성능면에서 좀더 나은 향상을 바라야 한다.

 

그래서 우리는 노드환경에서 사용할수 있는 PM2를 사용해본다.

 

일단 yarn패키지를 사용하고 있으므로 yarn 기준으로 한다.

npm패키지 같은 경우는 여러곳에서 많이 사용하므로 구글링을 해보면 바로 나온다.

 

패키지 다운로드

// yarn패키지
yarn global add pm2

// npm패키지
npm i pm2 -g

사실 처음시도할때는 글로벌로 설치하지 않고 yarn add pm2로 다운받았었다.

이렇게 다운로드 하고 버전을 확인하기 위해 pm2 -version을 해보았다.

[ERROR] 'pm2'용어가 cmdlet, 함수, 스크립트 또는 실행할 수 있는 프로그램 이름으로 인식되지 않습니다.

+ pm2 start app.js + ~~~
+ CategoryInfo : ObjectNotFound: (pm2:String) [], CommandNotFoundException + FullyQualifiedErrorId : CommandNotFoundException

 

이러한 에러가 발생했다. 

위 문제는 pm2를 전역으로 설치를 했지만 해당 위치에서 불러들이지를 못하고 있는것 같았다.

그러면서 몇가지를 시도해 보았다.

 

시도1

파워쉘 보안 문제

파워쉘에서 보안을 막으면 발생할수도 있다고 하여 관리자 권한으로 파워쉘을 들어가서 권한을 열어주었다.

Set-ExecutionPolicy RemoteSigned

 

명령어로 권한을 RemoteSigned으로 바꿔주었다.

그래도 똑같이 에러가 발생했다.

 

시도 2

원래는 설치를 yarn add pm2로 하다가 서버가 한프로젝트에만 묶여있으면 안된다고 생각이 들었다.

이때 들었던 생각이 글로벌로 설치를 해야하지않나? 라는 의문을 가지고 글로벌로 설치하게 됬다.

 

해결

이렇게 시도 2를 사용하여 힘겹게 에러를 처리할수 있었다.

이렇게 보면 얼마 안되지만 구글링과 글로벌을 생각하기까지 너무 오래 걸렸던것 같다.

 

이제 AWS EC2에 PM2를 적용하는것처럼 테스트를 해보았다.

잘 작동되는걸 볼수있다.

 

이제 내가 할것은 서버를 분산시키는 것이다.

이부분에서 거의 하루가 다 간것 같다..

이 프로젝트에서는 패키지는 패키지는 yarn을 사용했고 모듈은 requeir가 아닌 import 즉, es6를 사용했다.

pm2의 예시로 es6를 사용하는사람이 별로 없다는 걸 알게 되었다.

일단 우리가 명령어로 치지 않는다면 따로 pm2설정파일을 만들어서 설정을 해주어야 한다.

가장 최상단 루트에다가 파일을 하나 만들어준다.

// ecosystem.config.js

module.exports = {
  apps: [
    {
      script: "./app.js",
      name: "app",
      instances: 3,
      exec_mode: "cluster",
    },
  ],
};

commonjs에서는 이렇게하고 pm2 start하면 알아서 파일을 읽으면서

클러스터가 나오는걸 볼수있었다.

 

하지만 es6에서는 어떻게 해야하지 고민을 하다가 처음에는 es6의 모듈화를 시켜주었다.

// ecosystem.config.js
export default {
  apps: [
    {
      script: "./app.js",
      name: "app",
      instances: 3,
      exec_mode: "cluster",
    },
  ],
};

하지만 에러가 뜨면서 작동하지 않았다.

 

[PM2][ERROR] File ecosystem.config.js malformated
Error [ERR_REQUIRE_ESM]: require() of ES Module C:\developer\layered_architecture_pattern_resume_api\ecosystem.config.js from  C:\Users\User\AppData\Roaming\npm\node_modules\pm2\lib\Common.js not supported.

 

이 에러는 ecosystem.config.js 에서는 esm을 사용하고 있어서 문제가 발생하는 것이였다.

 

그럼 es6를 사용하고 있으면 pm2의 클러스터를 사용못하나??생각을 하면서 이것저것 시도해 보았다.

 

 

시도 1

해달 파일로 클러스터를 못만든다고 가정을 하고 해당 명령어가 있는지 확인을 했다.

pm2의 명령어로 작성하여 클러스터를 만들었다.

형식 : pm2 <명령어> <실행할 파일> <...옵션> 

 

명령어

더보기
명령어 역할
start - 앱 실행
- 일반적으로 옵션을 정하지 않는다면 fork모드로 설정
- 서버 실행즉시 데몬화되어 종료하거나 에러가 발생하지 않는이상 24시간 유지
pm2 start app.js
restart - 프로세스 재시작
- 모든 프로세스를 죽인다음 다시 시작하는 방식 
- 잠깐동안 서비스를 이용하지 못하는 상황 발생
pm2 restart app (프로세스이름)
pm2 restart 0 (프로세스id)
pm2 restart all (프로세스 전체)
reload - 하나씩 프로세스를 죽여 최소한 1개 이상의 프로세스 유지하여 하나씩 재시작
- 잠깐 재시작 하는 동안에 서비스를 이용못하는 상황을 방지
- 0-second-downtime이라 불림
- restart 보다 재실행 속도가 느림
pm2 reload app
pm2 reload 0
pm2 reload all
stop - 프로세스 중지
- 클러스터링 된 여러개의 프로세스중에 특정 프로세스를 골라 중지
- 중지된 프로세스는 pm2가 관리
pm2 stop app.

pm2 stop 0

pm2 stop all
delete - 프로세스 삭제 pm2 delete app
pm2 delete 0

pm2 delete all
kill - 프로세스 전체 삭제 pm2 kill
log - 로그 보기
- 에러를 보기위해서는 뒤에 --err
- 출력줄수는 --lines (숫자)
기본 로그파일 위치 - /root/.pm2/pm2.log
pm2 log

pm2 log 0
pm2 log --lines 10
pm2 log --err 10
list - 프로세스 목록 보기 pm2 list
monit - 프로세스 모니터화 하기 pm2 show (이름, id, 전체)
show - 프로세스 정보보기 pm2 show (이름, id, 전체)

scale - 프로세스 늘리기 pm2 scale app +증가할 프로세스수
ls | status - 프로세스 상태보기 pm2 ls | pm2 status

옵션

더보기
옵션 설명
--watch - 현재 디렉토리와 그 하위 폴더의 파일을 실시간으로 감시
- 파일 수정시 서버를 재 실행
- 수종으로 재실행 x, 새로고침만으로 확인 가능
- nodemon과 유사
pm2 start app.js --watch
--no-deamon - deamon이 아닌 상태로 프로그램을 실행 pm2 start app.js --no-deamon
-i (코어 개수) - node.js의 싱글 스레드를 보완하기 위한 클러스터 모드
- 해당하는 코어 개수로 클러스터링함
pm2 start app.js -i 4 
--name - 앱 이름 지정 pm2 start app.js --name "app"
... ... ...

pm2 start app.js -i 3 

생성 되었다

하지만 지금까지의 생각으로는 이렇게 된다음에 실행을 하면 id 0.1.2가 번갈아 가면서 실행되어야 하는데

요청을 보내면

마지막 프로세스인 2번 프로세스만 들어가는걸 알수 있었다.

명령어로 하면 한계가 있나? 싶어 다른 방법을 찾아봤다.

 

 

 

시도 2

ecosystem.config.js 변환하기

예전에 스웨거를 적용시킬때 auto-swagger를 사용하였는데 이때도 es6를 지원안하여 requier로 변환했던 기억이 있어 이번에도 변환을 해보고자 시도를 해보았다.

 

처음엔 스택오버플로우 여기에 나와있는 방법으로 한번 시도를 해보았다.

될것 같았지만 되지 않았다...

 

수많은 구글링을 한 결과 node_args:"--experimental-modules"를 입력하면 es모듈을 활성화를 시켜준다고 한다.

 

그래서 common.js 문법인 설정파일에서 위 키 값을 적어주었다.

module.exports = {
  apps: [
    {
      script: "./app.js",
      name: "app",
      instances: 3,
      exec_mode: "cluster",
      merge_logs: true,
    },
  ],
  node_args: "--experimental-modules",
};

이렇게 하면 pm2 실행시에 node_args에 있는 옵션이 es모듈을 활성화 시켜주는 것이다.

 

 하지만 그래도 에러가 발생하였다.

근데 그중에서 바뀐에러가 있었는데

Instead either rename ecosystem.config.js to end in .cjs, change the requiring code to use dynamic import() which is available in all CommonJS modules, or change "type": "module" to "type": "commonjs" in C:\developer\layered_architecture_pattern_resume_api\package.json to treat all .js files as CommonJS (using .mjs for all ES modules instead).

확장자를 js에서 cjs로 바꾸면 가능하다는 에러였다.

 

그렇게 파일 확장자명을 cjs로 바꿧다.

ecosystem.config.cjs

적용이 완료 되었다.

후..

 

이제 실행을 하면 되겠지?

여전히 2번 프로세스 , 마지막 프로세스만 나온다...

 

또 다시 시작된 엄청난 구글링

똑같은 문제를 질문한 글을 봤는데 클러스터가 모두 online인데 로그를 찍었을때 특정 프로세스 아이디만 나온다고 저기 있는 다른 프로세스들은 안쓰인다고 어떻게 장담하냐는 글을 봤다.

여기에서 머리를 크게 맞은듯한 느낌이 들었다..

얕은 지식으로 눈에 보이는것만 확인을 하려니 이렇게 된거 같다라는 생각이 든다.

 

하지만 저 글 하나만으로는 확실하지가 않다

좀더 깊게 파고 들어서 확실한 답을 알아야 겠다..

하지만 오늘은 너무 많은 시간을 쏟았으니 추후에 더 공부를 해봐야겠다..

 

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
글 보관함