正常closures在Forever下运行的NodeJS上的UNIX套接字服务器

我有一个NodeJS应用程序,它设置了一个UNIX套接字来公开一些进程间通信通道(某种监视的东西)。 UNIX套接字文件放在os.tmpdir()文件夹(即/tmp/app-monitor.sock )中。

 var net = require('net'); var server = net.createServer(...); server.listen('/tmp/app-monitor.sock', ...); 

我使用信号处理(SIGINT,SITERM等…)正常closures我的服务器并删除套接字文件。

 function shutdown() { server.close(); // socket file is automatically removed here process.exit(); } process.on('SIGINT', shutdown); // and so on 

我的应用程序正在forever start ...运行forever start ...监视它的生命周期。

我有一个与forever restartall命令的问题。 当永远restartall它使用SIGKILL来终止所有subprocess。 SIGKILL不能被进程处理,所以我的应用程序没有任何关机程序而死亡。

问题是使用SIGKILL时不会删除的套接字文件。 在subprocess重新启动后,新的服务器不能启动,因为“一个listen调用将导致EADDRINUSE错误。

我不能在应用程序启动过程中删除现有的套接字文件,因为我不知道它是否是一个真正的工作套接字或以前的不干净closures的痕迹。

所以,问题是…有什么更好的方式来处理这种情况(SIGKILL和UNIX-socket服务器)?

正如其他人所提到的那样,对于SIGKILL来说,不能做任何事情,一般来说为什么forever (和其他人)不应该在极端情况下使用SIGKILL。 所以你可以做的最好的是在另一个过程中清理。

我build议你开始清理。 当你得到EADDRINUSE ,尝试连接到套接字。 如果套接字连接成功,另一个服务器正在运行,所以这个实例应该退出。 如果连接失败,则可以安全地断开套接字文件并创build一个新文件。

 var fs = require('fs'); var net = require('net'); var server = net.createServer(function(c) { //'connection' listener console.log('server connected'); c.on('end', function() { console.log('server disconnected'); }); c.write('hello\r\n'); c.pipe(c); }); server.on('error', function (e) { if (e.code == 'EADDRINUSE') { var clientSocket = new net.Socket(); clientSocket.on('error', function(e) { // handle error trying to talk to server if (e.code == 'ECONNREFUSED') { // No other server listening fs.unlinkSync('/tmp/app-monitor.sock'); server.listen('/tmp/app-monitor.sock', function() { //'listening' listener console.log('server recovered'); }); } }); clientSocket.connect({path: '/tmp/app-monitor.sock'}, function() { console.log('Server running, giving up...'); process.exit(); }); } }); server.listen('/tmp/app-monitor.sock', function() { //'listening' listener console.log('server bound'); }); 

你应该可以使用SIGTERM来做你想做的事: process.on('SIGTERM', shutdown)

 server.on('error', function (e) { if (e.code == 'EADDRINUSE') { console.log('Address in use, retrying...'); setTimeout(function () { server.close(); server.listen(PORT, HOST); }, 1000); } }); 

http://nodejs.org/api/net.html#net_server_listen_port_host_backlog_callback

UPD

你不能处理SIGKILL,那么你必须清理套接字手册

这个例子永远正常工作

 var fs = require('fs'); var net = require('net'); var server = net.createServer(function(c) {}); server.listen('./app-monitor.sock', function() { console.log('server bound'); }); server.on('error', function (e) { if (e.code == 'EADDRINUSE') { console.log('Address in use, retrying...'); setTimeout(function () { fs.unlink('./app-monitor.sock'); }, 1000); } }); 

既然你不能处理SIGKILL ,你想永远使用(使用SIGKILL ),你将不得不使用一个解决方法。

例如,首先发送一个信号来closures你的服务器,然后进行永久重启:

 kill -s SIGUSR1 $pid # $pid contains the pid of your node process, or use # killall -SIGUSR1 node sleep 2 forever restart test.js 

在你的js句柄中SIGUSR1:

 process.on('SIGUSR1', gracefullyShutdownMyServer); 

你必须select

  1. 将SIGKILL更改为永久监视器中的另一个信号以在应用程序中处理
  2. 在这种情况下照顾你的应用程序,使用fs.unlink
  3. 停止使用永远