任何一个 Node.js 应用都会有一些基本的操作,如
启动服务
./start.sh 或 systemctl start <service> 或 pm2 start app.json …
停止服务
./stop.sh 或 systemctl stop <service> 或 pm2 stop app.json …
重启服务
./restart.sh 或 systemctl restart <service> 或 pm2 restart app.json …
执行任务脚本
node ./tools/qps.js 或 ./tools/qps.sh
我们可能会使用 pm2 来管理服务,使用 node 来执行脚本,服务往往会依赖一些环境变量的正确定义,如:
PATH
同一机器可能跑了多个服务,而每个服务使用不同的 node.js 版本,通过设置
PATH
环境变量来决定使用哪个版本的 node.js。NODE_ENV
值为
production
表示运行在产品环境。值为
development
表示运行在开发环境。如果忘记设置
NODE_ENV
而导致在线上机器使用开发环境运行服务,后果会很严重。PM2_HOME
pm2 会在
PM2_HOME
(默认为当前用户的 HOME 目录) 目录下存放元数据,服务总是以特定的帐号(如:root)运行,线上机器往往会有多个帐号,当我们以非服务帐号登录系统,并使用 pm2 管理我们的服务进程时,就可能以错误的帐号重复运行我们的服务。NODE_CONFIG_DIR
config 模块用于指定配置文件存放路径,同时它也会使用
NODE_ENV
环境变量来决定载入哪些配置文件。
所以我们可能会写一大堆脚本,如:
.bashrc
设置环境变量,由于一台机器上可能跑多个服务,而每个服务的环境设置会不一样,所以我们不好直接放置在用户根目录下的
.bashrc
中。
.bashrc.$HOSTNAME
机器特定的环境变量,用于覆盖默认设置
start.sh
会先载入 .bashrc 中定义的环境变量,再使用
pm2 start <app>
启动服务stop.sh
会先载入 .bashrc 中定义的环境变量,再使用
pm2 stop <app>
停止服务restart.sh
会先载入 .bashrc 中定义的环境变量,再使用
pm2 restart <app>
重启服务pm2.sh
会先载入 .bashrc 中定义的环境变量,再使用用户传入的参数执行
pm2
node.sh
会先载入 .bashrc 中定义的环境变量,再使用用户传入的参数执行
node
还有一堆 js 任务脚本,你得决定要不要提供配套的 bash 脚本(确保载入 .bashrc),或者祈祷运行前操作人员会记得先载入 .bashrc
。
npm scripts 相关文章
npm scripts 使用的是 shell 命令,npm scripts 的强大其实是 shell scripts 的强大,npm scripts 只是约定了统一的入口也就是操作界面。
npm scripts 示例如下:
"scripts": { "node": "export NODE_ENV=${NODE_ENV:-production}; node", "pm2": "export NODE_ENV=${NODE_ENV:-production}; PM2=pm2; PM2_USER=${PM2_USER:-root}; [[ $HOME != `echo ~$PM2_USER` ]] && PM2=\"sudo -u $PM2_USER pm2\"; $PM2", "ps": "npm run pm2 -- list $npm_package_name", "prestart": "STARTED=`npm -s run pm2 -- jlist | json -a -c \"this.name == '$npm_package_name' && ['errored', 'stopped'].indexOf(this.pm2_env.status) == -1\" pm2_env.pm_id | wc -l`; [[ $STARTED > 0 ]] && echo $STARTED process already running; exit $STARTED", "start": "PM2_FILE=./process.json; [[ -f ./process.${HOSTNAME}.json ]] && PM2_FILE=./process.${HOSTNAME}.json; npm run pm2 -- start $PM2_FILE", "stop": "PM2_FILE=./process.json; [[ -f ./process.${HOSTNAME}.json ]] && PM2_FILE=./process.${HOSTNAME}.json; npm run pm2 -- stop $PM2_FILE", "restart": "PM2_FILE=./process.json; [[ -f ./process.${HOSTNAME}.json ]] && PM2_FILE=./process.${HOSTNAME}.json; npm run pm2 -- startOrGracefulReload $PM2_FILE" }
运行 npm scripts:
npm run
列出所有脚本。
npm run pm2 -- list
执行
pm2 list
,会确保正确设置环境变量,并且必要时切换到 pm2 帐号。npm start
执行
pm2 start
,会确保正确设置环境变量,并且必要时切换到 pm2 帐号,通过prestart
预先检查进程是否已启动,避免重启服务。npm run node -- tools/qps.js
执行
node tools/qps.js
,会确保正确设置环境变量。
npm scripts 会自动将 ./node_modules/.bin 添加到 $PATH 环境变量,将 package.json
的内容暴露成环境变量供脚本引用,通过 pre
及 post
钩子自动执行前置/后置附带任务,通过在脚本中调用其它 npm scripts 脚本也可以简化脚本的开发。
现在我们只有 npm scripts,所有的一切操作都从 npm run 开始,整个世界清净了。