【问题标题】:Host multiple websites using Node.js Express使用 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 - 在单个服务器中启动多个节点服务器的好解决方案:stackoverflow.com/questions/5009324/node-js-nginx-what-now

标签: node.js express subdomain vhosts forever


【解决方案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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-07-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多