nginx为什么性能这么优越?

赵彬衫


看到下面回答中“nginx是基于epoll模型开发的,而epoll是基于JAVA NIO的同步非阻塞开发“,忍不住想这回答还真是无畏啊,错的离谱,竟还有那么多点赞。应该说Epoll机制仅仅是nginx在Linux上实现事件驱动的一种技术而已,说nginx基于epoll开发那就错了,说nginx基于java nio开发就更不知所云了。

当我们说性能优越的时候,我们在说什么呢?首先让我们看看有哪些衡量性能的性能指标吧。

性能指标一般包括响应时间、吞吐量、并发用户数等。

响应时间指功能完成的时间,和客观环境、数据量级、主观感受等都有关系。客观环境中硬件包括服务器配置、客户端机器配置等,软件包括数据库部署方式、客户端使用的浏览器等,另外还有网络环境。

吞吐量是给定时间内系统可处理的事务/请求的数量等,例如网络传输的数据流量。这个指标对于互联网软件更为关键,目前我们尚未进行定量分析和测试。

并发用户数用来衡量系统的同步协调能力,我们更关注多个用户同时操作同一功能或数据时,对系统性能的影响。

总的来说,nginx的性能是指其低延迟、高吞吐、高并发能力。

下面我们就从架构设计的角度,来分析nginx是如何做到低延迟、高吞吐、高并发能力的。

Nginx采用一个Master管理进程,多个worker工作进程的设计方式。如下图所示,Master进程管理了完全相同的worker进程,一个cache manager进程和cache loader进程。

这种多进程的架构可以充分利用多核系统的并发处理能力。同时,多个worker进程间可以实现负载均衡,一个请求到来时更容易被分配到负载较轻的worker进程中处理。这将降低请求的延迟,也提高了网络处理的性能。

Nginx进程内部采用了非阻塞方式的事件驱动架构模式,这也是Nginx不同于传统Web服务器的地方。传统的Web服务器而言,采用的所谓事件驱动往往局限于TCP建立连接、关闭事件上,一个连接建立以后,在关闭之前的所有操作都不再是事件驱动,这时会退化成按序执行每个操作的批处理模式,这样每个请求在连接建立之后都将始终占用系统资源,直到关闭才会释放。

nginx的异步事件驱动实际上是请求的多阶段异步处理的过程。nginx实际把请求处理流程划分为了11个阶段,这样划分的原因是将请求的执行逻辑细分,各阶段按照处理时机定义了清晰的执行语义,开发者可以很容易分辨自己需要开发的模块应该定义在什么阶段。

nginx做为一个异步高效的事件驱动型web服务器,在linux平台中当系统支持epoll时nginx默认采用epoll来高效的处理事件。Epoll实际上是 poll 的一种改进,它可以处理大批量的句柄。而 poll 又是select 的一种改进。在select 中对所打开的文件描述符个数有一定的限制,该限制由 FD_SETSIZE 设置(一般为 1024 或 2048), 而且内核中的 select 的实现是采用轮询来处理描文件描述符集,因此效率低。当文件描述符集中的某个描述符处于可读、可写或异常状态时,select 采用内存拷贝方法通知用户空间。因此, 在select 模型中文件描述符个数受限且效率低的问题就很明显。为了解决select 对文件描述符个数的限制,采用了 poll 模型,但是 poll 依然不能解决 select 的效率问题。所以,最终epoll 模型重新对poll 模型进行改进 。

epoll 的优点如下所示:

  • 处理大批量文件句柄:一个进程可以处理大批量的文件句柄,可处理文件描述符的个数远大于 2048;


  • 高效率:内核实现中 epoll 是根据每个描述符上面的回调函数实现的,并且只有处于活动状态的套接字才会主动调用该回调函数,其他不活动的套接字并不会去调用,因此,epoll 不必扫描整个文件描述符集,只需要扫描处于活动状态的文件描述符。所有大大减低了效率。
  • 加快内核与用户的消息传递:epoll 是通过内核与用户空间mmap 同一块内存实现内核与用户之间消息的传递。
  • 内核微调:可以根据运行时所需内存动态调整内存大小。


Nginx的高性能有赖于其高效内存管理,下面我们看看其内存池设计。

Nginx 使用内存池对内存进行管理,把内存分配归结为大内存分配和小内存分配。若申请的内存大小比同页的内存池最大值 max 还大,则是大内存分配,否则为小内存分配。

  1. 大块内存的分配请求不会直接在内存池上分配内存来满足请求,而是直接向系统申请一块内存(就像直接使用 malloc 分配内存一样),然后将这块内存挂到内存池头部的 large 字段下。
  2. 小块内存分配,则是从已有的内存池数据区中分配出一部分内存。

这样设计的好处就是减少了内存碎片,提升了内存分配的效率。

总结一下,nginx优越的性能得益于其多进程、异步事件处理的架构,得益于其高效的内存管理。


本回答的内容参考了nginx官网上的内容,截图也来自于https://www.nginx.com/blog/inside-nginx-how-we-designed-for-performance-scale/


坐云观潮


我做过深入测试,windows下面最强者是iis,linux下最强者是nginx,nginx在win下性能很差,还不如apache


jackson316


这个问题要从本质来看,NGINX本质上是不实现业务的,不是容器,而是一个看门+转发的服务器,这个定位决定了NGINX可以做得高效,如果不是NGINX,也会有另一个服务器来实现得这么高效。

1.NGINX

采用了的构架极其简单,采用了多进程,每个进程的核心业务其实是单线程的,在执行上,代码逻辑可以极其简化。同时也可以把多核机器的性能发挥出来。

2.采用了EPOLL的这个异步IO模型,在面对大并发时,系统在处理网络事件上,占用的CPU极低,为高性能提供了可能。

3.在内存使用上,NGINX不像传统的写法,在池里面分配,然后再释放,而是为每个连接生成一个临时池,这个池上的申请小块内存不进锁,同时这个池上的内存也不释放,而是在完成请求后,这个池一次性释放。


TY丶念经姐姐


所谓没有对比就没有伤害!

在nginx横空出世之前,Apache服务器一直占据web服务器的垄断地位,所以就用对比的方式来解释nginx那么强!

两者性能差别的主要原因在于网络IO模型选择不同,apache使用了select,而nginx使用了epoll模型!

举个例子:一个万人村里面选村长,有两种方式:

①,让每个人在纸条上写下自己的名字,然后前村长去收集纸条(一个线程去遍历),然后得到村长推荐候选人的名单(需要处理的连接),这就相当于select模型,去轮询每一个连接,并对需要进行处理的连接进行处理!

②,每个人都可以毛遂自荐(每个连接都有可能活跃),想要竞选的在旁边站成一排(事件触发,放入队列中),然后就在这几个人中选择(几个待处理的任务),相当于只要对少量的事件进行处理!

一个是从上万人中循环得到几个进行处理,一个是几个自己站出来直接处理,这种效率相差不是一般的大吧?

nginx是基于epoll模型开发的,而epoll是基于JAVA NIO的同步非阻塞开发,在高并发情况下能支持更多的连接!

nginx是事件驱动的,一个主进程跟多个工作进程组成的工作模式,主线程负责循环分配事件,多个工作线程负责事件的处理!

我们通常使用nginx做什么呢?

nginx作为高性能的http服务器和反向代理服务器,通常用做负载均衡组件,负责接受大量的连接然后基于一定的规则(轮询,权重等)分发连接给不同的应用服务器进行处理!

而且负载均衡配置十分简单,只需要在安装好nginx之后,通过修改配置文件nginx.conf,将不同的连接分发到不同的服务器上(通过配置server),配置十分简单!



一般来说,企业中使用nginx作为负载均衡组件的场景还是很多的,同时为了避免单点故障带来的不稳定性,通常会使用keepalive搭建高可用的集群方案!

nginx搭建比较简单,大家自己可以多玩一玩!更多的技术分享,敬请关注。。。


此生唯一


部署架构上支持负载均衡

设计上采用进程池概念

网络模块在linux上支持非阻塞epoll模型


日月齐晖1


说性能优越,主要看哪个方面,Nginx和Apache还有Tomcat各有各的特长,不应厚此薄彼,在负载均衡的服务器系统架构中,他们都有各自的用处。


分享到:


相關文章: