这段代码很简单,我们改写应用接收到 SIGINT 事件的默认行为,不再简单粗暴直接杀死进程,而是在 server.close 方法回调中再调用 process.exit 方法,接着继续试验一下。
$ lsof -i TCP:9420 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME node 75842 myunlessor 13u IPv6 0xd250033ec7c9362b 0t0 TCP *:9420 (LISTEN) $ curl :9420 & [1] 75878 $ kill -2 75842 $ It works [1]+ Done curl :9420
可以看到,应用在退出前(即进程离场前),成功地响应了存量请求。
我们还可以验证,进程离场前,确实不再接收增量请求:
$ curl :9420 curl: (7) Failed to connect to 127.0.0.1 port 9420: Connection refused
这正是 server.close 所做的事,进程平滑离场就是这么简单,是这么描述这个 API 的:
Stops the server from accepting new connections and keeps existing connections. This function is asynchronous, the server is finally closed when all connections are ended and the server emits a 'close' event. The optional callback will be called once the 'close' event occurs. Unlike that event, it will be called with an Error as its only argument if the server was not open when it was closed.
结束语
进程平滑离场只是 Node 进程平滑重启的一部分。生产环境中,新旧进程的接替涉及进程负载均衡、进程生命周期管理等方方面面的考虑。专业的工具做专业的事,PM2 就是 Node 进程管理很好的选择。