使用 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 托管多个网站的主要内容,如果未能解决你的问题,请参考以下文章
Node.JS、Express 和 MongoDB :: 多个集合
多个域上的 Node.js 使用 express.vhosts()