用node.js本身还是nginx前端来提供静态文件服务?

99

有没有任何基准测试或比较表明:将nginx放在节点前并直接使用它来提供静态文件比仅使用节点并使用其来提供静态文件更快?

对我来说,nginx解决方案似乎更易管理,你有什么想法吗?


3
我认为这还取决于使用一台服务器与另一台服务器相比,你需要编写的配置和代码量。如果你不打算上市,而且应用服务器已经配置好并完成了你需要的所有工作,那么你可以继续使用它,直到它不够用为止。 - m33lky
8个回答

129
我必须不同意这里的答案。虽然Node表现良好,但是当正确配置时,nginx肯定会更快。nginx采用高效的C实现,遵循相似的模式(仅在需要时返回连接),具有小巧的内存占用。此外,它支持sendfile系统调用来提供那些文件,这是提供文件速度最快的方法,因为执行任务的是操作系统内核本身。
到目前为止,nginx已成为前端服务器的事实标准。您可以使用它来提高静态文件的性能、gzip、SSL,甚至以后进行负载均衡。
附言:这假设文件确实是“静态”的,即在请求时处于磁盘上静止状态。

7
小小的注释:node.js 也支持 sendfile 方法,但是似乎需要编写一些代码,可以参考例如 http://blog.std.in/2010/09/09/using-sendfile-with-nodejs/。 - tuomassalo
除了提供静态内容之外,为什么Nginx在公共域上的表现比直接暴露主要Web服务器(Tomcat/Jetty/IIS等)更好? - raffian
1
如果您的应用程序收到请求,将其通过nginx路由不会使请求变得更快(当nginx处理静态CSS和js、gzip和SSL时,在最佳情况下可能会明显更快)。然而,nginx也是最好的软件负载均衡器之一,因此在大多数服务器在中等高负载下容易翻转的情况下,这可能是至关重要的。 - m33lky
但是你可以使用Node.js以异步方式提供文件。NGINX可以这样做吗? - Dragos C.
1
@lwansbrough 把那些基准数据拿出来吧。至少这个话题中有一个人已经进行了自己的实验。 - m33lky

84

我快速地使用 ab -n 10000 -c 100 测试了提供静态 1406 字节的 favicon.ico 的性能,对比了 nginx、Express.js(静态中间件)和 clustered Express.js。希望这对你有所帮助:

enter image description here

不幸的是,我无法测试 1000 甚至 10000 个并发请求,因为在我的机器上,nginx 会开始抛出错误。

编辑:如 artvolk 所建议的那样,这是使用 cluster + static 中间件的结果(较慢):

enter image description here


谢谢,非常有帮助!您是否使用了这个中间件来处理网站图标:http://www.senchalabs.org/connect/favicon.html,或者只是将其作为静态文件提供? - artvolk
@artvolk 很好知道,谢谢!顺便说一下,我正在写我的论文,唯一重要的事情是证明在处理静态内容方面nginx比node更快。 - gremo
3
你在测试中设置了NODE_ENV=production吗?因为这会对生产环境下的缓存static中间件产生巨大影响。 - ruffrey
24
对于不会意大利语的人,X轴表示请求数量,Y轴表示为提供文件所需的毫秒数。我必须使用谷歌翻译以确保我没有错误地阅读数据。尽管如此,这些数据非常有帮助,我真的很感激基准测试。最终我会坚持使用nginx。 - JL Griffin
1
NODE_ENV=production已设置吗? - basickarl
显示剩余6条评论

12
无论哪种方式,我都会设置Nginx缓存静态文件...你会看到巨大的差异。然后,无论您是从节点中提供服务还是不提供服务,您基本上都可以获得相同的性能和相同的负载减轻效果。
就我个人而言,在大多数情况下,我不喜欢我的Nginx前端提供静态资源,因为
1)项目现在必须在同一台机器上 - 或者必须将其拆分为资源(在nginx机器上)和Web应用程序(在多台机器上进行扩展)
2)Nginx配置现在必须维护静态资产的路径位置/在更改时重新加载。

11

我对 @gremo 的图表有不同的解释。在我的看法中,无论是 node 还是 nginx,在请求数量上都具有相同的扩展性(在 9-10k 之间)。当然,nginx 响应的延迟要比 node 快出一个恒定的 20ms,但我认为用户不一定会察觉到这种差异(如果您的应用程序构建得很好的话)。 如果给定一定数量的机器,考虑到大部分负载最初都将发生在 node 上,那么需要承受相当大的负载才会考虑将 node 机器转换为 nginx。 唯一的反驳是,如果您已经将一台机器专门用于 nginx 负载均衡,那么您也可以将其用于提供静态内容。


1
虽然Nginx响应的延迟通过一个固定的20ms减少了,但我不认为用户一定能察觉到这种差异。我真心希望你们不要这样做。有证据表明,用户会感知到1毫秒的差异! - Navin
7
需要引用来源。 - David Burrows

2

FWIW,我在AWS EC2 t2.medium实例上进行了一个相当大的文件下载测试(约60 MB),以比较这两种方法。

下载时间大致相同(约15秒),在两种情况下内存使用都很小(<= 0.2%),但是我在下载过程中得到了巨大的CPU负载差异:

  • 使用Node + express.static():3.0〜5.0%(单个节点进程)
  • 使用nginx:0.3〜0.7%(nginx进程)

0

这是一个棘手的问题。如果你编写了一个非常轻量级的节点服务器来仅提供静态文件,它很可能比nginx表现更好,但情况并不那么简单。(这里有一个“基准测试”,比较了一个nodejs文件服务器和lighttpd - 在提供静态文件时与ngingx类似的性能)。

在提供静态文件方面的性能往往不仅仅取决于Web服务器的工作。如果您想获得最高的性能,您将使用CDN为终端用户提供文件以减少延迟,并从边缘缓存中受益。

如果您不担心这个问题,大多数情况下,节点可以很好地提供静态文件。节点适用于异步代码,因为它依赖于单线程和任何阻塞I/O都会阻塞整个进程,并降低应用程序的性能。很可能您正在以非阻塞方式编写代码,但如果您正在执行任何同步操作,则可能会导致阻塞,这将降低其他客户端获取其静态文件的速度。简单的解决方案是不编写阻塞代码,但有时这是不可能的,或者您不能始终强制执行它。


9
这些都是废话。这个问题是关于 nginx 而不是 Apache 的。nginx和node都使用libev作为它们的事件循环机制。nginx比node快得多。其中一个没有虚拟机的开销,而且是专门编写用于在您的文件系统上执行此操作的。 - Evan Carroll
1
libev是早期的Node。libuv已经承担了这个角色,使得Node可以跨平台运行。 - tsturzl
1
我不明白异步代码如何影响这个问题。Node的性能远不如Nginx,这很可能是由于阻塞I/O造成的,当你有一堆客户端要求从磁盘读取文件时,就会遇到这种情况。最佳实践是始终使用Nginx处理静态资源,以便您的Node应用程序可以处理应用逻辑。我们可以讨论理论上Node表现更好的场景,但在现实世界中,Nginx在10次中有9次会胜出。 - wgp

0
使用Nginx缓存由Node.js提供的静态文件。 Nginx服务器部署在Node.js服务器之前,以执行以下操作:
SSL终止:终止来自客户端的HTTPS流量,减轻上游Web和应用程序服务器的SSL / TLS加密计算负载。
使用NGINX配置基本负载平衡:在两个Node.js服务器之前设置NGINX Open Source或NGINX Plus作为负载平衡器。
内容缓存:缓存来自Node.js应用程序服务器的响应既可以改善对客户端的响应时间,也可以减少服务器的负载,因为合格的响应立即从缓存中提供,而不是在服务器上再次生成。

-13

我确信纯粹的node.js在很多方面都能胜过nginx。

话虽如此,我必须承认NginX有内置缓存,而node.js并没有预装(你必须自己构建文件缓存)。 自定义文件缓存确实比nginx和市场上的其他服务器表现更好,因为它非常简单。

此外,Nginx可以运行在多个核心上。要充分发挥Node的潜力,你需要集群化node服务器。如果你对此感兴趣,请私信我了解详情。

要达到与node相媲美的性能境界,你需要深入挖掘,这是唯一的问题。一旦完成,它绝对能击败Nginx。


1
你需要提供一些事实,因为我想相信你所说的话,但是我需要基准数据,如果是基于真实世界的情况那就太好了!但不要只考虑极端情况。 - Stefan Rogin
7
有趣的是,这个答案提供的事实与获得最多赞同票的答案一样多。我认为人们只是更喜欢在前面放一个Web服务器,因为这是他们在其他Web应用程序技术中学到的方式。虽然这不是一个好的回答,但出于同情投+1。 - user636044

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