Node.js "server" 与 Nginx 或 Apache 服务器相比如何?
How does a Node.js "server" compare with Nginx or Apache servers?
我最近一直在研究 Node.js 并遇到了一些 material 关于编写简单的基于 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 到 运行 之类的东西中,这不是真的吗?那为什么都叫“服务器”呢?
NodeJs 创建自己的服务器。如您所见,术语非常清楚:
http.createServer(app).listen(3000);
创建服务器并监听 3000 端口上的 http 请求。
我们在一个项目中使用了 nginx,但它更像是多个 nodejs 实例的负载均衡器。
假设您在端口 3000 和 3001 上有两个 nodejs 实例 运行,
现在您仍然可以使用 nginx
作为服务器来监听您在 port 80
上的实际 http
调用,并且可能希望将您的请求重定向到 nodejs
服务器或其他服务器,更像是 loadbalancer
。所以你仍然可以使用 nginx
提供的任何东西 nodejs
.
已经问了一个好问题 here。
这是一个服务器,是的。
node.js 网络应用程序是一个成熟的网络服务器,就像 Nginx 或 Apache。
您确实可以在不使用任何其他 Web 服务器的情况下为您的 node.js 应用程序提供服务。只需将您的代码更改为:
app = express();
http.createServer(app).listen(80); // serve HTTP directly
确实,一些项目使用 node.js 作为其他服务器(包括 Apache)的 前端 负载平衡器。
请注意,node.js 并不是执行此操作的唯一开发堆栈。 Go 中的 Web 开发框架,Java 和 Swift 也这样做。
为什么?
一开始是CGI。 CGI 很好,工作正常。 Apache 会收到一个请求,发现 url 需要执行 CGI 应用程序,执行该 CGI 应用程序并将数据作为环境变量传递,读取标准输出并将数据返回给浏览器。
问题是它很慢。当 CGI 应用程序是一个小型静态编译的 C 程序时,这很好,但是一组小型静态编译的 C 程序变得难以维护。所以人们开始用脚本语言编写。然后这变得难以维护,人们开始开发面向对象的 MVC 框架。现在我们开始遇到麻烦 - 每个请求都必须编译所有这些 类 并创建所有这些对象只是为了服务一些 HTML,即使没有任何动态服务(因为框架需要弄清楚没有什么动态服务)。
如果我们不需要在每次请求时都创建所有这些对象怎么办?
人们就是这么想的。为了解决这个问题,出现了几种策略。最早的方法之一是将解释器直接嵌入到 Web 服务器中,例如 Apache 中的 mod_php
。编译 类 和对象可以存储在全局变量中,因此可以缓存。另一种策略是进行预编译。另一种策略是 运行 将应用程序作为常规服务器进程,并使用 FastCGI 等自定义协议与 Web 服务器通信。
然后一些开发人员开始简单地使用 HTTP 作为他们的 app->server 协议。实际上,该应用程序也是一个 HTTP 服务器。这样做的好处是您不需要实施任何新的、可能有错误的、可能未经测试的协议,您可以直接使用网络浏览器(或者通常,curl
)调试您的应用程序。而且您不需要经过修改的网络服务器来支持您的应用程序,只需任何可以进行反向代理或重定向的网络服务器即可。
为什么要使用Apache/Nginx?
当您提供 node.js 应用程序时,请注意您是您自己的网络服务器的作者。您应用中的任何潜在错误都是互联网上可直接利用的错误。有些人(有理由)对此感到不舒服。
在您的 node.js 应用程序前面添加一层 Apache 或 Nginx 意味着您在实时互联网上拥有经过实战检验、安全强化的软件作为您的应用程序的界面。它增加了一点点延迟(反向代理),但大多数人认为这是值得的。
这曾经是 node.js 早期的标准建议。但现在也有一些网站和网络服务直接将 node.js 暴露给互联网。 http.Server
模块现在在 Internet 上经过了相当好的实战测试,值得信赖。
假设有一家名为 Apache Hotel 的酒店,为每位顾客配备一名服务员。
顾客一点沙拉,服务员就去找厨师告诉他。厨师准备食物时,服务员等待。在这里,
Chef => File System,
Waiter => Thread,
Customer => Event.
即使顾客点水,服务员也只是在上色拉后才送来。
服务员一直等到厨师准备好沙拉。这种状态被称为阻塞状态。即使酒店发展壮大,每个顾客也应该有不同的服务员来服务。这增加了线程(等待者)的阻塞。
现在,来到节点酒店,所有客人只需要一个服务员。如果第一位顾客点了汤,服务员会告诉厨师然后去找第二位顾客。食物准备好后,服务员将食物送到顾客面前。在这里,客户不会等待。这种状态被称为非阻塞状态。单个服务员(线程)服务所有客户并让他们开心。
因此,作为单线程应用程序的 Node 非常快。
我最近一直在研究 Node.js 并遇到了一些 material 关于编写简单的基于 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 到 运行 之类的东西中,这不是真的吗?那为什么都叫“服务器”呢?
NodeJs 创建自己的服务器。如您所见,术语非常清楚:
http.createServer(app).listen(3000);
创建服务器并监听 3000 端口上的 http 请求。
我们在一个项目中使用了 nginx,但它更像是多个 nodejs 实例的负载均衡器。
假设您在端口 3000 和 3001 上有两个 nodejs 实例 运行,
现在您仍然可以使用 nginx
作为服务器来监听您在 port 80
上的实际 http
调用,并且可能希望将您的请求重定向到 nodejs
服务器或其他服务器,更像是 loadbalancer
。所以你仍然可以使用 nginx
提供的任何东西 nodejs
.
已经问了一个好问题 here。
这是一个服务器,是的。
node.js 网络应用程序是一个成熟的网络服务器,就像 Nginx 或 Apache。
您确实可以在不使用任何其他 Web 服务器的情况下为您的 node.js 应用程序提供服务。只需将您的代码更改为:
app = express();
http.createServer(app).listen(80); // serve HTTP directly
确实,一些项目使用 node.js 作为其他服务器(包括 Apache)的 前端 负载平衡器。
请注意,node.js 并不是执行此操作的唯一开发堆栈。 Go 中的 Web 开发框架,Java 和 Swift 也这样做。
为什么?
一开始是CGI。 CGI 很好,工作正常。 Apache 会收到一个请求,发现 url 需要执行 CGI 应用程序,执行该 CGI 应用程序并将数据作为环境变量传递,读取标准输出并将数据返回给浏览器。
问题是它很慢。当 CGI 应用程序是一个小型静态编译的 C 程序时,这很好,但是一组小型静态编译的 C 程序变得难以维护。所以人们开始用脚本语言编写。然后这变得难以维护,人们开始开发面向对象的 MVC 框架。现在我们开始遇到麻烦 - 每个请求都必须编译所有这些 类 并创建所有这些对象只是为了服务一些 HTML,即使没有任何动态服务(因为框架需要弄清楚没有什么动态服务)。
如果我们不需要在每次请求时都创建所有这些对象怎么办?
人们就是这么想的。为了解决这个问题,出现了几种策略。最早的方法之一是将解释器直接嵌入到 Web 服务器中,例如 Apache 中的 mod_php
。编译 类 和对象可以存储在全局变量中,因此可以缓存。另一种策略是进行预编译。另一种策略是 运行 将应用程序作为常规服务器进程,并使用 FastCGI 等自定义协议与 Web 服务器通信。
然后一些开发人员开始简单地使用 HTTP 作为他们的 app->server 协议。实际上,该应用程序也是一个 HTTP 服务器。这样做的好处是您不需要实施任何新的、可能有错误的、可能未经测试的协议,您可以直接使用网络浏览器(或者通常,curl
)调试您的应用程序。而且您不需要经过修改的网络服务器来支持您的应用程序,只需任何可以进行反向代理或重定向的网络服务器即可。
为什么要使用Apache/Nginx?
当您提供 node.js 应用程序时,请注意您是您自己的网络服务器的作者。您应用中的任何潜在错误都是互联网上可直接利用的错误。有些人(有理由)对此感到不舒服。
在您的 node.js 应用程序前面添加一层 Apache 或 Nginx 意味着您在实时互联网上拥有经过实战检验、安全强化的软件作为您的应用程序的界面。它增加了一点点延迟(反向代理),但大多数人认为这是值得的。
这曾经是 node.js 早期的标准建议。但现在也有一些网站和网络服务直接将 node.js 暴露给互联网。 http.Server
模块现在在 Internet 上经过了相当好的实战测试,值得信赖。
假设有一家名为 Apache Hotel 的酒店,为每位顾客配备一名服务员。
顾客一点沙拉,服务员就去找厨师告诉他。厨师准备食物时,服务员等待。在这里,
Chef => File System,
Waiter => Thread,
Customer => Event.
即使顾客点水,服务员也只是在上色拉后才送来。 服务员一直等到厨师准备好沙拉。这种状态被称为阻塞状态。即使酒店发展壮大,每个顾客也应该有不同的服务员来服务。这增加了线程(等待者)的阻塞。
现在,来到节点酒店,所有客人只需要一个服务员。如果第一位顾客点了汤,服务员会告诉厨师然后去找第二位顾客。食物准备好后,服务员将食物送到顾客面前。在这里,客户不会等待。这种状态被称为非阻塞状态。单个服务员(线程)服务所有客户并让他们开心。
因此,作为单线程应用程序的 Node 非常快。