Graceful restart/reload
Graceful Stop
为了优雅的restart/reload/stop,在你的app退出之前,确保你可以收到SIGINT信号,并清除需要删除的数据(例如,数据库连接,进程事务…)
process.on('SIGINT', function() {
db.stop(function(err) {
process.exit(err ? 1 : 0);
});
});
现在,pm2 reload 将会是一个优雅的reload
Explanation: Signals flow
当一个进程通过pm2,是已经停止或者重启,一些系统信号按照一定的顺序发送到你的进程。
首先,一个SIGINT信号发送到你的进程,你可以知道你的进程将会被停止。如果你的app在1.6s(可定制)前还没有退出,将会收到一个SIGKILL信号强制进程退出。
Cleaning states and jobs
如前所述,如果你需要清理(停止轮询,停止数据库连接…)你可以截获SIGINT信号准备退出你的应用。
process.on('SIGINT', function() {
// My process has received a SIGINT signal
// Meaning PM2 is now trying to stop the process
// So I can clean some stuff before the final stop
clearInterval(my_interval);
my_db_connection.close();
current_jobs.save();
setTimeout(function() {
// 300ms later the process kill it self to allow a restart
process.exit(0);
}, 300);
});
Customize exit delay
- 通过cli设置,延长超市时间到3000ms
$ pm2 start app.js --kill-timeout 3000
或者在json配置文件中声明:
{
"apps" : [{
"name" : "api",
"script" : "app.js",
"kill_timeout" : 3000
}]
}
Graceful start
从现在开始(pm2 version 2.1.x),你可以有一个优雅的start。有时候,你或许需要等待你的app已经建立了和DBs/caches/workers/whatever的连接。在认为你的app是online之前,pm2需要去等待。为了做到这一点,你需要提供一个–wait-ready的指令或者wait_ready:true的配置。这将会确保pm2可以监听到此事件。在你的app中,当你想让你的app被认为是ready,则需要添加process.send(‘ready’)。
注意,pm2有一个监听事件的超时设置。如果你启动花费的时间比默认的3000ms多,那么你可以提高这个超时时间设置,通过配置PM2_GRACEFUL_LISTEN_TIMEOUT env variable或listen_timeout
var http = require('http');
var app = http.createServer(function(req, res) {
res.writeHead(200);
res.end('hey');
})
var listener = app.listen(0, function() {
console.log('Listening on port ' + listener.address().port);
process.send('ready');
});
Graceful start using http.Server.listen
还有一个老系统,hooks into http.Server.listen方法。当你的http server接受到一个连接,它即将会默认为你的app已经ready。你可以增加pm2的等待时间,使用–wait-ready, PM2_GRACEFUL_LISTEN_TIMEOUT env variable 或listen_timeout。
Windows graceful stop
当信号不可用时,进程被杀死。在这种情况下,您需要监听shutdown事件:
process.on('message', function(msg) {
if (msg == 'shutdown') {
console.log('Closing all connections...');
setTimeout(function() {
console.log('Finished closing connections');
process.exit(0);
}, 1500);
}
});
Environment management
When starting a new process
当开启一个新的process,pm2将按照命令注入指定的环境设置:
1. 首先,pm2 cli将会使用shell命令所指定的环境;
2. pm2将会投入指定环境在ecosystem file中的相关配置;
module.exports = {
apps : [
{
name: "myapp",
script: "./app.js",
watch: true,
env: {
"NODE_ENV": "development",
}
}
]
}
你可以看到pm2将会覆盖当前的环境,添加 NODE_ENV=development,但是你也可以声明其他不同的环境。
module.exports = {
apps : [
{
name: "myapp",
script: "./app.js",
watch: true,
env: {
"PORT": 3000,
"NODE_ENV": "development"
},
env_production: {
"PORT": 80
"NODE_ENV": "production",
}
}
]
}
默认的环境是env,但是你也可以使用pm2 start ecosystem.config.js –env production 来开启 env_production
While restarting/reloading a process
默认情况下,pm2不会改变进程的运行环境,当指定restarting或reloading。如果你想更新他们,那你必须使用 –update-evn
- 你想restart你的进程并且获取在ecosystem.json中的更改?pm2 reload ecosystem.json –update-env
- 仅仅指定某个app更新环境配置?pm2 reload ecosystem.json –update-env –only myapp*
- 想投入一个新的环境配置(for example: DEBUG): DEBUG=* pm2 reload myapp –update-evn
Specific environment variables
NODE_APP_INSTANCE : pm2 2.5 app实例的最小数量,这个变量是用来制造进程间的差异。比如,你可能只想在一个进程里运行一个任务,你可以检查是否 process.env.NODE_APP_INSTANCE === 0。两个进程可能有相同的号码,在 pm2 restart 和 pm2 scale 后
你或许不能使用 NODE_APP_INSTANCE 这个名字,你可以通过 instance_var 来重命名
module.exports = {
apps : [
{
name: "myapp",
script: "./app.js",
watch: true,
instance_var: 'INSTANCE_ID',
env: {
"PORT": 3000,
"NODE_ENV": "development"
}
}
]
}
接下来,可以使用process.env.INSTANCE_ID来访问了
Log management
PM2.5可以让你方便的管理你的应用程序的日志。您可以实时显示来自所有应用程序的日志,刷新它们,并重新加载它们。也有不同的方式来配置如何处理你的日志(PM2将分散在不同文件、合并、时间戳…)没有修改任何代码。
Displaying logs in real-time
实时显示日志
# 显示pm2 log命令的选项说明
$ pm2 logs -h
# 显示所有app的log
$ pm2 logs
# 只显示app名字为api的log
$ pm2 logs api
# 只显示app名字为api的最多1000行log
$ pm2 logs big-api --lines 1000
# json形式输出log
$ pm2 logs --json
# 指定日期格式输出log
$ pm2 logs --format
Directly output json logs
从pm2 2.4.0开始,你可以直接输出json格式的log
- CLI: –log-type json
- Process file: “log_type”: “json”
这将会将log以json形式保存到err和out文件里。下面是一个json格式的例子:
{
"message": "echo\n", // the actual message that has been `console.log`
"timestamp": "2017-02-06T14:51:38.896Z", // timestamp of the message, can be formated
"type": "out", // the type of logs, can be `err`, `out` or `PM2`
"process_id": 0, // the process id used by PM2
"app_name": "one-echo" // the application name
}
注意:timestamp将会使用–format或date_format: “DD-MM-YYYY” 指定的格式来进行格式化
Flushing logs
# 清空所有log
$ pm2 flush
Rotating Logs
pm2-logrotate auto rotate logs of PM2 and applications managed:
$ pm2 install pm2-logrotate
Reloading all logs
Reloading logs is especially useful for Logrotate or any other rotating log system. You can reload logs by sending SIGUSR2 to the PM2 process. You can also reload all logs via the command line with:
$ pm2 reloadLogs
Log configuration
- CLI
Example:
$ pm2 start echo.js --merge-logs --log-date-format="YYYY-MM-DD HH:mm Z"
Options:
--merge-logs 没有以process id为后缀的日志文件
--log-date-format <format> 使用指定的日期格式化表达式来格式化日期并作为log前缀
-l --log [path] 指定整个日志文件路径(包括error和out)
-o --output <path> 指定out log日志文件路径
-e --error <path> 指定error log日志文件路径
- JSON way
{
"script" : "echo.js",
"error_file" : "err.log",
"out_file" : "out.log",
"merge_logs" : true,
"log_date_format" : "YYYY-MM-DD HH:mm Z"
}
- Combine out and err logs
将所有的log合并到一个文件,设置error_file和out_file为相同的值,或者使用log_file配置。如:
{
"log_file": "combined.outerr.log",
"out_file": "out.log",
"error_file": "err.log"
}
如果你想将out和err合并到一个文件,并不想产生其他文件,则只需设置成相同的log file:
{
"out_file": "combined.log",
"error_file": "combined.log"
}
注意,相对路径基于cwd
Disabling log suffix
使用–merge-logs 可以禁用自动生成的log文件后缀Disable logging
{
"out_file": "/dev/null",
"error_file": "/dev/null"
}
从pm2 2.4.0开始,你可以设置 /dev/null 或 NULL 来禁用日志。
注意:合并的日志log_file仍是可用的,这些值只适用于 error 和 out文件
- Setting up a native logrotate
$ sudo pm2 logrotate -u user
这将会创建一个基本的logrotate configuration配置到 /etc/logrotate.d/pm2-user。如下:
/home/user/.pm2/pm2.log /home/user/.pm2/logs/*.log {
rotate 12
weekly
missingok
notifempty
compress
delaycompress
create 0640 user user
}