仅使用 Node.js 与将 Node.js 与 Apache/Nginx 一起使用

Posted

技术标签:

【中文标题】仅使用 Node.js 与将 Node.js 与 Apache/Nginx 一起使用【英文标题】:Using Node.js only vs. using Node.js with Apache/Nginx 【发布时间】:2013-05-22 03:54:00 【问题描述】:

在什么情况下,在实际部署中应该更愿意将 Node.js 仅用作服务器?

当一个人只想使用 Node.js 时,Node.js 有什么更好的选择? Apache 还是 nginx

【问题讨论】:

【参考方案1】:

在 Node.js 前面放置另一个网络服务器有几个很好的理由:

不必担心 Node.js 进程的权限/setuid。通常只有 root 可以绑定到端口 80。如果您让 nginx/Apache 担心以 root 身份启动,绑定到端口 80,然后放弃其 root 权限,这意味着您的 Node 应用程序不必担心。 提供静态文件,如图像、css、js 和 html。与使用适当的静态文件 Web 服务器相比,Node 可能效率较低(Node 在某些情况下也可能更快,但这不太可能成为常态)。除了更有效地提供文件之外,您不必担心处理 eTag 或缓存控制标头的方式,就像您在 Node.js 之外提供服务时那样。一些框架可能会为您处理这个问题,但您需要确定一下。无论如何,可能还是会慢一些。 正如 Matt Sergeant 在他的回答中提到的,如果您的节点服务崩溃,您可以更轻松地显示有意义的错误页面或退回到静态站点。否则用户可能只是连接超时。 在 Node 前面运行另一个 Web 服务器可能有助于缓解针对 Node.js 的安全漏洞和 DoS 攻击。例如,CVE-2013-4450 是 prevented by running something like Nginx in front of Node。

我将警告第二个要点,您可能应该通过 CDN 或从像 Varnish 这样的缓存服务器后面提供静态文件。如果您这样做,那么源是 Node、Nginx 还是 Apache 并不重要。

特别注意 nginx:如果您使用的是 websockets,请确保使用最新版本的 nginx (>= 1.3.13),因为它只是添加了对升级连接以使用 websockets 的支持。

【讨论】:

express.static 可以很好地处理 ETag 和缓存控制标头。 节点不是很好吧? centminmod.com/siegebenchmarks/2013/020313/index.html, zgadzaj.com/… pauljz,你有基准来备份慢吗? @pawlakpp 指出的文章似乎说 Node.js 在负载下要快得多。 这里有一些相关的讨论:***.com/questions/9967887/… 有一些额外的观点。那里的基准测试(因为您要求额外的基准测试)显示 node.js/express,甚至是集群的,性能明显不佳。我的感觉是最好将静态文件服务和请求处理完全排除在节点事件循环之外,将这些循环留给需要在 Node.js 中发生的工作。但老实说,如果你在 Node 之外提供静态的东西,你也会没事的。这没什么大不了的。 需要注意的是,如果你只是直接使用node,你仍然可以绑定到保留端口,例如:80,而无需以root身份运行node,只需使用authbind:thomashunter.name/blog/using-authbind-with-node-js【参考方案2】:

只是为了给 pauljz 的答案添加另一个原因,我使用前端服务器,以便在我重新启动后端服务器或由于某种原因崩溃时它可以提供 502 错误页面。这使您的用户永远不会收到有关无法建立连接的错误。

【讨论】:

【参考方案3】:

我相信在任何情况下都可以使用 Node 来提供静态文件只要您知道自己在做什么。使用应用程序服务器来提供静态文件无疑是一种新的范例,因为许多(每一种?)竞争技术(php、Ruby、Python 等)都需要在应用程序服务器之前使用像 HTTPD 或 Nginx 这样的 Web 服务器.

我读过的反对使用 Node 提供静态文件的每一个客观原因都围绕着使用你最了解的东西或使用被认为经过更好测试/更稳定的东西的想法。实际上,这些都是非常正当的理由,但几乎没有纯粹的技术相关性。

除非您发现经典 Web 服务器可以提供而 Node 无法提供的功能(我怀疑您会这样做),否则请选择您最了解或您更喜欢使用的功能,因为这两种方法都可以。

至于 Nginx 与 Apache —— 他们将与 Node 一样“玩”。您应该在不考虑 Node 的情况下比较它们。

【讨论】:

总体上对技术比较有很好的看法:“我读过的反对使用 Node 提供静态文件的每一个客观原因都围绕着使用你最了解的东西或使用被认为经过更好测试的东西的想法/更稳定。实际上,这些都是非常正当的理由,但几乎没有纯粹的技术相关性。”如今,太多的比较都带有偏见,并且基于经验的包袱和对劣质但经过时间考验的技术的舒适度。 是的,但它们确实是/主观/原因。客观原因的一个很好的例子是基准测试 - 我发现其中大部分都表明 nginx > nodejs(尽管我真的应该自己做......) @Nick 你完全正确。虽然我不是科学基准测试方面的专家,但也有一些,所以我会让人们在网上搜索。我要说的是,我认为使用一台服务器而不是两台服务器的简单性是有好处的。出现问题的可能性较小。另一方面,Nginx 通常在每个类 Unix 系统上都有一个配置良好的包,而对于 Node,您需要弄清楚与 systemdpm2 等的集成。所以有优缺点,用户应该选择可以说是他们的毒药。 我认为恰恰相反——节点在负载下会做得更好(也许不是纯粹的卸载速度),因为它不必为每个请求移交一个提供文件的进程,而是可以当本地磁盘或远程客户端在所有其他数千个客户端所在的同一线程上准备好时推送数据。当你有多个处理器时,这当然会崩溃。除非节点现在知道如何使用它们。或者网络服务器现在可以使用协作式多任务处理来提供静态页面......【参考方案4】:

将 NGINX 放在 Node 前面有助于更好地处理高连接量。 NGINX 提供 (仅举几例) 缓存负载平衡速率限制(使用 leaky桶算法),如果与 Fail2ban 等禁止服务配合使用,可以帮助减轻攻击。

对于生产应用程序,您可以在 NGINX 后面作为反向代理运行您的应用程序服务器,再加上像 Redis 这样的缓存服务器——所有这些服务器都可以位于内容交付网络后面,作为防止 ipv4/ipv6 暴露的另一道防线.

【讨论】:

【参考方案5】:

仅使用 Node.js

Node.js 可以完成 Web 服务器的所有任务:提供静态文件、响应 API 调用、在 HTTPS 上运行服务器……还有很多包提供额外的功能,例如记录请求、压缩响应、设置 cookie、防止 XSS 攻击...功能不足可能不是使用另一个 Web 服务器(Apache/Nginx/etc..)来完成 Node.js 的原因。换句话说,对于一个不需要扩展的简单应用程序,您不需要在 Node.js 中添加额外的层,这只会使问题复杂化。

在另一个网络服务器上使用 Node.js

每个网络服务器都有自己的优势。例如,Apache 允许通过 .htaccess 文件对每个目录进行额外的配置。 Nginx 以其在提供静态文件或充当反向代理方面的性能而闻名。 Node.js 在处理 I/O 繁重的系统时提供了巨大的好处...有时,我们需要组合不同 Web 服务器的力量来满足系统的要求。

示例:对于未来可能扩展的企业级应用程序,在 Node.js 应用程序具有一些优势之前将 Nginx 设置为反向代理:

Nginx 可以充当负载均衡器,如果您有超过 1 个 NodeJS 实例,则将流量分派到您的 NodeJS 实例。 Nginx 可以为您处理HTTPS、缓存和压缩。加密和压缩是 NodeJS 不擅长的大量计算操作。所以使用 Nginx 会给你更好的性能。 Nginx 将提供静态内容,这减少了 Node.js 的负载关注点分离:Nginx 负责所有“配置”部分,Node.js 专注于应用程序逻辑。

【讨论】:

【参考方案6】:

额外:如果您需要反向代理也很重要,例如在同一端口上执行 Websocket 服务器,或者可能混合一些技术(用 NodeJS 回复一些请求,用 PHP 回复一些其他请求或其他)

【讨论】:

以上是关于仅使用 Node.js 与将 Node.js 与 Apache/Nginx 一起使用的主要内容,如果未能解决你的问题,请参考以下文章

仅使用 vanilla node.js 将 multipart/form-data 与文件组合

如何仅使用 node.js(https 包)在 api 调用中禁用“withCredentials”

Heroku Node.js 版本 16

Node.js Express POST 仅更改了路由器的输入

仅使用 websockets 构建整个站点(通过 socket.io 和 node.js,没有 Ajax)?

Node.js:深入浅出 http 与 stream