2012-05-28 63 views
15

我有一台运行着几个node.js项目的根服务器。他们应该分别在自己的流程和目录中运行。考虑这个文件结构:在多个node.js中共享一个端口HTTP进程

/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 
    | +-- ... 
    +-- ...    | ... 

每个index.js应与cwd设置为其父文件夹(someProjectanotherProject等)开始作为一个单独的进程。

Think ov vHosts。每个项目启动一个监听其自己的域的网络服务器。还有问题。只有一个脚本可以启动,因为它们都尝试绑定到端口80.我挖掘到node.js API并寻找可能的解决方案:child_process.fork()

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

Seccond方法child.js

var http = require("http"); 

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

process.send(server); // Nope 

第一种方法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); 

所以这是一个死胡同。但是,嘿! 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); 
}); 

child.js

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

这里的孩子直接听主人的服务器。所以在这之间没有任何域名检查。所以这里是死路一条。

我也想过Cluster,但是它使用与手柄相同的技术,因此具有相同的限制。

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

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

+1

如果有人提出这个问题的“更合适的”解决方案,我会标记他或她的答案是正确的。 – buschtoens

+0

我目前正在研究应该解决这个问题的东西...... – buschtoens

+0

任何人都知道如何在IIS内运行节点时如何做到这一点? –

回答

1

就我个人而言,我只是让他们都听专用的端口或最好是套接字,然后把所有东西都放在专用路由器脚本或nginx之后。这是IMO最简单的方法。

+0

我只是喜欢有一个内部重写请求的轻量级node.js脚本。但遗憾的是,目前这是不可能的,我必须坚持使用unix插槽。 – buschtoens

+1

我真的很困惑,为什么我的答案去了0/2,当almypal的建议是完全一样的(只留下一切在不同的端口,并使用一个单独的路由器),并去6/0。我并不是很在乎,但很好奇。 – Chuck

9

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

定义您routes.json像

{ 
     "beep.example.com" : 8000, 
     "boop.example.com" : 8001 
} 

,然后使用

bouncy routes.json 80 
+0

bouncy与[http-proxy](https://github.com/nodejitsu/node-http-proxy)几乎相同。这种解决方案让我感到恼火的是,项目服务器绑定到另一个端口,它实际上并未使用,因为它应该绑定到端口80. – buschtoens

+0

http-proxy上的+1 - 这就是我使用的 – bryanmac

0

对于连接中间件有vhost延长运行有弹性。也许你可以复制他们的一些概念。

+0

Connect's 'vhost' bascially做到这一点:'server.emit('request',req,res);'。我已经尝试过了。您需要获取子进程的服务器实例才能够在其上发出事件。由于node.js在内部对此实例进行字符串化,所有引用都会丢失,并且我不能在那里发出事件。 – buschtoens

相关问题