์ ์ฌ ์ด๊ธฐ ํ๋ก ํธ์๋ ์๋น์ค ๋ฐฐํฌ ํ๊ฒฝ์ด EC2์ PM2๋ก ๊ตฌ์ถ๋์ด ์์์ต๋๋ค.
PM2์ ๋ํด ๊ณต๋ถํ๋ฉฐ ๋ฆฌ์์นํ ๋ด์ฉ์ ๋๋ค.
PM2๋ Process Manager์ ์ฝ์๋ก NodeJS ํ๋ก์ธ์๋ฅผ ๊ด๋ฆฌํ๋, ์ํํ ์๋ฒ ์ด์์ ์ํ ํจํค์ง
- ์๋น์ค๋ฅผ ์ ๊ณตํ๊ณ ์๋ ๋์ค ๊ฐ์๊ธฐ ์๋ฒ๊ฐ ์ค์ง๋์ด๋ ์๋ฒ๋ฅผ ๋ค์ ์คํ
- Node.js๋ ์ฑ๊ธ ์ค๋ ๋ ๊ธฐ๋ฐ์ด์ง๋ง, ๋ฉํฐ ์ฝ์ด ํน์ ํ์ดํผ ์ค๋ ๋ฉ์ ์ฌ์ฉํ ์ ์๊ฒ ํด์ค
- ํด๋ผ์ด์ธํธ๋ก๋ถํฐ ์์ฒญ์ด ์ฌ ๋ ์์์ ์์ฒญ์ ์ฌ๋ฌ ๋ ธ๋ ํ๋ก์ธ์ค์ ๊ณ ๋ฅด๊ฒ ๋ถ๋ฐฐ (๋ก๋ ๋ฐธ๋ฐ์ฑ)
์๋ ์๋ฆฌ
- PM2์ Cluster mode๋ Node.js์ Cluster module์ ํตํด ์๋
- Node.js Cluster module์ Node.js์์ ๋ฉํฐ์ฝ์ด ์์คํ ์ ์ด์ฉํ ์ ์๋๋ก Port๋ฅผ ๊ณต์ ํ๋ Child process๋ฅผ ์์ฑ
- ์์ฒญ์ Parent process๊ฐ ๋ฐ์ ํ Child process๋ค์ ์ฌ๋ถ๋ฐฐ
- ๊ฐ Child process๋ ๊ฐ๊ฐ์ V8์์ ์๋ํ๋ฏ๋ก, Node ์ธ์คํด์ค๋ฅผ ๋ ๋์ด ๊ฒ๊ณผ ๊ฐ์ด ๋์
- ์ธ๋ฉ๋ชจ๋ฆฌ์ ์์กดํ์ง ์๋ ํ๋ก๊ทธ๋จ์ ๋ง๋ค๋ฉด ์์ ๊ฐ์ ํ์ฅ์ ๋ ์ฉ์ด
- Node.js ๊ณต์ ํํ์ด์ง์ Cluster module์ ๋ํ ์ค๋ช
A single instance of Node.js runs in a single thread. To take advantage of multi-core systems, the user will sometimes want to launch a cluster of Node.js processes to handle the load.
> Node.js์ ๋จ์ผ ์ธ์คํด์ค๋ ๋จ์ผ ์ค๋ ๋์์ ์คํ๋๋๋ฐ, ๋ฉํฐ์ฝ์ด ์์คํ ์ ์ด์ฉํ๊ธฐ ์ํด์ Node.js ํ๋ก์ธ์ค๋ค์ ํด๋ฌ์คํฐ๋ก ์ฌ์ฉํ ์ ์์ต๋๋ค. ์ด๋ฅผ ํตํด ๋ชจ๋ ์๋ฒ port๋ฅผ ๊ณต์ ํ๋ ํ์ ํ๋ก์ธ์ค๋ฅผ ์์ฑํฉ๋๋ค.
The worker processes are spawned using the child_process.fork() method, so that they can communicate with the parent via IPC and pass server handles back and forth.
> ์ด ํ์ ํ๋ก์ธ์ค๋ค์ child_process.fork() ๋ฉ์๋๋ฅผ ์ฌ์ฉํด์ ์์ฑ๋๋๋ฐ, ๋ถ๋ชจ ์์ ๊ฐ์ ํต์ ์ ์ํ IPC(Inter-process communication) ์ฑ๋์ ๊ฐ์ง๊ณ ์์ผ๋ฉฐ ์์ฑ๋ ๊ฐ ํ๋ก์ธ์ค๋ ์์ฒด V8์ธ์คํด์ค๊ฐ ์์ต๋๋ค.
๋ช ๋ น์ด
pm2 start <ํ์ผ๋ช
>
# pm2๋ฅผ ์ด์ฉํด ์ฑ์ ์คํํ๋ค๋ฉด fork ๋ชจ๋(์์ ํ๋ก์ธ์ค)๋ก ์ค์ ๋๊ณ ,
# ์๋ฒ ์คํ ์ฆ์ Daemonํ ๋์ด, ์ข
๋ฃํ๊ฑฐ๋ ์๋ฌ๊ฐ ๋ฐ์ํ์ง ์๋ ์ด์ 24์๊ฐ ๊ณ์ ์ ์ง๋๋ค.
$ pm2 start app.js --watch -i 2 # ํ๋ก์ธ์ค๋ฅผ watchingํ๊ณ ๋ฉํฐ ์ฝ์ด๋ก ์๋ฒ ์คํ
$ pm2 start app.js -i max # ์ต๋ ์ฝ์ด ๊ฐฏ์๋ก ํด๋ฌ์คํฐ๋ง
$ pm2 start app.js -i 0
$ pm2 scale app +2 # app ํ๋ก์ธ์ค ๊ฐฏ์ +2
$ pm2 scale app 4 # app ํ๋ก์ธ์ค ๊ฐฏ์ 4๊ฐ๋ก ๊ณ ์
$ pm2 status
$ pm2 ls # status์ ls๋ฅผ ์ด์ฉํด ํ์ฌ ํ๋ก์ธ์ค ๋ฆฌ์คํธ๋ฅผ ๋์
$ pm2 stop <app_name | namespace | id | 'all' | json_conf>
$ pm2 stop 2 # id 2๋ฒ ํ๋ก์ธ์ค๋ฅผ ๋ฉ์ถค
$ pm2 stop app # ์ด๋ฆ์ ์ค๋ ๋จ. (์ ์ฒด ํ๋ก์ธ์ค ๋ฉ์ถค)
$ pm2 restart <app_name | namespace | id | 'all' | json_conf>
$ pm2 restart 2 # ์์์ ์ค์งํ 2๋ฒ ํ๋ก์ธ์ค๋ฅผ ์ฌ์์
$ pm2 reload <app_name | namespace | id | 'all' | json_conf>
$ pm2 reload app
$ pm2 reload all # ๋ฆฌ๋ก๋
# - pm2 restart๋ ๋ชจ๋ ํ๋ก์ธ์ค๋ฅผ ์ฃฝ์ธ๋ค์ ๋ค์ ์์ํ๋ ๋ฐฉ์. ๊ทธ๋์ ์์ฃผ ์ ๊น ๋์ ์๋น์ค๋ฅผ ์ด์ฉํ์ง ๋ชปํ๋ ์ํฉ์ด ์๊ธด๋ค.
# - pm2 reload๋ ํ๋์ฉ ํ๋ก์ธ์ค๋ฅผ ์ฃฝ์ฌ์, ์ต์ํ 1๊ฐ ์ด์์ ํ๋ก์ธ์ค๋ฅผ ์ ์งํ๋ฉฐ ํ๋์ฉ ์ฌ์์ ํ๋ ๋ฐฉ์์ด๋ค.
# ๊ทธ๋์ ์ ๊น ์ฌ์์ ํ๋ ๋์ ์๋น์ค๋ฅผ ์ด์ฉ๋ชปํ๋ ์ํฉ์ ๋ฏธ์ฐ์ ๋ฐฉ์งํ ์ ์๋ค.
# ๋จ,์ด๋ฌํ ๋ฐฉ์ ๋๋ฌธ์ reload๋ restart๋ณด๋ค ์ฌ์คํ ์๋๊ฐ ๋๋ฆฌ๋ค๋ ๋จ์ ์ด ์๋ค.
$ pm2 delete <app_name | namespace | id | 'all' | json_conf>
$ pm2 delete 2 # ํน์ ํ๋ก์ธ์ค ์ญ์
$ pm2 delete app # ํ๋ก์ธ์ค name์ด app์ธ ๊ฑฐ ๋ชจ๋ ์ญ์
$ pm2 kill # ํ๋ก์ธ์ค ์ ์ฒด ์ญ์
$ pm2 log # ์ ์ฒด ํ๋ก์ธ์ค ๋ก๊ทธ ๋ณด๊ธฐ
$ pm2 log [process name | process id] # ํน์ ํ๋ก์ธ์ค ๋ก๊ทธ ๋ณด๊ธฐ
$ pm2 log --lines 200 # 200์ค ๊น์ง๋ง ๋ณด๊ธฐ
$ pm2 log --err 200 # ์๋ฌ ๋ก๊ทธ๋ง ๋ณด๊ธฐ
์ค์ ๋ฐฉ๋ฒ
- pm2 ์ค์ ํ์ผ ๋ง๋ค๊ธฐ (ecosystem.config.js)
$ pm2 ecosystem # ecosystem.config.js ํ์ผ์ด ์์ฑ
# ecosystem.config.js
module.exports = {
/* apps ํญ๋ชฉ์ ์ฐ๋ฆฌ๊ฐ pm2์ ์ฌ์ฉํ ์ต์
์ ๊ธฐ์ฌ */
apps: [
{
name: 'projectName', // app์ด๋ฆ
script: './index.js', // ์คํํ ์คํฌ๋ฆฝํธ ํ์ผ
instances: 2, // cpu ์ฝ์ด์ ๋งํผ ํ๋ก์ธ์ค ์์ฑ (instance ํญ๋ชฉ๊ฐ์ ‘0’์ผ๋ก ์ค์ ํ๋ฉด CPU ์ฝ์ด ์ ๋งํผ ํ๋ก์ธ์ค๋ฅผ ์์ฑ)
exec_mode: 'cluster', // ํด๋ฌ์คํฐ ๋ชจ๋
max_memory_restart: '300M', // ํ๋ก์ธ์ค์ ๋ฉ๋ชจ๋ฆฌ๊ฐ 300MB์ ๋๋ฌํ๋ฉด reload ์คํ
watch: ['bin', 'routes'], //binํด๋, routesํด๋๋ฅผ ๊ฐ์ํด์ ๋ณ๊ฒฝ์ฌํญ ์คํ
ignore_watch: ['node_modules'], // ๋ฐ๋๋ก ํด๋นํด๋์ ํ์ผ๋ณ๊ฒฝ์ ๋ฌด์
env: {
// ํ๊ฒฝ๋ณ์ ์ง์
Server_PORT: 4000,
NODE_ENV: 'development',
Redis_HOST: 'localhost',
Redis_PORT: 6379,
},
output: '~/logs/pm2/console.log', // ๋ก๊ทธ ์ถ๋ ฅ ๊ฒฝ๋ก ์ฌ์ค์
error: '~/logs/pm2/onsoleError.log', // ์๋ฌ ๋ก๊ทธ ์ถ๋ ฅ ๊ฒฝ๋ก ์ฌ์ค์
},
],
/* deploy๋ ์๊ฒฉ ์๋ฒ์ git์ ์ฐ๋ํด์ ๋ฐฐํฌํ๋ ๋ฐฉ์ */
deploy: {
production: {
user: 'SSH_USERNAME',
host: 'SSH_HOSTMACHINE',
ref: 'origin/master',
repo: 'GIT_REPOSITORY',
path: 'DESTINATION_PATH',
'pre-deploy-local': '',
'post-deploy': 'npm install && pm2 reload ecosystem.config.js --env production',
'pre-setup': '',
},
},
};
$ pm2 start ecosystem.config.js # ์ค์ ํ์ผ์ startํ๋ฉด, ์ธํ
๋๋ก pm2 ๋ช
๋ น์ด๊ฐ ์คํ
- references:
PM2์ Cluster mode๋ ์ด๋ป๊ฒ ๋์ํ ๊น์?
์๋ ํ์ธ์. ์ค๋์ PM2์ Cluster mode์ ๋ํด์ ์์๋ณด๊ฒ ์ต๋๋ค. ๋จผ์ PM2๊ฐ ๋ฌด์์ผ๊น์? PM2๋ Node.js ์ ํ๋ฆฌ์ผ์ด์ ์ ํ๋ก์ธ์ค ๊ด๋ฆฌ๋ฅผ ์ํด ์ฌ์ฉํ๋ฉฐ, ์๋์ ๊ฐ์ ์ด์ ์ ์ป์ ์ ์์ต๋๋ค. ํ๋ก๊ทธ
short-term.tistory.com
[NODE] ๐ PM2 ๋ชจ๋ ์ฌ์ฉ๋ฒ - ํด๋ฌ์คํฐ / ๋ฌด์ค๋จ ์๋น์ค
Node.js ์ฑ๊ธ ์ค๋ ๋ Node.js๋ Chrome์ V8 ์๋ฐ์คํฌ๋ฆฝํธ ์์ง์ผ๋ก ๋น๋๋ ์๋ฐ์คํฌ๋ฆฝํธ ๋ฐํ์(runtime)์ผ๋ก ‘Event Driven’, ‘Non-Blocking I/O’ ๋ชจ๋ธ์ ์ฌ์ฉํด ๊ฐ๋ณ๊ณ ์ฑ๋ฅ์ด ๋ฐ์ด๋ ๋์ ํ๊ฐ๋ฅผ ๋ฐ๊ณ ์
inpa.tistory.com
'DevOps' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| CDN (Content Delivery Network) (2) | 2025.01.05 |
|---|---|
| ๋ฌด์ค๋จ ๋ฐฐํฌ (Zero Downtime Deployment) (3) | 2025.01.05 |