2012-05-28 16 views
15

複数のnode.jsプロジェクトを実行しているルートサーバーがあります。彼らはそれぞれのプロセスとディレクトリで別々に動作することになっています。このファイル構造を考えてみましょう:複数のnode.js HTTPプロセス間で1つのポートを共有する

/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は、その親フォルダ(someProjectanotherProjectなど)へのcwdセットで個別のプロセスとして開始する必要があります。

ov vHostsを考えてください。各プロジェクトは、独自のドメインでリッスンするWebサーバーを開始します。そして、問題があります。私がnode.js APIを掘り下げて、可能な解決策を探しました:child_process.fork()

悲しいことに、これはうまくいきません。サーバーインスタンスをマスタープロセス(後でリクエストを発行する)に送信しようとすると、またはrequestresponseのオブジェクトをconsiveに送信してエラーが発生します。これは、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にバインドし、別のアプリケーションがリッスンする/tmp/distroy/http/www.example.comなどのUnixドメインソケットパスへのすべての要求を内部的にプロキシします。これも(ちょっと)HTTPSのために働く(私の質問SNI参照)。 残りの問題は、元のIPアドレスが失われていることです。現在は常に127.0.0.1です。私は接続を開く前にIPアドレスを送信できるように、net.Serverをmonkeypatchingすることでこれを回避できると思います。

+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をチェックしてください。websocketとhttps対応のhttpルータープロキシ/ロードバランサがnode.jsにあります。

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

のようなあなたのroutes.jsonを定義して、vhost拡張子があり、接続ミドルウェアについて

bouncy routes.json 80 
+0

弾みは[http-proxy](https://github.com/nodejitsu/node-http-proxy)とほぼ同じです。この種のソリューションについて私を悩ますのは、プロジェクトサーバがポート80にバインドする必要があるため、実際には使用しない別のポートにバインドするという事実です。 – buschtoens

+0

httpプロキシで+1してください。 – bryanmac

0

を使用して弾力を実行します。たぶんあなたはそれらの概念のいくつかをコピーすることができます。

+0

Connect's 'vhost'は基本的にこれを行います:' server.emit( 'request'、req、res); '。私はすでにそれを試みた。イベントを発生させるには、子プロセスのサーバーインスタンスを取得する必要があります。 node.jsは内部的にこのインスタンスをストリング化するので、すべての参照が失われ、そこではイベントが発生しません。 – buschtoens

関連する問題