Nginx高并发之IO模型介绍


   nginx 是一个高性能的HTTP反向代理web服务器,同时也提供了IMAP/POP3/SMTP服务。众所周知nginx的相比于apache有更高的并发,可以接收处理更多的访问请求,这得益于IO模型,下面为大家介绍IO模型相关。


 一、先了解下同步异步,阻塞和非阻塞:

同步异步阻塞非阻塞.png

同步/异步  关注是消息通信机制

1、同步

调用者等待被调用者返回消息,才能继续执行

例如:老板布置你任务,一直向你询问有没有完成,完成了老板做下一件事,这种通信机制成为同步。

2、异步

被调用者通过状态、通知或者回调机制主动通知被调用者的运行状态

例如:老板分配你任务,任务进度状态你会向老板汇报,老板做自己的事情,不会向你问询结果。


阻塞/非阻塞:关注调用者在等待结果返回之前的状态

1、阻塞 blocking 

指IO操作需要彻底完成后才返回到用户空间,调用结果返回之前,调用者被挂起

例如:  洗衣服手洗,没洗完之前你都是被占用的状态。

2、非阻塞 nobloking 

指IO操作被调用后立刻返回一个用户状态,无需等IO操作彻底完成,最终的调用结果返回之前,调用者不会被挂起

例如:全自动洗衣机,不需要占用你时间,洗完会通知你,在期间你没有因为洗衣服被占用时间。


二、IO模型介绍

1、同步阻塞型

即用户进程通过系统调用拿资源,因不确定是否拿到数据,所以会一次次的询问结果,这个过程是同步。

将数据从磁盘拷贝到内核空间,再将内核中的数据复制到应用的用户空间,这个过程进程不能做其他事,即阻塞。

同步阻塞.png


2、同步非阻塞

即用户进程通过系统调用拿资源,因不确定是否拿到数据,所以会一次次的询问结果,这个过程是同步。

将数据从磁盘拷贝到内核空间,再将内核中的数据复制到应用的用户空间,这个过程进程可以做其他事,即非阻塞。

这个较同步阻塞没有改善,看似非阻塞,进程可以干其他事,但由于是同步,进程依旧在不断问询结果,反而更消耗资源。

同步非阻塞.png


3、IO多路复用

用户进程找一个代理select,而不直接与内核打交道,系统调用交于select进行处理。

用户进程收到资源从磁盘写入内核缓冲区信息后,将内核缓冲区内容复制到用户空间。

select接待用户进程不是一对一的方式,而是一对多。用户进程依旧阻塞于select调用。这个有点像吃饭,客人和服务员之间的关系,>客人不会和后厨打交道,交由服务员完成。

IO多路复用只能成为异步阻塞模型,因阻塞在IO调用那里,但一个select可以检测多个IO模型,相比与同步阻塞只能检测一个提高了cpu的利用率。

IO多路复用.png


4、信号驱动型

即用户进程建立SIGIO的信号处理程序,复制数据从磁盘到内核空间,等处理完递交SIGIO告知用户进程,这个过程是不阻塞的状态。

用户进程从内核空间复制到用户应用空间,这个过程是阻塞的。

信号驱动并未完全解决问题,只是做到了一部分不阻塞,一部分阻塞。

信号驱动型.png


5、异步IO模型

用户进程不受阻塞,所有的请求,拿数据拷贝到应用空间都由内核完成,用户进程可以接收更多的用户请求。

异步.png


三、nginx高并发原理

nginx高并发使用的是epoll的方式,提供给用户访问,复制数据的一些操作交由内核完成。自身做的事情越少接待的用户请求就越多。

epoll在linux2.6中增加了内存拷贝mmap机制,加速与内核空间的消息传递,即内存映射。

内存映射机制:磁盘中有数据,数据有对应的inode,在内存中映射一个相同的inode,大小也相同,下次拿数据不需要遍历inode,分析路

径了。这样提高了效率。

select epoll poll.png

select和poll优缺点.png