文章汇总:https://www.cnblogs.com/dotnetcrazy/p/9160514.html
上篇回顾:静态服务器+压测
3.2.概念篇
1.同步与异步
同步是指一个任务的完成需要依赖另外一个任务时,只有等待被依赖的任务完成后,依赖的任务才能算完成。
异步是指不需要等待被依赖的任务完成,只是通知被依赖的任务要完成什么工作。然后继续执行下面代码逻辑,只要自己完成了整个任务就算完成了(异步一般使用状态、通知和回调)
PS:项目里面一般是这样的:(个人经验)
- 同步架构:一般都是和钱相关的需求,需要实时返回的业务
- 异步架构:更多是对写要求比较高时的场景(同步变异步)
- 读一般都是实时返回,代码一般都是
await xxx()
- 读一般都是实时返回,代码一般都是
- 想象个情景就清楚了:
- 异步:现在用户写了篇文章,可以异步操作,就算没真正写到数据库也可以返回:发表成功(大不了失败提示一下)
- 同步:用户获取订单信息,你如果异步就会这样了:提示下获取成功,然后一片空白...用户不卸载就怪了...
2.阻塞与非阻塞
阻塞是指调用结果返回之前,当前线程会被挂起,一直处于等待消息通知,不能够执行其他业务(大部分代码都是这样的)
非阻塞是指在不能立刻得到结果之前,该函数不会阻塞当前线程,而会立刻返回(继续执行下面代码,或者重试机制走起)
PS:项目里面重试机制为啥一般都是3次?
- 第一次重试,两台PC挂了也是有可能的
- 第二次重试,负载均衡分配的三台机器同时挂的可能性不是很大,这时候就有可能是网络有点拥堵了
- 最后一次重试,再失败就没意义了,日记写起来,再重试网络负担就加大了,得不偿失了
3.五种IO模型
对于一次IO访问,数据会先被拷贝到内核的缓冲区中,然后才会从内核的缓冲区拷贝到应用程序的地址空间。需要经历两个阶段:
- 准备数据
- 将数据从内核缓冲区拷贝到进程地址空间
由于存在这两个阶段,Linux产生了下面五种IO模型(以socket为例)
- 阻塞式IO:
- 当用户进程调用了
recvfrom等阻塞方法时,内核进入IO的第1个阶段:准备数据(内核需要等待足够的数据再拷贝)这个过程需要等待,用户进程会被阻塞,等内核将数据准备好,然后拷贝到用户地址空间,内核返回结果,用户进程才从阻塞态进入就绪态 - Linux中默认情况下所有的socket都是阻塞的
- 当用户进程调用了
- 非阻塞式IO:
- 当用户进程发出read操作时,如果
kernel中的数据还没有准备好,那么它并不会
- 当用户进程发出read操作时,如果
