Node.js“服务器”与 Nginx 或 Apache 服务器相比如何?
Posted
技术标签:
【中文标题】Node.js“服务器”与 Nginx 或 Apache 服务器相比如何?【英文标题】:How does a Node.js "server" compare with Nginx or Apache servers? 【发布时间】:2016-12-13 19:12:18 【问题描述】:我最近一直在研究 Node.js,并且偶然发现了一些关于编写基于 Node.js 的简单服务器的资料。比如下面的。
var express = require("express"),
http = require("http"), app;
// Create our Express-powered HTTP server
// and have it listen on port 3000
app = express();
http.createServer(app).listen(3000);
// set up our routes
app.get("/hello", function (req, res)
res.send("Hello World!");
);
app.get("/goodbye", function (req, res)
res.send("Goodbye World!");
);
现在,虽然我似乎理解了代码中发生了什么,但我对术语感到有些困惑。当我听到服务器一词时,我会想到 Apache 或 nginx 之类的东西。我习惯于将它们视为可以容纳我的 Web 应用程序的容器。 Node.js 服务器与 Nginx/Apache 服务器有何不同?基于 Node.js 的服务器(即代码)是否仍然可以放置在 Nginx 之类的东西中运行?那为什么都叫“服务器”呢?
【问题讨论】:
Isn't it true that a Node.js based server (i.e. code) will still be placed within something like Nginx to run?
不,不正确
从技术上讲,您可以运行您的应用程序并让节点将其提供给客户端,从而有效地充当网络服务器的角色,但您可能比您想要咀嚼的更多。我最近阅读了这篇关于该主题的精彩文章:nginx.com/blog/nginx-vs-apache-our-view
让我澄清一下,当我询问两者之间的区别时,我并没有考虑 apache 和 nginx。我正在讨论 Node.js 与 Nginx。
不要让标题误导你。如果你读了这篇文章,你就会明白为什么我说虽然你可以自己做,但你可能不想......
【参考方案1】:
它是一个服务器,是的。
node.js Web 应用程序是一个成熟的 Web 服务器,就像 Nginx 或 Apache。
您确实可以在不使用任何其他 Web 服务器的情况下为您的 node.js 应用程序提供服务。只需将您的代码更改为:
app = express();
http.createServer(app).listen(80); // serve HTTP directly
确实,一些项目使用 node.js 作为其他服务器(包括 Apache)的前端负载平衡器。
请注意,node.js 并不是唯一这样做的开发堆栈。 Go、Java 和 Swift 中的 Web 开发框架也可以做到这一点。
为什么?
一开始是CGI。 CGI 很好,工作正常。 Apache 会收到一个请求,发现该 url 需要执行一个 CGI 应用程序,执行该 CGI 应用程序并将数据作为环境变量传递,读取标准输出并将数据返回给浏览器。
问题是它很慢。当 CGI 应用程序是一个小的静态编译的 C 程序但一组小的静态编译的 C 程序变得难以维护时,这没关系。所以人们开始用脚本语言写作。然后这变得难以维护,人们开始开发面向对象的 MVC 框架。现在我们开始遇到麻烦了 - 每个请求都必须编译所有这些类并创建所有这些对象以提供一些 html,即使没有任何动态可以提供服务(因为框架需要确定没有任何动态可以提供服务)。
如果我们不需要在每个请求中创建所有这些对象怎么办?
这是人们的想法。试图解决这个问题产生了几种策略。最早的方法之一是将解释器直接嵌入 Web 服务器中,例如 Apache 中的 mod_php
。编译的类和对象可以存储在全局变量中,因此可以缓存。另一种策略是进行预编译。另一种策略是将应用程序作为常规服务器进程运行,并使用自定义协议(如 FastCGI)与 Web 服务器通信。
然后一些开发人员开始简单地使用 HTTP 作为他们的应用程序->服务器协议。实际上,该应用程序也是一个 HTTP 服务器。这样做的好处是您不需要实现任何新的、可能有错误的、可能未经测试的协议,并且您可以直接使用 Web 浏览器(或者通常,curl
)调试您的应用程序。而且您不需要修改过的 Web 服务器来支持您的应用,只需任何可以进行反向代理或重定向的 Web 服务器即可。
为什么要使用 Apache/Nginx?
当您为 node.js 应用程序提供服务时,请注意您是您自己的 Web 服务器的作者。您的应用程序中的任何潜在错误都是互联网上可直接利用的错误。有些人(有理由)对此感到不舒服。
在您的 node.js 应用程序前面添加一个 Apache 或 Nginx 层意味着您在实时互联网上拥有一个经过实战考验、安全加固的软件,作为您的应用程序的接口。它增加了一点延迟(反向代理),但大多数人认为这是值得的。
这曾经是 node.js 早期的标准建议。但是现在也有一些网站和 Web 服务将 node.js 直接暴露在互联网上。 http.Server
模块现在在互联网上经过了很好的实战测试,值得信赖。
【讨论】:
我在类似的 SO 线程中读到,将 Nginx 或 Apache 层放在 Node 前面“带走了它的非阻塞性质”。对此有什么想法吗? @MrfksIV Nginx 和 Apache2 都是非阻塞的。事实上,他们早在 node.js 存在之前就实现了非阻塞。不要使用 Apache1 关于node-cgi使用什么架构的任何想法?我的印象是它是经典的基于线程的架构(因此每个请求都有自己的线程),而我需要一个具有基于事件架构的托管服务提供商(每个请求都在同一个线程上处理)。如果我不想要云服务、docker 等运行 nodejs、支持 websocket 等的东西,我不知道哪个托管服务提供商支持这种架构。 @inf3rno 如果是 CGI,那么它就是 CGI,所以它确实是最糟糕的扩展架构,因为它消耗大量 RAM。然而,节点进程在启动时通常只占用大约 30MB 的内存,所以不像 Java 那样糟糕。 CGI 甚至不是基于线程的。它是基于过程的。每个请求都会产生一个新进程(应用程序)并使用环境变量将数据发送到进程(是的,按照现代标准,这很尴尬,但如果您刚刚在 unix 上学习了 C 编程,那么这很容易,因为您不需要学习任何有关 tcp/ip 或插座) @inf3rno 用于托管运行 Web 应用程序支持节点的最流行方式之一:Heroku。有很多提供者也提供 node.js 托管。只需谷歌“nodejs托管”。但是,即使您最终没有使用它,我也鼓励您查看 AWS。他们赠送 1 年免费帐户。它们提供了一切,从可以安装任何操作系统的虚拟硬件到可以上传 docker 映像以运行的容器运行器,再到应用程序运行器,您只需将代码提供给他们,甚至只运行您不运行的功能。甚至给他们一个完整的应用程序【参考方案2】:NodeJs 创建自己的服务器。如您所见,术语很清楚:
http.createServer(app).listen(3000);
创建一个服务器并在 3000 端口监听 http 请求。
我们在一个项目中使用了 nginx,但它更像是多个 nodejs 实例的负载均衡器。
假设您有两个 nodejs 实例在端口 3000 和 3001 上运行,
现在您仍然可以使用nginx
作为服务器来监听您对port 80
的实际http
调用,并且可能希望将您的请求重定向到nodejs
服务器或其他一些服务器,更像loadbalancer
。所以你仍然可以使用nginx
与nodejs
提供的任何东西。
here 已经提出了一个很好的问题。
【讨论】:
其实我并不太关注nginx本身。我想知道 node.js“服务器”与 apache 或 nginx 等其他“服务器”之间的区别。我无法理解包含的(即节点代码)如何等同于容器(即 apache)......但我想这种理解是不正确的。现在,我意识到 node.js 代码侦听端口 3000 就像 Apache 侦听端口 80 .... 所以我猜它们是相似的。所以说他们都是各有优劣的服务器是真的吗? createServer 只是创建一个监听端口。它不提供任何服务。 如果 nodejs 不会根据请求向该端口提供服务,那么让 nodejs 使用 createServer 来侦听端口有什么意义? ...因此,通过逻辑扩展,它是“服务器”的一种或另一种方式,不是吗? @RogerF.Gay... 它在指定端口上创建一个侦听器,并在传入请求时执行回调函数。这就是我要说的它创建一个服务器。 @Naeem Shaikh 它没有任何作用。将不提供任何服务的东西称为服务器是没有意义的。【参考方案3】:假设有一家名为 Apache Hotel 的酒店,为每位顾客配备一名服务员。
顾客一点沙拉,服务员就去找厨师告诉他。当厨师准备食物时,服务员在等待。这里,
Chef => File System,
Waiter => Thread,
Customer => Event.
即使顾客点了水,服务员也只是在上完沙拉后才送来。 服务员一直等到厨师准备好沙拉。这种状态称为阻塞状态。即使酒店发展壮大,每个顾客也应该有不同的服务员来服务。这增加了线程(等待者)的阻塞。
现在,来到节点酒店,所有顾客都只有一名服务员。如果第一位顾客点汤,服务员会告诉厨师,然后去找第二位顾客。食物准备好后,服务员将食物送到顾客手中。在这里,客户不会等待。这种状态称为非阻塞状态。单个服务员(线程)为所有客户服务并让他们开心。
因此,Node 作为单线程应用程序非常快。
【讨论】:
以上是关于Node.js“服务器”与 Nginx 或 Apache 服务器相比如何?的主要内容,如果未能解决你的问题,请参考以下文章
WebSocket 错误,意外响应代码:200 与 Nginx 和 Node.js