Nginx----IO模型及架构流程概述

按说暮春时节,草长莺飞,带上心爱的姑娘或者家人出去踏踏青、赏赏花最合适不过,可这一场接一场的大雪,下得人心生烦闷,每日早起都要考虑时宜穿秋裤还是时宜不穿,费脑又耗时,关键是我烧烤架都备好了,寒什么也不能寒了一颗吃货的心呢!早晨起床上班,在小区看到一车将垃圾桶怼到墙上,我想他也应该是在用另一种方式表达对这差劲天气的不满:(

言归正传,开始聊聊本文主题Nginx,深度用户可绕过本篇文章,好久不写技术文章,13年的简历中就写过熟悉Nginx,但也没有落实到文字上,本篇主要目的一是记录总结工作中的一些点,二是分享给需要的童鞋。nginx是一个高性能HTTP和反向代理服务器,来自于俄罗斯,可做HTTP和邮件服务器,不懂反向代理服务器的读者可移步本博前面HTTP系列文章,用过Nginx的朋友都能列出用它的十大理由,所谓存在即合理,安装过程也不再赘述,linuxmakemake installconfigure这几个命令来回用,报错就是依赖包差了或者冲突了,移步度娘便有完整教程。

首先来说nginx高性能的其中一个原因,就是使用了一种高效的I/O模型,先来梳理一下所有的网络模型,本章节图文都是参考Stevens的《Unix Network Programming》,英文好的可以直接看原版I/O Models章节,学渣就看这个吧,网络模型总共分一下几种类型:

1blocking I/O----------------------------------阻塞IO

2nonblocking I/O-------------------------------非阻塞IO

3I/O multiplexing (select and poll)------------多路复用IO

4signal driven I/O (SIGIO)---------------------信号驱动IO

5asynchronous I/O (the POSIX aio_functions)----异步IO

IO模型:blocking I/O


从图宏观来看,左侧为应用程序,右侧为内核,当应用程序的进程使用recvform函数发起对内核的调用,内核开始准备数据,一般来说内核需要收到一个完整的数据包(如UDP),不会很快,因此应用程序的进程处于阻塞等待的状态,待内核将数据准备好,它将数据从内核拷贝到用户内存,内核才会返回结果,然后应用程序解除阻塞状态,去处理下一步请求,从本次过程,做过开发的基本都能理解,平时程序都是属于这种阻塞的同步调用方式。

IO模型:nonblocking I/O


从图可以看出,应用程序进程当使用recvform函数对内核发起调用时,内核立即返回一个数据没有准备好的结果,进程通过轮询不断的去请求内核,询问数据是否给老子准备好了,知道内核返回结果,说已经准备好了,进程才结束轮询。

跟阻塞IO对比,进程本地不必阻塞等待,而是隔三差五的通过轮询调用,在这个过程中,会大量的占用CPU的时间,所以一般Web服务器都不使用这种I/O模型。

IO模型:I/O multiplexing (select and poll)


多路复用模型新增了几个函数:selectpollepoll(Linux2.6以后的内核开始支持),这几个函数也会使进程阻塞,但是和阻塞I/O所不同的,这两个函数可以同时阻塞多个I/O操作,而且可以同时对多个读操作,多个写操作的I/O函数进行监测,直到有数据可读或可写时,才真正调用I/O操作函数,说直白一点就是他们可以监控多个内核的IO操作,一个顶仨,一个select会监测多个socket,当内核准备好其中一个数据时,select会立即通知进行,赶快使用recvform调用内核,让内核抓紧开始拷贝数据到用户内存,如此,它比阻塞IO好处就是一次能处理多个连接,而阻塞IO只能处理一个。

其中还有一个点,就是epollpoll要比select要高级一点,他们是无轮询的,因为他们用callbackselect需要通过遍历Socket来完成调度,如果socket多,那肯定是需要浪费CPU时间的,而epollpoll使用回调函数,给套接字注册个回调函数,当他们活跃时,自动完成相关操作,就避免了轮询,这些函数实际是阻塞进程的。

IO模型:signal driven I/O (SIGIO)


信号驱动IO,应用程序进程建立SIGIO处理函数调用内核,内核会立即返回数据没有准备好的信号,进程不再阻塞,待内核准备好后,发送SIGIO信号给用户进程,然后用户进程通过阻塞的方式使用recvform函数调用内核,让内核把数据拷贝到用户内存,并返回拷贝结果。看到此处是不是似曾相识,其实这有点回调的意思了,赶快去翻翻本博客Java回调机制解析的知识点吧。

IO模型:asynchronous I/O (the POSIX aio_functions)


异步IO,也就是AIO,这个之前有篇文章MINA时,也提过异步IO的,看图说话,这个过程其实就非常简单,应用程序进程调用内核,内核返回数据没有准备好消息,进程继续去干别的事情,待内核准备好数据,并且拷贝到用户内存,才通知进程已完成数据拷贝,因此,可以看出这种IO方式是效率最高的。

综上所述,可以看出,越往后,阻塞越少,理论上效率也是最好的,其中五种I/O模型中,前三种属于同步I/O,后两者属于异步I/O,到此同步和异步的含义也就不言而喻。目前nginx主要是基于多路复用IO来处理,至于为啥不能使用异步IO,这得看操作系统的支持程度的。

Nginx架构

Nginx由内核和模块组成,从官方文档http://nginx.org/en/docs/下的Modules reference可以看到一些比较重要的模块,一般分为核心、基础模块以及第三方模块,第三方模块意味着你也可以按照nginx标准去开发符合自己业务的模块插件,核心主要用于提供Web Server的基本功能,以及WebMail反向代理的功能;还用于启用网络协议,创建必要的运行时环境以及确保不同的模块之间平滑地进行交互。不过,大多跟协议相关的功能和某应用特有的功能都是由nginx的模块实现的。这些功能模块大致可以分为事件模块、阶段性处理器、输出过滤器、变量处理器、协议、upstream和负载均衡几个类别,这些共同组成了nginxhttp功能。事件模块主要用于提供OS独立的(不同操作系统的事件机制有所不同)事件通知机制如kqueueepoll等。协议模块则负责实现nginx通过httptls/sslsmtppop3以及imap与对应的客户端建立会话。在Nginx内部,进程间的通信是通过模块的pipelinechain实现的;换句话说,每一个功能或操作都由一个模块来实现。例如,压缩、通过FastCGIuwsgi协议与upstream服务器通信,以及与memcached建立会话等。

Nginx工作流程

官网对nginx的一段叙述,大概意思是Nginx由一个主进程(master)和多个工作进程组成(worker),master进程主要用来管理worker进程,包含:接收来自外界的信号,向各worker进程发送信号,监控worker进程的运行状态,当worker进程退出后(异常情况下),会自动重新启动新的worker进程。而基本的网络事件,则是放在worker进程中来处理了。多个worker进程之间是对等的,他们同等竞争来自客户端的请求,各进程互相之间是独立的。一个请求,只可能在一个worker进程中处理,一个worker进程,不可能处理其它进程的请求。worker进程的个数是可以设置的,一般我们会设置与机器cpu核数一致,示意图如下(图来自网络):


nginx采用这种进程模型的好处是,对于每个worker进程来说,独立的进程,不需要加锁,所以省掉了锁带来的开销,同时在编程以及问题查找时,也会方便很多。其次,采用独立的进程,可以让互相之间不会影响,一个进程退出后,其它进程还在工作,服务不会中断,master进程则很快启动新的worker进程,以上也是Nginx高校的另一个原因了。

下篇开始讲Nginx的实际应用。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值