我有nodejs进程A和nodejs进程B。进程A在9000端口开了一个http server。进程B不断尝试绑定9000端口,并且由于端口已被占用而失败。这很正常。
现在进程A想要释放绑定的9000端口以使得进程B可以绑定。可是进程A不能退出。该如何做到呢?
@Larvata 感谢你,你的代码是能够释放原端口的。我发现是我错误的描述了我的问题,补充如下:
我在windows上使用nodeJS启动一个http服务A。为了防止它挂掉,我启动了一个后备的http服务B,服务B会不断的尝试绑定同一个端口。如果http服务A因为某种原因退出了进程,那么服务B就会拿到那个端口的控制权,以替代http服务A。这个过程我可以通过代码完成。
然后我尝试将这个手动过程写入代码。代码会不断尝试绑定9000端口,绑定成功则提供http服务,并且开一新的进程,启动同一套代码:不断尝试绑定9000端口,绑定成功则代替前一个服务,并且开一个新的进程……
也就是进程A会开启进程B作为备胎,当进程A挂掉以后进程B会转正,并且开启进程C作为备胎……
由于开启的备胎显然不能随主进程挂掉而一起挂掉,所以有两种开启方法:
1. 通过windows的"start node xxx.js"命令启动
2. 通过cp.spawn的detached模式启动
备胎启动很顺利,但是遇到的问题是,进程A挂掉的时候,并没有将9000端口给释放,所以进程B一直无法绑定9000端口。端口只有当进程B也挂掉的时候才会被释放。但是我觉得这是说不通的,端口9000应该跟进程A一起释放才对,这种情况更像是一种port leak。
因为实际中无法决定进程A是怎么挂掉的,所以进程A不能主动关闭端口,所以我之前的问题归纳出现了问题。。。
附可执行代码(windows only)
var express = require('express');
var http = require('http');
var app = express();
var cp = require('child_process');
var server = http.createServer(app);
server.setTimeout(1000);
server.on('error', function(){
console.log("Error:", arguments);
setTimeout(tryToConnect, 3000);
});
server.on('listening', function()
{
console.log("Listening");
// var child = cp.spawn('node', ['donoting.js'], {
// detached: true,
// stdio: ['ignore', 'ignore', 'ignore']
// });
// child.unref();
cp.exec('start node listen.js');
});
var tryToConnect = function()
{
var port = 9000;
console.log("Trying to connect to port", 9000);
server.listen(9000);
};
tryToConnect();
代码应该达到的效果,应该是启动另一个窗口,然后当你把第一个关掉以后,新窗口中启动的程序取代关掉的程序。
大致写了个demo
访问
http://127.0.0.1:8001/change
之后 会释放8001 并且重新绑定8002端口这个需要用chrome测试 ie有10-20秒的延迟 不清楚具体原因 可能与keepalive有关
这里标记一下,我也想看看其他人的答案
如果是本机访问的话,我觉得没什么办法的,必定要先kill A再重新部署一番
如果是外机访问的话,倒是可以尝试一下用Ngnix或Apache做一下端口映射