如何在同一系统上组织多个Express服务器?

46

我正在使用一个服务器托管多个分布在多个域上的Node.js Web应用。我的当前做法是在不同的端口上运行每个应用程序的Express服务器,并运行一个基础服务器,仅将请求路由(重定向)到正确的端口/Express服务器。这样可以工作,但意味着我的基础服务器正在路由每个HTTP请求(并通过手动重定向),而我的用户将我的应用程序视为托管在[hostname.com]:8000。

经过一些研究,我发现我可以使用http-proxy来满足我的路由需求,但我仍然想知道在同一系统上运行多个Express服务器的最佳实践。以下是我的计划:

每个Web应用程序都将拥有自己的文件夹,具有完整的Express文件夹结构(app.js、routes、views等)。应用程序将按域分组,因此示例文件夹结构如下:

    hostname.com/
        app.js
        routes/
        views/
        ...
        app1/
            app1.js
            routes/
            views/
            ...
        app2
        ...
    hostname2.com/
        app.js
        routes/
        views/
        ...

我需要使用Node(或者我目前正在使用的 forever)分别运行每个app.js文件,每个文件都必须在内部使用不同的端口,并将跨应用程序重定向指向目标应用程序的端口。

所以,这是我的当前计划。有哪些问题和陷阱我应该避免呢? 最重要的是,是否存在解决此问题的既定方案-在Node.js / Express系统上托管多个Web应用程序的问题?

编辑:我确实打算最终使用WebSockets和HTTPS,而我设置可以支持的带宽量对我来说并不重要-这是一个开发服务器(至少现在是这样)。感谢David Ellis提出WebSockets的问题。

第二次编辑:感谢EhevuTov和David Ellis的回答,两位都给了我很大帮助。我仍在确定我的应用程序的总体结构,看起来这个StackOverflow问题详细解答了这个问题。

第三次编辑:自发表这个问题以来,我已经取得了一些进展(虽然还有很长的路要走)。请查看我在GitHub存储库中的此文件,它利用了我从这个问题的答案中学到的东西!

3个回答

36

由于Express使用了Connect,所以我相信你可以使用Connect的虚拟主机中间件。它的操作方式类似于其他产品上的vhost模块。我没有多个域名进行测试并展示适当的代码,但我认为应该是这样的:

express.createServer()
.use(express.vhost('hostname1.com', require('/path/to/hostname1').app)
.use(express.vhost('hostname2.com', require('/path/to/hostname2').app)
.listen(80)
如果你到了一个 Express 服务器不够的地步,那么请研究使用 API 中的 Node.Cluster。如果这仍然不够,则当前的做法是在 Express 服务器前放置像 Nginx 这样的异步反向代理,并将代理指向 Express 服务器。

感谢您的评论。我已经开始使用vhost(在#express中得到了一些有用的IRC用户的帮助),它运行得非常好。同时,也感谢您提醒我可以考虑升级到Node.Cluster。 - Aaron
@Aaron,你有一些代码可以分享给我们展示一下你是如何做到的吗? - Matt
@Matt 嗯,看看我在帖子中的第三次编辑。我添加了一个指向我的GitHub存储库的链接。 - Aaron

7
如果你不需要使用WebSockets(或任何HTTP 1.1功能),可以使用NginX作为代理。优点在于NginX可以处理的总负载比Node更高(基本上是静态编译和专门为此类事物设计的),但你失去了流式传输任何数据的能力(一次只发送较小的块)。对于规模较小的站点,或者如果您不确定未来需要哪些功能,最好使用node-http-proxy并仅在证明代理是服务器瓶颈时再切换到NginX。幸运的是,如果以后确实需要它,设置NginX并不难。

1
我计划最终使用WebSockets和HTTPS,并且我的设置可以支持的带宽量对我来说并不重要 - 这是一个开发服务器(至少目前是这样)。感谢提出WebSockets问题。然而,我的问题是关于反向代理服务器之后组织系统的一个步骤 - 我应该如何为我的多个Web应用程序设置并组织Express服务器? - Aaron
我认为Node.js还年轻,没有针对在同一服务器上运行多个Express应用程序的已建立模式。Node.js与Tomcat/Getty和其他基于Java的Web服务器有更多共同点;一个服务器一个应用程序,而传统上使用单个Web服务器(Apache/NginX/Lighttpd等)来托管多个网站。每个Node.js Web应用程序必须配置为不使用另一个Web应用程序使用的TCP端口,因此没有“拖放”方式来设置它。 - user1207456
2
此外,由于Node.js HTTP服务器可以设置为仅监听特定主机名的端口(http://nodejs.org/docs/v0.6.10/api/http.html#server.listen),因此您*可以*将整个设置为一个Node.js进程同时运行多个Express服务器。当然,当这些服务器彼此之间从不接触代码且Node.js进程开销仅为几兆字节时,这几乎没有意义,但这也是一种“选择”。 - user1207456
感谢指出 listen() 接受一个可选的主机名参数!目前我使用单个 Node.js 进程来处理 5 个虚拟主机,但使用 listen(port, hostname),我将能够独立运行应用程序! - Aaron

0
const express = require('express')
const cors = require('cors')
server=express()
server2=express()
server.use(cors())
server2.use(cors())

server.get('/',(req,res)=>res.send({"server":"3001","name":"aakash4dev","data":"some data 1"}))
server.get('/blog/:id',(req,res)=>res.send({"server":"3001","name":"aakash4dev","data":"some data 1"}))

server2.get('/',(req,res)=>res.send({"server":"3002","name":"aakash4dev","data":"some data 2"}))
server2.get('/something/',(req,res)=>res.send({"server":"3002","name":"aakash4dev","data":"some data 2"}))

server.listen(3001)
server2.listen(3002)

正如我在问题中提到的:“我的当前做法是为每个应用程序运行一个Express服务器,并在不同的端口上运行一个基本服务器,仅将请求路由(重定向)到正确的端口/Express服务器。这样做可以工作,但意味着我的基本服务器正在路由每个HTTP请求(并通过手动重定向它),而我的用户会看到我的应用程序托管在[hostname.com]:8000。”我正在寻找一种方法来拥有多个应用程序的单个入口点(代理),正如我在上面的答案中提到的,express.vhost解决了这个问题。 - Aaron
抱歉,以下是翻译的文本:你可以尝试使用 fsconst fs = require('fs'); fs.readdir(testFolder, (err, files) => { files.forEach(file => { console.log(file); }); }); 获取文件夹中 HTML 文件的文件名。 以上代码将返回类似于 ["index.html","about.html","blog.html"] 的内容。 根据文件名使用 forEach 循环创建服务器。 - aakash4dev
1
我很感激你想要帮忙,但是你对一个已经解决的问题提出了不适用的答案,而且这个问题已经超过10年了。我很好,谢谢。 - Aaron

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接