同步与异步的理解

同步与异步的重点在消息通知的方式上,也就是调用结果通知的方式。
同步:当一个同步调用发出去后,调用者要一直等待调用结果的通知后,才能进行后续的执行。
异步:当一个异步调用发出去后,调用者不能立即得到调用结果的返回。
异步调用,要想获得结果,一般有两种方式:
1、主动轮询异步调用的结果;
2、被调用方通过callback来通知调用方调用结果。

生活实例

同步取快递:小明收到快递将送达的短信,在楼下一直等到快递送达。
异步取快递:小明收到快递将送达的短信,快递到楼下后,小明再下楼去取。
异步取快递,小明知道快递到达楼下有两种方式:1、不停的电话问快递小哥到了没有,即主动轮询;2、快递小哥到楼下后,打电话通知小明,然后小明下楼取快递,即回调通知。

阻塞和非阻塞

阻塞与非阻塞的理解

阻塞与非阻塞的重点在于进/线程等待消息时候的行为,也就是在等待消息的时候,当前进/线程是挂起状态,还是非挂起状态。
- 阻塞阻塞调用在发出去后,在消息返回之前,当前进/线程会被挂起,直到有消息返回,当前进/线程才会被激活
- 非阻塞非阻塞调用在发出去后,不会阻塞当前进/线程,而会立即返回。

生活实例

阻塞取快递:小明收到快递即将送达的信息后,什么事都不做,一直专门等快递。
非阻塞取快递:小明收到快递即将送达的信息后,等快递的时候,还一边敲代码、一边刷微信。

同步与异步,重点在于消息通知的方式;阻塞与非阻塞,重点在于等消息时候的行为。
所以,就有了下面4种组合方式

1. 同步阻塞:小明收到信息后,啥都不干,等快递;
2. 同步非阻塞:小明收到信息后,边刷微博,边等着取快递;
3. 异步阻塞:小明收到信息后,啥都不干,一直等着快递员通知他取快递;
4. 异步非阻塞:小明收到信息后,边刷着微博,边等快递员通知他取快递。
  • 1
  • 2
  • 3
  • 4

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

Nginx采用了异步非阻塞的方式工作。那么Nginx是如何实现异步非阻塞的呢?那得先了解一下I/O多路复用。

I/O多路复用

所谓的I/O复用,就是多个I/O可以复用一个进程。I/O多路复用允许进程同时检查多个fd,以找出其中可执行I/O操作的fd。
系统调用select()和poll()来执行I/O多路复用。在Linux2.6中引入的epoll()是select()的升级版,提供了更高的性能。通过I/O复用,我们可以在一个进程处理大量的并发I/O。

初级版I/O复用

比如一个进程接受了10000个连接,这个进程每次从头到尾的问一遍这10000个连接:“有I/O事件没?有的话就交给我处理,没有的话我一会再来问一遍。”然后进程就一直从头到尾问这10000个连接,如果这10000个连接都没有I/O事件,就会造成CPU的空转,并且效率也很低,不好不好。

那么,如果发明一个代理,每次能够知道哪个连接有了I/O流事件,不就可以避免无意义的空转了吗?为了避免CPU空转,可以引进了一个代理(一开始有一位叫做select的代理,后来又有一位叫做poll的代理,不过两者的本质是一样的)。

升级版I/O复用

select()

select可以同时观察许多流的I/O事件,在空闲的时候,会把当前线程阻塞掉,当有一个或多个流有I/O事件时,就从阻塞态中醒来,于是我们的程序就会轮询一遍所有的流(于是我们可以把“忙”字去掉了)。

while true {select(streams[])for i in streams[] {if i has dataread until unavailable
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

select()采用轮询的方式来检查fd是否就绪,当fd数量较多时,性能欠佳。因为从select那里仅仅知道了,有I/O事件发生了,但却并不知道是那几个流(可能有一个,多个,甚至全部),我们只能无差别轮询所有流,找出能读出数据,或者写入数据的流,对他们进行操作。–from 知乎

生活实例

小明家楼下有一个收发室,每次有快递到了就先代收,但收发室也不知道那个是小明的快递;但小明去取的时候,要查询所有代收的快递。

高级版I/O复用

epoll()

epoll能更高效的检查大量fd,UNIX中提供了类似功能的kqueue调用。
epoll可以理解为event poll,不同于忙轮询和无差别轮询,当连接有I/O流事件产生的时候,epoll就会去告诉进程哪个连接有I/O流事件产生,然后进程就去处理这个事件。此时我们对这些流的操作都是有意义的。(复杂度降低到了O(k),k为产生I/O事件的流的个数,也有认为O(1)的)

生活实例

小明家楼下有一个收发室,每次有快递到了,就先代收并做了标记;然后通知小明去取送给小明的快递。

Nginx的异步非阻塞

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

events {worker_connections  1024;use kqueue;  # 在Linux中配置:use epoll;
}
  • 1
  • 2
  • 3
  • 4

在一个Web服务中,延迟最多的就是等待网络传输。nginx在启动后,会有一个master进程和多个worker进程。master进程主要用来管理worker进程,包含:接收来自外界的信号,向各worker进程发送信号,监控worker进程的运行状态,当worker进程退出后(异常情况下),会自动重新启动新的worker进程。而基本的网络事件,则是放在worker进程中来处理了。在一个请求需要等待的时候,worker可以空闲出来处理其他的请求,少数几个worker进程就能够处理大量的并发。

举例来说:同样的4个进程,如果采用一个进程负责一个request的方式;那么,同时进来4个request之后,每个进程就负责其中一个,直至会话关闭。期间,如果有第5个request进来了。就无法及时反应了,因为4个进程都没干完活呢,因此,一般有个调度进程,每当新进来了一个request,就新开个进程来处理。

nginx不这样,每进来一个request,会有一个worker进程去处理。但不是全程的处理,处理到什么程度呢?处理到可能发生阻塞的地方。比如向后端服务器转发request,并等待请求返回。那么,这个处理的worker不会这么傻等着,他会在发送完请求后,注册一个事件:“如果upstream返回了,告诉我一声,我再接着干”。于是他就休息去了。此时,如果再有request 进来,他就可以很快再按这种方式处理。而一旦上游服务器返回了,就会触发这个事件,worker才会来接手,这个request才会接着往下走。

总结

web server刚好属于网络io密集型应用,不算是计算密集型。web server的这种性质决定了每个request的大部份时间都消耗在网络传输中,实际上花费在server机器上的时间片不多。异步非阻塞,使用epoll,和大量细节处的优化,这就是Nginx几个进程就解决高并发的秘密所在。

nginx异步非阻塞 解析相关推荐

  1. nginx异步非阻塞理解

    nginx异步非阻塞理解? 看了一下午如何理解异步非阻塞,不是用生活举例的就是只是说某一点的,其实真的还是很不明白,最后只能通过nginx的异步非阻塞模型来稍微理解理解了,我也不拿什么生活的举例了因为 ...

  2. Nginx的异步非阻塞

    转载地址:https://blog.csdn.net/dutsoft/article/details/55224755 同步与异步 同步与异步的理解 同步与异步的重点在消息通知的方式上,也就是调用结果 ...

  3. flask异步操作_Flask实现异步非阻塞请求功能实例解析

    本文研究的主要是Flask实现异步非阻塞请求功能,具体实现如下. 最近做物联网项目的时候需要搭建一个异步非阻塞的HTTP服务器,经过查找资料,发现可以使用gevent包. 关于gevent Geven ...

  4. Nginx Note03——异步非阻塞机制

    曾经有一段时间,在我的理解中,同步就是阻塞,异步就是非阻塞.可不就是这样吗?从代码执行的角度来看,确实如此.但随着了解的深入,概念和场景的拓展,有了不一样的理解.试分析之,难免疏漏,欢迎指正. --题 ...

  5. 处理大并发之一 对异步非阻塞的理解

    处理大并发之一 对异步非阻塞的理解 在研究nginx和node.js的时候常会遇到异步.非阻塞等,之前自己也经常使用epoll,对其同步与阻塞,异步与非阻塞有了一定的认识,现对参考资料总结下. 首先讨 ...

  6. mysql异步非阻塞方式_如何理解swoole异步非阻塞?

    传统的apache2handler或php-fpm本质上都是短生命周期(请求后释放资源)的FastCGI运行模式. 请求来了,master进程会调用worker进程来处理,处理完后释放资源. 假设你在 ...

  7. tornado异步非阻塞实现方式

    目录 tornado异步非阻塞实现方式 1.多线程 2.老版协程 3.新版协程 实验 1.完全阻塞,同步代码 2.老版本协程 3新版本协程 4 多线程+新版协程,线程函数失效 5.线程+不声明异步,可 ...

  8. Python web框架 Tornado(二)异步非阻塞使用以及原理

    原文: http://www.liangxiansen.cn/2018/04/11/tornado/ 作者: 梁先森 稍有改动 Tornado默认是单进程单线程.实时的web特性通常需要为每个用户一个 ...

  9. 异步就是异步,根本就没有 异步非阻塞IO这个说法。阻塞 非阻塞,同步I/O 异步I/O 的区别

    先给大家安利一下这个 https://www.ibm.com/developerworks/cn/linux/l-async/ 里面关于 异步非阻塞IO 是错的. 异步就是异步,别扯 异步阻塞 异步非 ...

最新文章

  1. SQL SERVER与C#中数据类型的对应关系
  2. [笔试题目] 腾讯2015年9月基础研究笔试题
  3. 【原创】软件测试工程师基础技能+
  4. C语言递归算法(二)
  5. java批量执行多条Sql语句
  6. php 子进程_PHP 多进程入门
  7. 旅游是开车自驾好还是坐火车好?能否从各个方面解答一下?
  8. python爬虫:bs4搜索文档树
  9. C++11 右值引用与移动语义
  10. python梦幻西游辅助_GitHub - fanxueqian/mhxy_fz: 一个基于计算机视觉开发的梦幻西游辅助脚本...
  11. 矩阵L2,1范数及矩阵L2,p范数的求导
  12. 微信账户显示有异常怎么办?要如何解除?
  13. aspcms友情链接调用
  14. 作业必备:操作系统实验四【软中断通信】
  15. CSS 实现平行四边形、菱形、切角效果、梯形
  16. 连续潜在变量---主成分分析
  17. python使用openCV图像加载(转化为灰度图像)、平滑图像处理就是将每个像素的值变换为其相邻元素的平均值、可视化平滑处理之后的图像(Blurring Images)
  18. CCNA-思科网络 EIGRP(增强内部网关路由协议)
  19. 派森编程python_派森学python
  20. 从零开始学习软件测试

热门文章

  1. php自我诊断检查表,店铺自我诊断自查技巧
  2. ubuntu18.04下发现一个类似XShell的远处链接管理工具
  3. 【H5开发】02手把手带你开发H5列表页面 ~ 包含查询、重置、提交功能
  4. 厦大C语言上机 1364 找闰年
  5. Linux 时间修改--date -s命令
  6. 深度学习常见网络结构
  7. 春季吃什么水果保养皮肤
  8. 中国大学MOOC-陈越、何钦铭-数据结构 Saving James Bond - Easy Version
  9. 阿里云安全ACP认证考试实验之云盾之云安全中心与态势感知入门体验
  10. getrawinputdata鼠标_获取鼠标的原始移动值