Nginx介绍

一、Nginx介绍


Nginx(“engine X”)是一个开源的、支持高并发、高性能的Web服务和反向代理服务软件。它是由俄罗斯人Lgor Sysoev(伊戈尔·赛索耶夫)开发的,最初应用在俄罗斯大型门户网站及搜索引擎Rambler上(网址为www.rambler.ru),后来作者将源代码以BSD-like协议的形式开源出来以供全球使用。


Nginx最初的设计是用来解决C10k问题的,并在较高负载下对资源的消耗非常小。Nginx正是因为具有高并发(特别是静态资源)、对系统资源的消耗非常小等特性而逐渐受到欢迎的。它的二次开发版中较为有名的有Tengine和OpenResty。


Nginx的官方介绍见 http://nginx.org。



1.1 Nginx的特性


Nginx早期刚开发出来时,其功能特性是较少的,后来功能特性逐渐增加并且完善,很多大型公司也为之开发了一些功能模块并开源出来,这都使得Nginx所提供的功能特性越来越强大。以下是Nginx主要的特性:

①模块化设计,具有较好的扩展性。

②具有高可靠性。

Nginx是基于可靠的Master/Worker两级架构设计的。

③支持热部署。

Nginx能够实现不停机更新配置文件、更换日志文件、更新服务器程序版本,即实现平滑升级。例如,在升级服务器程序版本时,当重载之后,Nginx过一会儿会在不影响处理用户请求的情况下慢慢地升级版本,直至完成。

④低内存消耗。

据Nginx官方统计,在10000个keep-alive连接模式下的非活动连接仅消耗2.5M内存。其中非活动连接指的是已经建立的、无数据传输的TCP连接。

⑤支持event-driven, aio, mmap机制。



1.2 Nginx的基本功能


①静态资源的Web服务器。

②http协议的反向代理服务器。

③pop3/imap4协议反向代理服务器。

④支持FastCGI(构建LNMP),uWSGI等协议。

⑤模块化(非DSO),其中有gzip、ssl等著名模块。


Nginx主要用于作为静态资源的Web服务器http协议的反向代理服务器。当Nginx作为Web服务器使用时,其能够提供Web服务器的相关功能,例如虚拟主机、keepalive、访问日志、错误日志、url rewrite、路径别名、基于ip及用户的访问控制、基于速率限制及并发数限制等功能。



1.3 Nginx的程序架构


前面提到,Nginx具有高可靠性,因为其采用了Master/Worker两级架构来设计。Master/Worker模式是最常用的并行模式之一,其核心思想为:系统由两类进程协同工作,即Master进程和Worker进程,其中Master进程负责接收和分配任务,Worker进程负责处理由Master进程分配的小任务,当各个Worker进程将子任务处理完成之后,将处理结果返回给Master进程,由Master进程进行汇总,从而得到最终结果,并返回给Client。其具体处理过程如下。

wKiom1lrdN7hA9rsAABwaBds4NA498.jpg

使用Master/Worker模式的好处,在于它能够将一个大任务拆分为多个小任务进行并行执行,从而提高了系统吞吐量。当其中有一个Worker进程将小任务处理完成并将处理结果交给Master进程之后,Master进程会立即这个结果先返回给系统请求者Client,而不会等待系统全部处理完成之后再返回,因此其处理过程是异步的,这样能使Client发出请求后的等待时间尽可能地降低。


Master/Worker模式中,Master进程是主控进程,它维护了一个Worker进程队列、Worker进程队列中的Worker进程、子任务队列和子结果集,在这个模式中,不断地从任务队列中获取小任务,并将任务处理结果写入结果集。具体结构如下。

wKiom1lrdVbAuNj0AAIFD6z0uoE054.jpg

注意:在Nginx的Master/Worker两级架构中,一个Master进程可生成一个或多个Worker进程。其中,Master进程主要负责加载配置文件、管理Worker进程(创建、销毁)以及平滑升级等,而负责任务处理的Worker进程则可作为http服务、http代理或者fastcgi代理等。



1.4 Nginx的模块类型


Nginx的模块类型有三种,第一种是核心模块(Core Modules),第二种是标准模块(Standard Modules),包括了标准HTTP模块(Standard HTTP Modules)、可选的HTTP模块(Optional HTTP Modules)和邮件模块(Mail Modules),第三种是第三方模块(3rd Party Modules)。



二、Nginx Web服务介绍


Nginx是一个支持高性能、高并发的Web服务软件,它具备许多优秀的功能特性。作为Web服务器,它和Apache httpd相比:

①Nginx使用epoll模型,能支持更高的并发连接数,且效率更高。

②Nginx更轻量级,消耗的系统资源更少。


2.1 Nginx与其它Web服务软件的比较


(1)当处理静态资源时,Nginx和lighttpd比Apache httpd更据优势,尤其是在处理静态小文件(小于1MB)时,其中Nginx优势更为明显。

(2)当处理动态资源时,Apache httpd相对更有优势一点,但Nginx、lighttpd和Apache httpd三者总体上差距不大。因为这主要取决于后台PHP服务器(Java)和数据库服务器的服务能力,并且与前端的Web静态服务器和动态服务器的结合方式有一定关系。


构建网站思路:从以上结论可知,Nginx在处理静态资源时更有优势,而Apache httpd则在处理动态资源时更有优势,为了将二者的优势结合起来,可以考虑构建LNAMP网站架构。其中,Nginx可以兼作前端调度器和Web静态资源服务器,但Nginx作为Web服务器时只负责处理静态资源而不负责处理动态资源。当收到的动态资源请求时,Nginx将之转发给后端的Apache httpd,而PHP可作为Apache httpd的模块(httpd与php的三种结合方式之一)。这样一来,这里的Apache httpd就只负责处理动态资源而不再处理静态资源了,动态资源请求就交给Apache httpd自带的PHP引擎处理,需要用到数据时再向数据库服务器发起请求。这种构建方式既发挥了Nginx处理静态资源能力高的优势,也发挥了Apache httpd功能丰富、处理动态资源能力高的优势。


注意:一般情况先普通PHP引擎的并发连接参考值为300~1000,Java引擎和数据库的并发连接参考值为300~1500。根据业务场景及网站架构的不同,这些参考值也会有上下浮动。



2.2 为什么Nginx总体性能比Apache httpd高?


Apache httpd使用的是传统的select模型(更准确地讲,应该是httpd的prefork、worker这两种MPM模块使用select模型),而Nginx使用的是较新的epoll(Linux 2.6内核)和kqueue(FreeBSD)模型。其中select模型属于I/O复用模型(I/O Multiplexing),epoll模型和kqueue模型属于信号驱动I/O(Signal Driven I/O),也称事件驱动。相比于Apache httpd,Nginx在处理大量连接的读写时,效率更高。


我们知道I/O过程有两个阶段,第一阶段是等待数据准备完成阶段,即数据先加载至内核内存空间(缓冲区)。第二阶段是数据从内核复制到进程阶段,即数据从内核空间复制到用户空间的进程的内存地址空间中去。


对于Apache httpd所采用的select模型而言,当从网络IO中有请求数据到达时,I/O过程的第一阶段就开始了,也就是开始先将数据从网卡加载至内核内存空间,当数据加载到内核空间之后再进行第二阶段,即把数据复制到用户空间中的Apache httpd进程(或线程)的内存空间中去,而究竟是httpd进程还是线程去参与这整个I/O过程取决于httpd采用的MPM模块(prefork或worker,此处假设httpd采用prefork)。这里中间有一个问题,就是在I/O过程的第一阶段中,负责处理该数据的httpd进程是否要阻塞呢?答案是肯定的,因为对于I/O复用模型来说,第一阶段用户空间的进程(这里为httpd进程)必须阻塞在I/O复用的系统调用上(时刻查看数据已经加载到内核完成了)。一旦第一阶段完成,则立即进入第二阶段,此时仍然需要阻塞httpd进程,因为它必须参与将数据复制到自身内存空间中,之后再对其进行处理。总而言之,负责处理该数据的httpd进程在I/O过程的两个阶段都会被阻塞(或被挂起)。如果httpd采用的MPM模块是worker也同理,负责处理该数据的线程在I/O过程的两个阶段都会阻塞(或被挂起)。


而对于Nginx所采用的epoll模型而言,在I/O过程的第一阶段中nginx的进程不需要被阻塞,也不需要盲等,当第一阶段完成之后内核通过信号通知机制(callback机制,即回调机制)通知nginx进程,而在第二阶段中nginx仍然需要阻塞。


这里打个比方。例如当你到一个饭馆吃饭时,点完菜后就开始等候,假设饭菜做好了需要自己去端口前领取我们知道,一般饭馆的服务员看见后台的师傅做好了一道菜时,会基于广播或者其他机制通知饭馆内的客户去领取饭菜,这是一种通知方式。而epoll模型就是采用这种通知方式,当你点完菜之后,师傅就开始做菜(数据开始加载至内核空间,即开始执行第一阶段),然后你就可以一边等候一边做其它事请,例如玩手机,甚至可以利用这个时间空隙到饭馆旁边的商场逛一逛(用户空间的进程在第一阶段不会被阻塞),而当饭菜做好了需要回去吃饭(去执行第二阶段),这时饭馆前台服务员可以用广播通知你,也可以打电话给你并告诉你可以回来领饭吃了(callback机制),而你接到电话之后就回去吃饭(完成第二阶段)。因此,epoll模型其实就是信号驱动或者事件驱动的I/O模型。对于那些点的菜已经烧好的客户,服务员直接一并通知就行了。


但是对于Apache httpd来说就相对麻烦多了。饭馆里的前台服务员同样会把饭馆内所有客户点的菜单交给后台的师傅做,但把每一道菜的完成状态登记并显示在饭馆内的一个大屏幕上,每个客户点完菜都必须站在大屏幕前看看自己点的菜做好了没有。后台的师傅每烧好一道菜,前台服务员就更新一次大屏幕(只要大屏幕中有一道菜的完成状态发生变化就更新整个屏幕。因此,当你点完菜之后,就必须站在大屏幕前,紧紧盯着自己的那道菜的完成状态,相当于你被阻塞在大屏幕上,而不能做其它事儿(第一阶段会被阻塞),一旦完成就马上去领取(去执行第二阶段)。当然,领完饭菜之后就是吃饭了(第二阶段也是被阻塞)。需要注意的是,大屏幕上记录着多道菜的完成状态(I/O复用),而且每烧好一道菜就需要更新整个屏幕,这就导致了一个问题,随着点的菜的数量增加,每次更新大屏幕时需要更新状态的菜的数量线性增加(select的调用复杂度是线性的,即O(n)),因为每次更新大屏幕时都需要遍历每一道菜的完成状态。因此,select模型就是I/O复用模型。另外,当饭馆内所有的客户点完菜之后都必须盯着大屏幕看,直到自己点的菜已经做好了。而大屏幕能够记录的菜完成状态的数量是有限的(select模型支持的并发连接数有限),当然这里假设大屏幕不能翻转。而select机制一般最大支持1024路的I/O复用,相当于这里大屏幕上最多只能记录1024道菜的完成状态。当然,select机制下的最大I/O复用数是可以调大的,但或多或少会影响其处理性能,就好比如大屏幕上本来是最多记录1024道菜的,为了记录更多道菜就只能把屏幕上的字体调小了,但这样一来对于站在靠后的客户来说,字体就显得不是很清楚了。


Apache httpd select和Nginx epoll对比如下表所示

模型

selectepoll

性能

随着连接数的增加性能急剧下降。处理成千上万并发连接数时,性能很差随着连接数的增加,性能基本上没有下降。处理成千上万并发连接数时,性能很好
内在处理机制I/O多路复用回调(callback)机制
时间复杂度O(n)O(1)
开发复杂性


I/O过程中用户空间的进程的状态

模型selectepoll
I/O过程第一阶段阻塞(在I/O多路复用上)非阻塞
I/O过程第二阶段阻塞非阻塞


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章