方案
我在Ubuntu OS中有永久模式运行的多个NodeJS脚本。其中一个文件( start.js )通过将其绑定到指定端口来导入启动ZMQ发布者的文件。当我分别以永久模式启动此 start.js 文件时,它会绑定并启动发布者,并且我能够通过连接到此端口的ZMQ订阅者获取此发布者发布的数据。 / p>
我通过检查exit,SIGINT和SIGUSR事件来优雅地关闭发布者。
每当我使用forever restart
单独重新启动此 start.js 文件时,发布者就会成功绑定并启动。如果我手动停止它(使用forever stop
)并使用forever start
再次启动它也可以正常工作[也适用于我手动停止的情况(使用forever stopall
)并永远启动它脚本一个接一个]。
注意:所有永久停止和重启命令都使用CLI选项运行--killSignal = SIGINT。
问题
但是当我forever restartall --killSignal=SIGINT
时,发布者未能绑定。它说该地址已被使用(我已使用netstat
检查了该地址,并且该端口没有tcp套接字)。当我停止所有脚本并逐个启动它时,它会正常绑定并成功启动。
我已经检查过这些kill信号是由发布者脚本捕获的,并在退出之前关闭了发布者套接字。
尝试失败:
降低了tcp套接字的TIME_WAIT状态。
启用TIME_WAIT套接字重用。
我认为tcp套接字需要时间才能释放 TIME_WAIT状态,并尝试在1000ms后绑定发布者 每次绑定失败,但脚本试图绑定和失败 每次尝试。
尝试永远使用SIGINT,SIGUSR1 kill重新启动所有脚本 发出信号并在绑定发布者的脚本中处理它们 插座。
这就是我在发布商处理SIG *事件的方式:
process.stdin.resume();
function exitHandler(options, err){
if (options.cleanup) console.log('pub-clean');
if (err) console.log("pub--" + err.stack);
if (options.exit){
socket.close();
console.log("Publisher Closed")
process.exit();
}
}
process.on('exit', exitHandler.bind(null,{cleanup:true}));
process.on('SIGINT', exitHandler.bind(null, {exit:true}));
process.on('uncaughtException', exitHandler.bind(null,{exit:true}));
process.on('SIGUSR2', exitHandler.bind(null, {exit:true}));
process.on('SIGTERM', exitHandler.bind(null, {exit:true}));
为什么永远重启所有脚本导致发布者脚本无法绑定?
可以做些什么来使发布商脚本永远重新启动时绑定?