Nginx学习笔记——理解IO模型

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Nginx学习笔记——理解IO模型相关的知识,希望对你有一定的参考价值。

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请求,当客户端发出一个请求后,服务器端会生成一个进程或线程来处理这个请求,所有的请求最终调用的是本地文件系统上的一个资源,而可以调用本地文件系统资源的只有内核,此时操作系统会由用户空间转入内核空间,此阶段为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阶段进程仍然处于阻塞状态,处理完成后发送通知给请求者转而接收下一个请求。epoll机制采用的就是这种事件驱动I/O模型,发送通知又分为水平触发和边缘触发2种方式。水平触发:进程不断的给请求者发送通知直到来取数据为止;边缘触发:进程只给请求者发送一次通知。

5.异步非阻塞(AIO)

当客户端发出请求后,服务器端使用一个进程处理求情并立即给客户端返回一个消息,转而接收下一个请求,后续的处理由内核来完成,处理完成后发送通知给请求者。整个过程中用户和进程都没有被阻塞,提高了并发处理请求的能力。

优化机制

经常听到的优化机制有send file和mmap,通过一个I/O请求从开始到响应结束的过程我们知道,系统会先把请求的资源加载到内核空间,然后再复制到用户空间构建响应完成后再到内核空间进行发送,其中内核空间复制到用户空间打包再转入内核空间的过程中数据本身并没有改变,而白白浪费了时钟周期,所以send file机制就是当资源在内核空间加载完成后直接构建响应发送给请求者,而不进入用户空间,以减少中间环节提升效率;mmap与之类似,是在内核空间内存中画出一段空间供用户控件的程序访问而不再需要将数据复制到用户空间。




本文出自 “兔样兔森破” 博客,请务必保留此出处http://arkling.blog.51cto.com/2844506/1951228

以上是关于Nginx学习笔记——理解IO模型的主要内容,如果未能解决你的问题,请参考以下文章

机器学习模型可解释性

PHP stream 学习笔记一(同步阻塞 IO 模型)

RT-Thread 内核学习笔记 - 设备模型rt_device的理解

Dubbo -- 系统学习 笔记 -- 示例 -- 线程模型

IO流学习笔记

Nginx:很正经的学习笔记