使用 Node.js Express 托管多个网站

Posted

技术标签:

【中文标题】使用 Node.js Express 托管多个网站【英文标题】:Host multiple websites using Node.js Express 【发布时间】:2015-10-11 21:22:29 【问题描述】:

我在配置具有不同域的两个不同 Node.js 应用程序时遇到问题。有两个目录

"/abc/" -> express-admin setup (backend) -> admin.abc.com

"/xyz/" -> express setup (frontend) -> abc.com

我需要 admin.abc.com 指向 express-admin 设置和 abc.com快速设置。我已经安装了 vhost,并且两个站点都监听端口 80。

已添加

app.use(vhost('abc.com', app)); // xyz/app.js file
app.use(vhost('admin.abc.com', app)); // abc/app.js file

我的问题:

forever 已安装,每当我启动这两个应用程序时,第二个总是停止。我尝试为两个应用程序使用不同的端口,但仍然有相同的错误。它们单独运行没有问题。

我认为我的设置对于域转发来说太复杂了。有更好的建议吗?可能是我有一个主 app.js 文件,我可以使用它来将域路由到它们各自的应用程序,而无需使用每个应用程序的 app.js。

【问题讨论】:

您仍然使用相同的网络接口在相同的端口上托管应用程序。所以当第二个应用程序启动时,它总是会找到正在使用的端口。即使使用虚拟主机,您不应该使用不同的端口来托管吗?有关详细信息,请参阅this example。也许您最好使用 node-http-proxy 来保持应用程序完全独立?请参阅this post 进行比较。 谢谢@veggiesaurus node-http-proxy 应该是要走的路。会告诉你进展如何。 请做。我已经添加了一个更详细的问题的答案,以防其他人遇到这个问题。 请考虑 nginx - 在单个服务器中启动多个节点服务器的好解决方案:***.com/questions/5009324/node-js-nginx-what-now 【参考方案1】:

我不确定您是如何使用虚拟主机的。首先,使用 vhost 方法,您只需要运行一个 express 应用程序。不是两个。这是一个例子。

var express = require('express');
var vhost = require('vhost');

/*
edit /etc/hosts:

127.0.0.1       api.mydomain.local
127.0.0.1       admin.mydomain.local
*/

// require your first app here

var app1 = require("./app1");

// require your second app here

var app2 = require("./app2");

// redirect.use(function(req, res)
//   if (!module.parent) console.log(req.vhost);
//   res.redirect('http://example.com:3000/' + req.vhost[0]);
// );

// Vhost app

var appWithVhost = module.exports = express();

appWithVhost.use(vhost('api.mydomain.local', app1)); // Serves first app

appWithVhost.use(vhost('admin.mydomain.local', app2)); // Serves second app

/* istanbul ignore next */
if (!module.parent) 
  appWithVhost.listen(8000);
  console.log('Express started on port 8000');

您只需要使用永久启用 vhost 来运行主 express 应用程序。

【讨论】:

如果使用相同的设置运行大量(比如 20 个)快速应用程序,是否会出现性能问题或其他问题?而且,让我们假设其中 19 个非常轻量级(快速渲染简单的 Jade 模板)——但第 20 个稍微复杂一些,需要更多的 CPU。如果我在 20 个站点中的每个站点上都有 10 个活跃用户,那么正在查看更复杂站点的 10 个是否会导致其他 19 个站点的查看速度变慢? @StandardQuality。 vhost 的问题在于所有这些独立的应用程序都在同一个用户空间中运行。那可能需要在单独的空间中运行它们(例如 Apache 中的 suexec),这样如果一个站点被黑客入侵/崩溃,它就不会感染其他站点。不过,在这个例子中它可能并不重要。看看pm2:pm2.keymetrics.io/docs/usage/startup/#user-permissions【参考方案2】:

您使用相同的网络接口将应用程序托管在同一端口上。所以当第二个应用程序启动时,它总是会找到正在使用的端口。如果你想在同一个端口上使用多个应用程序,它们每个都需要有自己的网络接口。使用 vhost 时,您仍然需要为每个应用程序侦听不同的端口。有关详细信息,请参阅this example。如果您希望您的应用程序完全独立,则最好使用 node-http-proxy。这允许您在端口 80 上托管一个代理,该代理转发请求以表达在不同端口上侦听的应用程序。如果其中一个应用程序崩溃,它不会使另一个应用程序崩溃,这与虚拟主机方法不同。 This post 给出了一个使用 node-http-proxy 实现的例子。

【讨论】:

【参考方案3】:

感谢 @veggiesaurus 指向 node-http-proxy。很抱歉发布迟了。

这是我使用 node-http-proxy 解决问题的方法

文件夹结构:

www/ server.js abc/ [快速设置] app.js xyz/ [express-admin 设置] node_modules/express-admin/app.js

“abc”和“xyz”有自己的设置并在端口 x.x.x.x:3001 和 x.x.x.y:3002 上运行

我安装了 node-http-proxy 并添加了带有以下代码的 server.js 文件。引用了这个link

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

var proxy = httpProxy.createProxy();
var options =   
  'abc.com': 'http://x.x.x.x:3001',
  'xyz.com': 'http://x.x.x.y:3002'


http.createServer(function(req, res) 
  proxy.web(req, res, 
    target: options[req.headers.host]
  );
).listen(80);

最后,使用永远运行所有 3 个应用程序设置为在端口 3001、3002 和 80 中永远运行。

【讨论】:

【参考方案4】:
const express = require("express");
const app = express();
const fs = require('fs');
app.use((req, res, next) => 
    let reqDomain = req.get("host");
    if (reqDomain.indexOf(":") > -1) 
        reqDomain = reqDomain.split(":")[0];
    
    if(reqDomain.endsWith(".local")) 
        reqDomain = reqDomain.substring(0, reqDomain.length - 6);
    
    const domainPath = "public/" + reqDomain;
    let filePath = domainPath + req.originalUrl;
    filePath = fs.lstatSync(filePath).isDirectory() ? filePath + "/index.html" : filePath;
    console.log(__dirname + "/" + filePath);
    res.sendFile(filePath,  root: __dirname );
);
const port = process.env.PORT || 80;
app.listen(port, () => console.log("Server Started on Port " + port));

public 目录中放置您的文件夹,例如“my-first-website.com”、“my-second-website.com”

在 /etc/hosts 中添加以下内容进行本地测试

127.0.0.1 my-first-website.com.local
127.0.0.1 my-second-website.com.local

【讨论】:

以上是关于使用 Node.js Express 托管多个网站的主要内容,如果未能解决你的问题,请参考以下文章

初识 Express 丨Node.js

Node.JS、Express 和 MongoDB :: 多个集合

多个域上的 Node.js 使用 express.vhosts()

在带有 Node 和 Express 的 IE10 中使用 CORS 的安全错误

django、node js、php网站托管和域信息

Express (RoutingMiddleware托管静态文件view engine 等等)