反直觉的问题,请教下如何关闭http的服务并释放端口?
发布于 2 个月前 作者 wldlzt 681 次浏览 来自 问答

之前觉得这个问题很简单,但不管是server.close还是对所有连接对象进行close,似乎都不能释放已经占用的3000端口。请教下大家如何直接关闭这个http服务并释放占用的端口?

let http = require('http');
let hostname = '127.0.0.1';
let port = 3000;
let ret = 'Hello World';
let server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  console.log(ret);
  res.end(ret);
});

server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});
8 回复

let http = require(“http”); let hostname = “127.0.0.1”; let port = 3000; let ret = “Hello World”; let server = http.createServer((req, res) => { res.statusCode = 200; res.setHeader(“Content-Type”, “text/plain”); console.log(ret); res.end(ret); }); server.listen(port, hostname, () => { console.log(Server running at http://${hostname}:${port}/); }); setTimeout(() => { // emit close event server.close(error => { if (error) { console.log(“server close error:${error}”) } else { console.log(“server close”) } }) // listen on close event server.on(“close”, () => { console.log(“server is closing”) }) }, 10000) 目前不能算是反直觉。

@jxycbjhc 我来试下哈

@wldlzt 很遗憾,作为独立脚本运行,你这样是可以的,但如果在服务开启之后,你不断请求,那这个关闭是不会触发,你停止请求,然后才会触发关闭,这是不是有点反直觉…而在我自己的业务流程的设计中,是想让http服务正常开着,但现在要通过另一个进程某种通信去注销它并释放它占用的端口,目前是做不到的…麻烦您有空再研究下哩

@wldlzt “停止请求,然后才会触发关闭”这里头还存在一定的失败概率,我刚试过几次拼命请求,然后再怎么等,这个关闭都不会触发

这不是反直觉吧。API 文档里写清楚了:

server.close: Stops the server from accepting new connections. See net.Server.close().

这里的 close 就是只是指的停止接受新的链接,参考:https://nodejs.org/dist/latest-v18.x/docs/api/http.html#serverclosecallback

@hyj1991 那有没办法平滑关闭http服务,并注销端口占用呢。。。。

要平滑关闭 http 服务参考 gracefuluncaughtException 的处理就可以了:https://www.npmjs.com/package/graceful

另外,你是无法在一个进程里手动关闭已经 bind 的端口的,底层就没有这样的 api

@hyj1991 谢谢谢谢,关闭服务应该可以了,只是这个端口占用实在太碍眼…

回到顶部