Nginx(十)网络I/O模型

一   探讨一下同步、异步和阻塞、非阻塞的一些概念

备注: 关于该'篇章',后续会学习'C/C++、操作系统'知识,再来总结归纳

涉及Nginx和Apache的运行原理一些区别,图文并茂

(1)同步和异步

同步与异步的重点消息通知的方式,也就是调用结果通知方式不同。

通俗:我们在执行某一程序,调用(获取)到程序结果通知方式不一样!

同步和异步描述的是用户线程内核交互方式

同步:当一个同步调用发出去后,调用者要一直等待调用的结果通知后(反馈),才能进行后续的执行。

异步:当一个异步调用发出去后,调用者不必一直等待调用结果的返回(干其它事),当有结果返回接受结果

一般有两种方式

1、主动轮询异步调用的结果--->主动去问返回了没有反复的问

2、调用方通过 callback(回调通知回调函数)来通知调用方获取调用结果!

通俗理解:调用方发出异步调用后,等被调用方发送消息了,调用方通知被调用方再去这个值!

实例解释

同步取快递:小明收到顺风快递将送达的短信,在楼下一直等到快递送达,等到快递送到手里为止!

场景:快递一直没来,只能一直傻等!

异步取快递:小明收到快递将送达的短信,快递到楼下后(消息已经到了),小明再下楼去取

同步缺点:如果你取的消息不给你,会一直占用系统资源!

异步取快递,小明知道快递到达楼下有两种方式:

1、不停的电话问快递小哥到了没有,即主动轮询

   不停的问,小哥到那了,快到了,我去取!

   主动询问消息到达的位置,等消息到达了再去取!

2、快递小哥到楼下后,打电话通知小明(收到了消息的会调通知),然后小明下楼取快递,即回调通知,常见

    收到了快递要到送达的消息,给小哥说快递到达了楼下之后给我打电话,不到楼下不要打电话,小明干别的事

(2)阻塞和非阻塞

阻塞与非阻塞的重点在于进/线程等待消息时候的行为(action),也就是在等待消息的时候,当前进/线程是挂起状态还是非挂起状态!

阻塞和非阻塞描述的是用户线程调用内核I/O操作的方式

通俗理解:你发起了一个行为,需要别人去做,你干什么?

阻塞:调用在发出去后(发出调用请求),在消息返回之前,当前进/线程会被挂起直到有消息返回,当前进/线程才会被激活,处理返回的值

Nginx(十)网络I/O模型_第1张图片

非阻塞调用在发出去后,并不会停下来等待请求的回执,不会阻塞当前进/线程,而会立即返回(干别的事情),当调用的结果返回才激活其它线程当前线程来处理

Nginx(十)网络I/O模型_第2张图片

实例

阻塞取快递:小明收到快递即将送达的信息后,什么事都不做,一直专门等快递。

非阻塞取快递:小明收到快递即将送达的信息后,等快递的时候,还一边敲代码、一边刷微信

理解:同步与异步重点在于消息通知的方式;阻塞与非阻塞重点在于等消息时候的行为

所以就有了下面 4 种组合方式

同步阻塞:小明收到信息后,啥都不干,在楼下等快递;
同步非阻塞:小明收到信息后,边刷微博,楼下(等快递的地方)站着边等着取快递;
异步阻塞:小明收到信息后,在楼上啥都不干,一直等着快递员通知他取快递
异步非阻塞:小明收到信息后,在楼上边刷着微博,边等快递员通知他取快递。

######################################

生产环境中的大部分数据处理模式:同步阻塞(Apache-->select)和异步非阻塞(Nginx-->epoll)

        大部分程序的 I/O 模型都是同步阻塞的单个进程每次只在一个文件描述符执行 I/O 操作,每次 I/O系统调用都会阻塞,直到完成数据传输,才会完成下一个任务的执行。传统的服务器采用的就是同步阻塞的多进程模型:一个 server采用一个进程负责一个 request 的方式一个进程负责一个 request,直到会话结束。进程数就是并发数,而操作系统支持的进程数是有限的,且进程数越多,调度的开销(系统资源)也越大,因此同步阻塞(Apache)无法面对高并发

Nginx 采用了异步非阻塞的方式工作。我们先来先了解一下 I/O 多路复用中的 epoll 模型

epoll 模型:当连接有 I/O 事件产生的时候(当有用户请求时),epoll 就会去告诉进程哪个连接有 I/O 事件产生,然后进程(工作进程把)就去处理这个事件。

例如:小明家楼下有一个收发室,每次有快递到了,门卫就先代收做了标记(小明的)并且通知小明去取送给小明的快递。

通俗理解一个用户的请求到达服务器上,首先epell(门卫)会把请求(快递)接收出来,这个时候不一定会有人处理,如果有空闲的工作进程(小明在家),epolll就会调用工作进程(门卫就会通知小明来取快递,小明立刻来取)来处理!

可能的场景:门卫接受的快递(进程)有点多,发现取快递的不一定在家,有些在家(立马来取),有些不在家(处理不过来的情况);当进程数量太多,处理不过来,消息就存储在这个位置,直到有相应的进程来处理为止!

############工作原理########多路复用########

为什么 Nginx 比其他 web 服务器(同步阻塞)并发高?

说明:涉及Nginx 工作原理

Nginx 配置 use epoll 工作模式后,以异步非阻塞方式工作,能够轻松处理百万级的并发连接。

处理过程:每进来一个 request进来,会有相应的一个空闲 worker 进程处理不是全程的处理,处理到可能发生阻塞的地方。比如向后端服务器转发 request,并等待请求返回。那么这个处理的 worker 不会这么傻等着,他会在发送完请求后,注册一个事件:“如果后端服务器返回了,告诉我一声,我再接着干”,于是他就休息去了(释放这个进程)。此时如果再有新的 request 进来,他就可以很快再按这种方式处理。而一旦后端服务器返回了,就会触发这个事件,worker 才会来接手,这个 request 才会接着往下走。通过这种快速处理,快速释放请求的方式,达到同样的配置可以处理更大并发量的目的!

Linux 网络 I/O 模型简介(图文)

IO多路复用的模式:select   poll  kqueue  epoll

IO多路复用:也称为异步阻塞IO,Java中的Selector和Linux中的epoll都是这种模型!

##############理解2#################

一般来说,IO操作都分为两个阶段,就拿套接口的输入操作来说,它的两个阶段主要是:

(1)等待网络数据到来,当分组到来时将其拷贝内核空间的临时缓冲区中

(2)将内核空间临时缓冲区中的数据拷贝到用户空间缓冲区中!

        I/O模型:由于进程是不可直接访问外部设备的,所以只能调用内核去调用外部的设备(上下文切换),然后外部设备比如磁盘,读出存储在设备自身的数据传送给内核缓冲区,内核缓冲区在copy数据到用户进程的缓冲区,在外部设备响应的给到用户进程过程中,包含了两个阶段,由于数据响应方式的不同,所以就有了不同的I/O模型

    同步是指用户线程发起I/O请求后,需要等待或者轮询内核I/O操作完成时才能继续执行

    异步是指用户线程发起I/O请求后仍继续执行,当内核I/O操作完成后会通知用户线程,或者调用用户线程注册的回调函数

参考博客1

参考博客2

参考博客3

同步异步,阻塞非阻塞 和nginx的IO模型

你可能感兴趣的:(nginx,epoll,nginx)