您的位置:首页 > 运维架构 > Nginx

Nginx学习笔记(一)——理解IO模型

2017-07-26 20:14 288 查看
I/O请求概述
操作系统根据使用者的不同分为用户空间和内核空间,Apache、Nginx等是运行在用户空间对外提供服务的程序,一个服务器应该尽可能多的运行在用户空间来接受业务请求。




一个完整的I/O请求步骤为:
1.客户端与服务器建立连接发出请求,服务器接受请求(1--2),此时的I/O为网络I/O,网络I/O在服务器的内核中完成。
2.当服务器接收完请求,并在用户空间启动一个进程或线程代客户端发起请求,直到构建响应完成的过程(3--5)称为服务器的I/O过程。
3.服务器将已构建好的响应再通过内核空间的网络I/O发还给客户端,同时将本次请求记录到日志中。
整个过程中服务器先在内核空间接收响应,而后在用户空间处理请求并构建响应,最后再通过内核空间的网络I/O发送响应。在用户空间处理请求构建响应的过程(3--5)就是我们通常所说的I/O过程。
I/O的类型划分
关注的角度不同,可以将I/O请求类型分为:
1.同步、异步
同步和异步关注的是消息通知机制。同步:进程或线程发出请求后不会立即返回,但一旦返回就可以返回最终结果;异步:进程或线程发出请求后会立即得到一个返回结果,但返回的非最终结果,当内核处理完成后通过通知机制告知进程,或通过回调函数来处理结果。
2.阻塞、非阻塞
阻塞和非阻塞关注的是等待结果(消息、返回值)时的状态。阻塞:最终结果返回之前,使用的进程或线程会被挂起,只有在得到结果之后才会返回;非阻塞:最终结果返回之前,不会阻塞当前进程或线程。
I/O模型的划分
根据上述类型,I/O模型就可分为5种:同步阻塞、同步非阻塞、I/0复用、事件驱动和异步非阻塞(AIO)



要弄清I/O模型,首先要详细了解一个请求从开始到响应结束的过程。我们知道操作系统分为内核空间和用户空间,一个进程或线程同一时间只能处理一个I/0请求,当客户端发出一个请求后,服务器端首先会通过内核中的TCP/IP协议栈来接受请求,并将客户端请求传递给用户空间内的一个进程或线程来代为请求,此时操作系统会由内核空间转入用户空间,所有的请求最终调用的是本地文件系统上的一个资源,而可以调用本地文件系统资源的只有内核,此时操作系统又由用户空间转入内核空间,从进程代客户端发起请求开始,直到获得最终的结果或通知消息之间的这个阶段称为wait for data,当内核将本地文件系统上的资源加载到内核内存后,由于内核内存不允许用户空间的程序访问,还要将内核内存中的资源复制到用户空间的进程或线程内存中,此时阶段为copy data,复制完成后再由内核空间转入用户空间构建响应发送给客户端。5种I/O模型的区别就是在wait for data和copy data阶段的不同。
1.同步阻塞
当客户端发出请求,服务器端接收到请求并启动一个进程代客户端发起请求,直到返回最终结果,整个过程中进程被挂起,不再处理其他请求。
2.同步非阻塞
当客户端发出请求,服务器端接收到请求并启动一个进程代客户端发起请求,内核立即给进程返回一个消息,由于没有通知机制,进程不停的询问处理是否完成,此时称为忙等待,在copy data阶段进程仍然处于阻塞状态。

3.I/O复用
此模型可以理解为服务器端有一个专门的进程只负责接收客户端发起的请求,将接收到的请求交由其他进程代客户端发起请求和处理,和上述两种模型不一样的地方是接收和处理用户请求不是同一个进程,此时代理用户发出请求的进程是被阻塞在代理进程上。Apache默认prefork工作模式的select模型就是使用的这种I/O模型,prefork模式默认支持1024个并发连接,超出这个并发数量就会因为进程间调度的开销导致效率递减。
4.事件驱动
当客户端发出请求,服务器端接收到请求并启动一个进程代客户端发起请求,内核立即给进程返回一个消息,尽管在copy data阶段进程仍然处于阻塞状态,但在wait data阶段由于进程没有被阻塞,所以依然可以接收其他的用户请求。epoll机制采用的就是这种事件驱动I/O模型,通过前文知道一个进程在同一时间只能处理一种I/O,当有这么一种情况发生:第一个请求的copy data阶段完成后,进程恰巧在接收另一个用户的请求,此时内核就会发送通知让进程来取数据,通知分为水平触发和边缘触发2种方式,水平触发:进程不断的给请求者发送通知直到来取数据为止;边缘触发:进程只给请求者发送一次通知。同时epoll还支持mmap机制。

5.异步非阻塞(AIO)
当客户端发出请求,服务器端接收到请求并启动一个进程代客户端发起请求,内核立即给进程返回一个消息,转而接收下一个用户请求,后续的处理由内核来完成,完成后发送通知给进程。整个过程中进程都没有被阻塞,提高了并发处理请求的能力。

优化机制
经常听到的优化机制有send file和mmap,通过一个I/O请求从开始到响应结束的过程我们知道,系统先把请求的资源加载到内核空间,然后再复制到用户空间构建响应完成后再到内核空间进行发送,其中内核空间复制到用户空间打包再转入内核空间的过程中数据本身并没有改变,而白白浪费了时钟周期,所以send file机制就是当资源在内核空间加载完成后直接构建响应发送给请求者,而不进入用户空间,以减少中间环节提升效率;mmap是在用户空间内存中开一片区域将内核的存储区域映射进去,数据不再需要在内核与用户空间中来回复制。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  模型 I/O Nginx