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

简介:

I/O请求概述

操作系统根据使用者的不同分为用户空间和内核空间,Apache、Nginx等是运行在用户空间对外提供服务的程序,一个服务器应该尽可能多的运行在用户空间来接受业务请求。

wKioL1l54AbiMu1cAAMetQ5vQOk082.png

一个完整的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)

wKioL1l54AfSNlGNAAGbQDDmH1g118.png

要弄清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是在用户空间内存中开一片区域将内核的存储区域映射进去,数据不再需要在内核与用户空间中来回复制。


本文转自 qiao645 51CTO博客,原文链接:http://blog.51cto.com/arkling/1951228

相关文章
|
4月前
|
Java Linux API
IO模型
BIO、NIO、AIO是Java中处理网络I/O的三种模型。BIO为阻塞式,每个连接需单独线程,高并发下性能受限;NIO通过非阻塞与多路复用提升并发能力,少量线程可处理大量请求;AIO进一步实现异步非阻塞,数据复制时线程可释放,由回调机制处理后续操作。三者适用于不同场景,BIO易用但低效,NIO高效但复杂,AIO理论性能更优但目前在Linux上仍依赖多路复用实现。Java 21引入虚拟线程后,BIO也可兼具高性能与易编写特性。
147 2
|
网络协议 前端开发 Java
网络协议与IO模型
网络协议与IO模型
442 4
网络协议与IO模型
|
安全 NoSQL Java
一文搞懂网络通信的基石✅IO模型与零拷贝
【10月更文挑战第1天】本文深入探讨了网络通信中的IO模型及其优化方法——零拷贝技术。首先介绍了IO模型的概念及五种常见类型:同步阻塞、同步非阻塞、多路复用、信号驱动和异步IO模型。文章详细分析了每种模型的特点和适用场景,特别是多路复用和异步IO在高并发场景中的优势。接着介绍了零拷贝技术,通过DMA直接进行数据传输,避免了多次CPU拷贝,进一步提升了效率。最后总结了各种模型的优缺点,并提供了相关的代码示例和资源链接。
一文搞懂网络通信的基石✅IO模型与零拷贝
|
开发者
什么是面向网络的IO模型?
【10月更文挑战第6天】什么是面向网络的IO模型?
113 3
|
数据挖掘 开发者
网络IO模型
【10月更文挑战第6天】网络IO模型
336 3
|
数据挖掘 开发者
网络IO模型如何选择?
网络IO模型如何选择?【10月更文挑战第5天】
149 2
|
数据库
同步IO模型是一种常见的编程模型
【10月更文挑战第5天】同步IO模型是一种常见的编程模型
143 2
|
缓存 Java Linux
硬核图解网络IO模型!
硬核图解网络IO模型!
181 1
|
存储 机器人 Linux
Netty(二)-服务端网络编程常见网络IO模型讲解
Netty(二)-服务端网络编程常见网络IO模型讲解