更改端口而不会丢失数据

时间:2011-03-29 15:25:54

标签: node.js serverside-javascript

我正在为我的http服务器构建一个设置管理器。我希望能够在不必杀死整个过程的情况下更改设置。我希望能够改变的一个设置是更改端口号,我想出了各种解决方案:

  • 终止进程并重新启动
  • 调用server.close()然后执行第一种方法
  • 调用server.close()并在同一进程中初始化新服务器

问题是,我不确定每种方法的影响是什么。我知道第一个会起作用,但我真的很想完成这些事情:

  • 回应现有请求而不接受新请求
  • 在新服务器上维护内存中的数据
  • 尽可能少的正常运行时间

有没有办法得到我想要的一切? server.close()的API给了我希望: server.close(): Stops the server from accepting new connections.

我的服务器只能由我创建的客户端以及通过浏览器连接的非常有限数量的客户端访问,因此我将能够通知他们端口更改。我知道更改端口通常是一个坏主意,但我想允许方便或可能需要的边缘情况。

P.S。如果改变了什么,我正在使用连接。

P.P.S。相对不相关,但如果我使用UNIX服务器套接字或更改主机名,会有什么变化?这可能是一个更相关的用例。

P.P.P.S。此代码说明了使用server.close()的问题。以前的服务器都没有被杀死,但是创建了更多可以访问相同资源的服务器...

var http = require("http");

var server = false,
    curPort = 8888;

function OnRequest(req,res){
    res.end("You are on port " + curPort);
    CreateServer(curPort + 1);
}
function CreateServer(port){
    if(server){
        server.close();
        server = false;
    }
    curPort = port;
    server = http.createServer(OnRequest);
    server.listen(curPort);
}
CreateServer(curPort);

资源:

http://nodejs.org/docs/v0.4.4/api/http.html#server.close

3 个答案:

答案 0 :(得分:3)

我测试了close()函数。它似乎绝对没有。服务器仍然接受其端口上的连接。重新开始这个过程对我来说是唯一的方法。

我使用了以下代码:

var http = require("http");

var server = false;
function OnRequest(req,res){    
    res.end("server now listens on port "+8889);
    CreateServer(8889);
}
function CreateServer(port){
    if(server){
        server.close();
        server = false;
    }
    server = http.createServer(OnRequest);
    server.listen(port);
}
CreateServer(8888);

答案 1 :(得分:3)

当我决定彻底测试我的代码以查看它是否真的是一个错误时,我正要在节点github页面上提交一个问题(我讨厌在用户出错时提交bug报告)。我意识到这个问题只能在浏览器中体现出来,因为显然浏览器会做一些奇怪的HTTP请求保持活动,因为它仍然可以访问死端口,因为它仍然与服务器有连接。

我所学到的是:

  • 浏览器缓存使端口保持活动状态,除非服务器上的进程被终止
  • 默认情况下不保留缓存的实用程序(curl,wget等)按预期工作
  • 节点中的HTTP请求也不保留与浏览器相同类型的缓存

例如,我使用此代码来证明节点http客户端无权访问旧端口:

客户端代码:

var http = require('http'),
    client,
    request;

function createClient (port) {
  client = http.createClient(port, 'localhost');

  request = client.request('GET', '/create');
  request.end();

  request.on('response', function (response) {
      response.on('end', function () {
          console.log("Request ended on port " + port);
          setTimeout(function () {
              createClient(port);
          }, 5000);
      });
  });
}

createClient(8888);

服务器端代码:

var http = require("http");

var server,
    curPort = 8888;

function CreateServer(port){
    if(server){
        server.close();
        server = undefined;
    }

    curPort = port;

    server = http.createServer(function (req, res) {
        res.end("You are on port " + curPort);
        if (req.url === "/create") {
            CreateServer(curPort);
        }
    });
    server.listen(curPort);
    console.log("Server listening on port " + curPort);
}
CreateServer(curPort);

感谢大家的回复。

答案 2 :(得分:0)

使用群集怎么样?

http://learnboost.github.com/cluster/docs/reload.html

看起来很有趣!