在多个node.js HTTP进程之间共享一个端口

bus*_*ens 15 linux http vhosts node.js

我有一个root服务器,上面运行着几个node.js项目.它们应该在自己的进程和目录中单独运行.考虑这个文件结构:

/home
+-- /node
    +-- /someProject      | www.some-project.com
    |   +-- index.js
    |   +-- anotherFile.img
    |   +-- ...
    +-- /anotherProject   | www.another-project.com
    |   +-- /stuff
    |   +-- index.js
    |   +-- ...
    +-- /myWebsite        | www.my-website.com
    |   +-- /static
    |   +-- index.js
    |   +-- ...
    +-- ...               | ...
Run Code Online (Sandbox Code Playgroud)

每个index.js应该开始与它的一个单独的处理cwd集合到它的父文件夹(someProject,anotherProject等).

想想ov vHosts.每个项目都会启动一个监听自己域名的Web服务器.而且存在问题.只有一个脚本可以启动,因为它们都尝试绑定到端口80.我深入研究了node.js API并寻找可能的解决方案:child_process.fork().

可悲的是,这不是很好.当我尝试将服务器实例发送到主进程(稍后发出请求)或者从主服务器requestresponse从主服务器到服务器的对象时,我得到错误.这是因为node.js在内部尝试将这些高级对象转换为JSON字符串,然后将其重新转换为其原始形式.这使得所有对象都失去了它们的引用和功能.

第二种方法 child.js

var http = require("http");

var server = http.createServer(function(req, res) {
    // stuff...
});
server.listen(80);

process.send(server); // Nope
Run Code Online (Sandbox Code Playgroud)

第一种方法 master.js

var http = require("http"),
    cp = require("child_process");

var child = cp.fork("/home/node/someProject/index.js", [], { env: "/home/node/someProject" });

var router = http.createServer(function(req, res) {
    // domaincheck, etc...
    child.send({ request: req, response: res }); // Nope
});
router.listen(80);
Run Code Online (Sandbox Code Playgroud)

所以这是一个死胡同.但是,嘿!Node.js提供了一些可发送的句柄.以下是文档中的示例:

master.js

var server = require('net').createServer();
var child = require('child_process').fork(__dirname + '/child.js');
// Open up the server object and send the handle.
server.listen(1337, function() {
  child.send({ server: true }, server._handle);
});
Run Code Online (Sandbox Code Playgroud)

child.js

process.on('message', function(m, serverHandle) {
  if (serverHandle) {
    var server = require('net').createServer();
    server.listen(serverHandle);
  }
});
Run Code Online (Sandbox Code Playgroud)

这里孩子直接听主人的服务器.所以中间没有域检查.所以这是一个死胡同.

我也考虑过Cluster,但是它使用与手柄相同的技术,因此具有相同的局限性.

那么......有什么好主意吗?

我目前所做的是相当黑客.我做了一个名为distroy的软件包.它绑定到端口80,并在内部代理所有对Unix域套接字路径的请求,例如/tmp/distroy/http/www.example.com单独的应用程序监听.这也(有点)适用于HTTPS(请参阅我关于SNI的问题).剩下的问题是,原始IP地址丢失了,因为它现在总是127.0.0.1.我想我可以通过monkeypatching来避免这种情况,net.Server这样我就可以在打开连接之前传输IP地址.

alm*_*pal 9

如果您对node.js解决方案感兴趣,请查看bouncy,node.js中的websocket和支持https的http路由器代理/负载均衡器.

定义你的routes.json就像

 {
      "beep.example.com" : 8000,
      "boop.example.com" : 8001
 }
Run Code Online (Sandbox Code Playgroud)

然后运行弹性使用

 bouncy routes.json 80
Run Code Online (Sandbox Code Playgroud)


Chu*_*uck 1

就我个人而言,我只是让它们全部监听专用端口或最好是套接字,然后将所有内容都放在专用路由器脚本或 nginx 后面。在我看来,这是最简单的方法。