16

我正在同时运行 Nodejs 和 Apache。

node-http-proxy 正在侦听端口 80,然后将请求转发到 Apache(:9000) 或 Express(:8000)。

我在 Apache 上的虚拟主机如下所示:

<VirtualHost 127.0.0.1>
    DocumentRoot "/localhost/myVhost"
    ServerName myVhost
</VirtualHost>

我的问题是,在 Express/Nodejs 端拥有类似 vhost 的功能的“正确”方式是什么?我宁愿不必像这里建议的那样将每个 Nodejs 应用程序放在自己的端口上:

https://github.com/nodejitsu/node-http-proxy (标题为“使用‘仅主机名’ProxyTable的代理请求”部分)

我注意到 Connect(据我了解,它捆绑在 Express 中)具有一些虚拟主机功能。我应该使用那个吗?如果是这样,与 node-http-proxy 一起运行它的正确方法是什么?

http://www.senchalabs.org/connect/middleware-vhost.html

我还注意到另一个名为“Cluster”的模块,它似乎是相关的,但我不确定如何:

http://learnboost.github.com/cluster/

虽然不想让人不知所措,但我也遇到了一个名为“Haibu”的东西,它似乎是相关的,但我不确定它是否只是使用虚拟主机的全面替代品:

https://github.com/nodejitsu/haibu

注意:我是前端的人,所以对很多服务器术语不是很熟悉

4

4 回答 4

11

我从来没有弄清楚 Haibu 或 Cluster。但我确实找到了一个很好的解决方案来解决我的问题。令我惊讶的是,它实际上非常简单。但是,我对服务器知之甚少,所以虽然这可行,但它可能不是最佳的。

我在 Apache 上设置了正常的虚拟主机(http://httpd.apache.org/docs/2.0/vhosts/examples.html)

我在节点上安装了以下

  • 快递 (http://expressjs.com/)
  • 节点-http-proxy (https://github.com/nodejitsu/node-http-proxy)

然后,作为个人风格,我将所有虚拟主机放在一个公共目录(/localhost)中

然后,我将 Apache 切换到侦听端口 80 以外的端口。我只是碰巧选择了端口 9000,因为我曾看到它在某处使用过。(在 httpd.conf 中,将“Listen 80”更改为“Listen 9000”)。我还必须确保我的所有虚拟主机(在 extra/httpd-vhosts.conf 中定义)都设置为基于 IP 的 nameVirtualHost (127.0.0.1) 而不是使用端口 (*:80)。

在节点方面,我创建了我的应用程序/服务器(又名节点虚拟主机),它在端口 8000 上侦听(端口号的任意选择)请参阅此链接以使用 express 创建服务器: http: //expressjs.com/guide。 html

然后在我的 /localhost 目录中创建了一个名为“nodeHttpProxy.js”的文件

使用 node-http-proxy,在 nodeHttpProxy.js 中,我创建了一个代理服务器,侦听端口 80。使用包含连接 (http://www.senchalabs.org/connect/) 的 express,我创建了我的虚拟主机。

nodeHttpProxy.js 文件如下所示:

// Module dependancies
var httpProxy = require('/usr/local/lib/node_modules/http-proxy/lib/node-http-proxy')
, express = require('/usr/local/lib/node_modules/express/lib/express');

// Http proxy-server
httpProxy.createServer(function (req, res, proxy) {

    // Array of node host names
    var nodeVhosts = [
        'vhost1'
        , 'vhost2'
    ]
    , host = req.header('host')
    , port = nodeVhosts.indexOf(host) > -1
        ? 8000
        : 9000;

    // Now proxy the request
    proxy.proxyRequest(req, res, {
        host: host
        , port: port
    });
})
.listen(80);

// Vhosts server
express.createServer()
.use(express.vhost('vhost1', require('./vhost1/app')))
.use(express.vhost('vhost2', require('./vhost2/app')))
.app.listen(8000);

如您所见,每次创建新的 Node 虚拟主机时,我都必须做两件事:

  1. 将虚拟主机名添加到我的“nodeVhosts”数组中
  2. 使用 .set 方法定义一个新的 express 虚拟主机

当然,我还必须在我的 /localhost 目录中创建实际的主机路径/文件。

完成所有这些后,我只需要运行 nodeHttpProxy.js:

node nodeHttpProxy.js

您可能会收到一些奇怪的“EACCESS”错误,在这种情况下,只需以 sudo 身份运行。

它将侦听端口 80,如果主机匹配 nodeVhosts 数组中的名称之一,它将请求转发到端口 8000 上的该主机,否则它将转发请求到端口 9000 上的该主机。

于 2012-03-10T08:42:29.363 回答
6

我最近一直在考虑这一点,因为我在我的个人测试环境中解决了同样的问题。您将无法让每个节点应用程序在其自己的端口上运行,但您可以抽象出该过程的痛苦。这是我现在使用的,但我希望围绕它构建一个 npm 包以简化未来的事情。

我的每个 node.js 应用程序都有一个映射文件,其中包含应用程序正在侦听的端口以及指示应用程序正在服务的预期路径的映射。该文件的内容如下所示:

{"path": "domain.com/path", "port": 3001}

当我启动我的应用程序时,它会从 map.json 文件中读取端口并监听指定的端口。

var map = fs.readFileSync('map.json', 'ascii');
app.listen(map.port);

然后在我的代理设置中,我遍历我的每个 node.js 应用程序目录,并检查一个 map.json 文件,该文件指示端口 80 流量应该代理到这个应用程序。

我也使用几乎完全相同的方法为我们的 apache 托管应用程序设置代理。我们在所服务的 PHP 网站上使用基于文件夹的约定,它使用以下配置:

VirtualDocumentRoot /var/www/%-2.0.%-1/%-3+/
VirtualScriptAlias /var/www/%-2.0.%-1/%-3+/cgi-bin/

这实质上允许我们使用以下结构将域映射到文件夹。

http://sub.domain.com/ = /var/www/domain.com/sub/

添加或删除站点不需要额外的配置。这与我目前用于代理 apache 和节点站点的方式非常接近。我可以在不修改此代理应用程序的情况下添加新节点和新 apache 站点。

代理.js

var fs = require('fs');
var httpProxy = require('http-proxy');

var proxyTable = [];

// Map apache proxies
fs.readdirSync('/var/www/').forEach(function(domain) {
    fs.readdirSync('/var/www/' + domain).forEach(function(path) {
        var fqd = domain + '/' + path;
        var port = fs.readFileSync('port', 'ascii');
        proxyTable[fqd] = fqd + ':' + 8080;
    });
});    

// Map node proxies
fs.readdirSync('/var/www-node/').forEach(function(domain) {
        var map = fs.readFileSync('map.json', 'ascii');
        proxyTable.[map.path] = '127.0.0.1:' + map.port;
});

var options = {
    router: proxyTable
};

var proxyServer = httpProxy.createServer(options);
proxyServer.listen(80);

将来,我可能会将路径与应用程序正在侦听的端口分离,但这种配置允许我用很少的工作自动构建代理映射。希望这会有所帮助。

于 2012-02-20T23:38:24.580 回答
0

我从@uglymunky 那里获得了一些灵感,并编写了一个厨师脚本来在 Ubuntu 上执行此操作。

使用此脚本,您可以在从 github 拉下我的 chef 项目后,使用 1 行在单个服务器上安装 express 和 apache 以及 vhost 支持

https://github.com/toranb/ubuntu-web-server

如果你安装了 git 并且你把它拉下来,你可以像这样开始它......

sudo ./install.sh configuration.json

这确实需要 Ubuntu 12.04 或更高版本,因为我在重新启动机器时利用了 upstart 脚本来启动节点

脚本完成后,您将拥有一个运行良好的 ubuntu Web 服务器,它可以运行您配置的任何节点应用程序,以及运行您配置的任何 wsgi 应用程序的 apache

于 2012-07-26T10:59:23.787 回答
0

我正在开发一个可以与您的项目完全隔离的极小且重要的库。基本上,这个想法将在您的服务器上独立运行,并且不必担心必须如何将其捆绑到您的项目中。

看看 config.json 文件,看看它实际上是多么简单。

我一直在寻找这个,我确实找到了一些东西,但它们不支持我需要的一切,特别是 HTTPS、WS 和 WSS!

现在我写的库只适用于 HTTP。但在接下来的几天里,我希望完成它并为 HTTPS、WS 和 WSS 工作。

于 2013-06-08T09:22:18.667 回答