优雅关机
优雅关机
一次优雅的关机,你的应用必须经过5
个步骤:
- 收到
stop
的通知 - 请求负载均衡器不再接收请求
- 完成所有正在进行的请求
- 释放所有资源(数据库,队列 …)
- 退出
比方说,下面是一个express
应用:
const app = express()
const port = process.env.port || 8000
app.get('/', (req, res) => { res.end('Hello world') })
const server = require('http').createServer(app)
server.listen(port, () => {
console.log('Express server listening on port ' + server.address().port)
})
我们首先要拦截SIGINT
信号(pm2 stop
发出的信号):
const app = express()
const port = process.env.port || 8000
app.get('/', (req, res) => { res.end('Hello world') })
const server = require('http').createServer(app)
server.listen(port, () => {
console.log('Express server listening on port ' + server.address().port)
})
process.on('SIGINT', () => {
console.info('SIGINT signal received.')
})
然后,我们要求HTTP
服务停止接收请求并完成正在进行的请求:
const app = express()
const port = process.env.port || 8000
app.get('/', (req, res) => { res.end('Hello world') })
const server = require('http').createServer(app)
server.listen(port, () => {
console.log('Express server listening on port ' + server.address().port)
})
process.on('SIGINT', () => {
console.info('SIGINT signal received.')
// Stops the server from accepting new connections and finishes existing connections.
server.close(function(err) {
if (err) {
console.error(err)
process.exit(1)
}
})
})
最后,我们关闭所有资源的连接:
const app = express()
const port = process.env.port || 8000
app.get('/', (req, res) => { res.end('Hello world') })
const server = require('http').createServer(app)
server.listen(port, () => {
console.log('Express server listening on port ' + server.address().port)
})
process.on('SIGINT', () => {
console.info('SIGINT signal received.')
// Stops the server from accepting new connections and finishes existing connections.
server.close(function(err) {
// if error, log and exit with error (1 code)
if (err) {
console.error(err)
process.exit(1)
}
// close your database connection and exit with success (0 code)
// for example with mongoose
mongoose.connection.close(function () {
console.log('Mongoose connection disconnected')
process.exit(0)
})
})
})
超时终止
默认情况下,PM2
在发送SIGKILL
信号之前,如果应用进程没用自己退出,PM2
等待1600
毫秒后会主动杀掉应用进程。
你可以在ecosystem.config.js
文件中修改这个超时时间的值,以毫秒为单位:
module.exports = {
apps: [{
name: "app",
script: "./app.js",
kill_timeout: 1600,
}]
}
在windows下的优雅关机
当进程终止信号不可用时。这种情况下,应用需要监听shutdown
事件:
process.on('message', (msg) => {
if (msg == 'shutdown') {
console.log('Closing all connections...')
setTimeout(() => {
console.log('Finished closing connections')
process.exit(0)
}, 1500)
}
})
优雅启动
在处理HTTP
请求之前,应用通常需要连接到数据库或其他资源。
你的应用需经过这3
个步骤来避免错误:
- 打开数据库连接
- 开始请求一个端口
- 通知
PM2
应用已准备就绪
首先,在ecosystem.config.js
文件配置在pm2
中启用ready
信号:
module.exports = {
apps : [{
name: "api",
script: "./api.js",
wait_ready: true,
listen_timeout: 3000,
}],
}
默认情况下,
PM2
会监听应用是否ready
,如果3000ms
后没有ready
会强制重载。 使用listen_timeout
改变这个值。
让我们继续使用之前的express
应用:
const app = express()
const port = process.env.port || 8000
app.get('/', (req, res) => { res.end('Hello world') })
server.listen(port, () => {
console.log('Express server listening on port ' + server.address().port)
})
首先,等待数据库连接准备就绪:
const app = express()
const port = process.env.port || 8000
app.get('/', (req, res) => { res.end('Hello world') })
const server = require('http').createServer(app)
mongoose.connect('mongodb://mongosA:27501,mongosB:27501', (err) => {
server.listen(port, () => {
console.log('Express server listening on port ' + server.address().port)
})
})
最后,使用process.send('ready')
通知PM2
应用已准备好:
const app = express()
const port = process.env.port || 8000
app.get('/', (req, res) => { res.end('Hello world') })
const server = require('http').createServer(app)
mongoose.connect('mongodb://mongosA:27501,mongosB:27501', (err) => {
server.listen(port, () => {
console.log('Express server listening on port ' + server.address().port)
process.send('ready')
})
})
在集群模式下优雅启动
在集群模式下,有一个默认系统,可以在应用接受连接时设置每个集群。 这里还有一个默认的超时时间为3000ms
,可以使用生态系统文件中的listen_timeout
属性设置。
问题
我们很乐于帮你解决你可能遇到的问题。搜索或查看FAQ
。你也可以在PM2
的GitHub仓库提交问题或评论。