仅使用Node.js与使用Node.js配合Apache/Nginx的区别

259

在实际部署中,什么情况下应该只使用Node.js作为服务器?

当不想仅使用Node.js时,与Node.js搭配更好的是Apache还是Nginx?

6个回答

237

在Node.js前面添加另一个Web服务器有几个好处:

  • 不必担心Node.js进程的特权/设置用户ID。通常只有root可以绑定端口80。如果您让nginx / Apache担心以root身份启动、绑定端口80,然后放弃其根特权,这意味着您的Node应用程序就不必担心它。
  • 提供静态文件,例如图片、CSS、JS和HTML。与使用适当的静态文件Web服务器相比,Node可能效率低下(Node在某些场景中也可能更快,但这不太可能成为常态)。除了更有效地提供文件外,您也不必像从Node中提供服务那样担心处理eTags或缓存控制标头。一些框架可能会替您处理此问题,但您需要确保。不管怎样,仍然很慢。
  • 如Matt Sergeant在他的答案中提到的,如果您的节点服务崩溃,您可以更轻松地显示有意义的错误页面或回退到静态站点。否则,用户可能只会得到超时连接。
  • 在Node之前运行另一个Web服务器可以帮助减轻针对Node的安全漏洞和DoS攻击。对于现实世界的例子,CVE-2013-4450由于运行类似Nginx的东西而得到了防止

我要附带说明第二个要点,即您应该通过CDN或从类似Varnish的缓存服务器后面提供静态文件。如果您这样做,则原点是Node还是Nginx或Apache并不重要。

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


12
express.static可以很好地处理ETags和缓存控制头。 - robertklep
22
Node.js 不是那么好用吗?http://centminmod.com/siegebenchmarks/2013/020313/index.html,http://zgadzaj.com/benchmarking-nodejs-basic-performance-tests-against-apache-php - el vis
5
Pauljz,你有支持更慢的基准测试吗?@pawlakpp指出的文章似乎表明Node.js在负载下要快得多。 - Samuel Neff
5
这里有一些相关的讨论:https://dev59.com/CWkw5IYBdhLWcg3wVpFi,提供了一些额外的观点。那里的基准测试(因为你要求更多的基准测试)显示node.js / express,即使是集群,性能也明显低于预期。我的感觉是最好将静态文件服务和请求处理完全从node事件循环中分离出来,将这些周期留给需要在Node中进行的工作。但是,老实说,如果您从Node提供静态内容,您也会很好。这并不重要。 - pauljz
4
基准测试非常有用,提供了有意义的信息。然而,在大多数应用程序中,数字之间的差异并不足以引起关注。在NodeJS前面使用Nginx/Apache可能更好,但在大多数情况下,这只是过度设计,并增加了不必要的复杂性。一切都取决于您的需求。我的建议是仅使用NodeJS使其正常工作,如果吞吐量不符合您的要求,则考虑在前面添加Web服务器。 - Nepoxx
显示剩余10条评论

86

除了pauljz的答案外,我还想再给出一个原因:我使用前端服务器,这样在重启后端服务器或由于某些原因导致其崩溃时,可以提供502错误页面。这使得用户永远不会收到关于无法建立连接的错误信息。


35

我认为,在任何情况下,只要你知道你在做什么,使用Node来提供静态文件都是可以的。将应用服务器用于提供静态文件确实是一种新的范例,因为许多(甚至所有?)竞争技术(如PHP、Ruby、Python等)需要像HTTPD或Nginx这样的Web服务器位于应用服务器之前。

我曾经读到的反对使用Node提供静态文件的每一个客观理由都围绕着使用最熟悉的工具或使用被认为更经过测试/更稳定的工具。从实际角度来看,这些都是非常有效的理由,但纯粹技术上讲,它们并不重要。

除非你找到了一种经典Web服务器可以实现而Node无法实现的功能(我怀疑你会找到),否则选择你最熟悉的或者你更喜欢的方法都是可以的。

至于Nginx与Apache的比较——它们与Node的“配合”是相同的。你应该忽略Node,将它们进行比较。


2
对技术比较的良好观点:“我曾经阅读过的所有反对使用Node提供静态文件的客观理由都围绕着使用自己最熟悉的东西或使用被认为更经过充分测试/更稳定的东西的想法。从实际角度来看,这些是非常有效的理由,但在纯技术上却没有太大的相关性。”现在有太多的比较是有偏见的,并且基于经验和舒适水平上低劣但经过时间考验的技术。 - Sunny
是的,但它们是非常主观的原因。一个客观原因的绝佳例子就是基准测试 - 我发现大多数都表明nginx > nodejs(虽然我真的应该自己做...)。 - Nick
@Nick 你说得完全正确。虽然有一些科学基准测试,但我不是专家,所以我会让人们在网上搜索。但我想说的是,使用一个服务器比使用两个服务器更简单,这样就可以减少出错的可能性。另一方面,Nginx通常在每个类Unix系统上都有一个包,并且具有良好的配置,而对于Node,您需要解决与systemdpm2等的集成问题。因此,有优点和缺点,用户应该自行选择。 - user636044
我曾认为相反的情况是正确的——节点在负载下表现更好(也许不是在纯未加载速度方面),因为它不必交出处理每个请求的文件的进程,而是可以在所有其他数千个客户端所在的同一线程上在本地磁盘或远程客户端准备好时推送数据。当然,这种情况在有多个处理器时会崩溃...除非节点现在知道如何使用它们。或者Web服务器现在可能使用协作式多任务处理来提供静态页面... - Gerard ONeill

15

仅使用Node.js

Node.js可以完成Web服务器的所有任务:提供静态文件、响应API调用、在HTTPS上运行服务器等。此外,有许多软件包提供额外的功能,如记录请求、压缩响应、设置cookie、防止XSS攻击等。在没有必要使用其他Web服务器(如Apache/Nginx等)来完善Node.js的情况下,缺乏功能可能不太可能是一个原因。换句话说,对于不需要扩展的简单应用程序,您不需要为Node.js添加额外的层次,这只会让问题更加复杂。

与其他Web服务器一起使用Node.js

每个Web服务器都有自己的优势。例如,Apache允许通过.htaccess文件进行每个目录的附加配置。Nginx在提供静态文件或作为反向代理时的性能表现突出。当处理I/O密集型系统时,Node.js提供了巨大的好处... 有时,我们需要结合不同的Web服务器的优势以满足系统的需求。

例如:对于可能在未来需要扩展的企业级应用程序,在Node.js应用程序之前设置Nginx作为反向代理具有以下优点:

  • Nginx可以作为负载均衡器将流量分配到您拥有多个Node.js实例的情况下。
  • Nginx可以为您处理HTTPS,缓存和压缩。加密和压缩是重度计算操作,NodeJS不擅长处理。因此使用Nginx会给您带来更好的性能
  • Nginx将服务于静态内容,这样可以减轻Node.js的负载
  • 关注点分离:Nginx负责所有“配置”部分,而Node.js专注于应用程序逻辑。

8
将NGINX置于Node之前有助于更好地处理大量的连接。NGINX提供了缓存、负载均衡、速率限制(使用漏桶算法)等功能,并且与类似Fail2ban的禁止服务配合使用可以帮助缓解攻击。
至于生产应用程序,您可以将应用程序服务器作为反向代理运行在NGINX后面,并与Redis等缓存服务器配合使用,所有这些都可以位于内容交付网络的后面,以作为防范曝露IPV4/IPV6的另一道屏障。

5
一个额外的提示:如果你需要一个反向代理,比如在同一端口上执行Websocket服务器,或者混合一些技术(用NodeJS回复一些请求,用PHP回复另一些请求或其他),这也是很重要的。

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