同步转异步处理|学习笔记

简介: 快速学习同步转异步处理

开发者学堂课程【企业级互联网分布式系统应用架构学习同步转异步处理】学习笔记,与课程紧密联系,让用户快速学习知识。  

课程地址:https://developer.aliyun.com/learning/course/503/detail/6745


同步转异步处理

下面我们来介绍另一种提高应用并发度的设计思路。我们简单的把它归结成同步转异步,即在互联网所面临的一些场景,是大量的用户同时来访问,例如阿里巴巴,天猫,淘宝,双十一,春节大家一起摇红包。这些都是大量的用户同时访问同一个系。

用户的请求可能是在每秒钟几百万甚至达到千万级别。如此大的请求量,若每一个请求的时间都非常长,那会对整个系统造成一个致命的损害。 主要的表象是服务器烫机或者停止响应,在以往的互联网应用,大家或多或少都会有所听闻。

从技术层面去分析,主要是因为应用层出现的问题。下面我们来介绍在应用层是什么原因会导致整个系统的摊痪。

图片1.png

上图所示,是我们常见一些的应用服务器,例如我们提到的 Tomcat,这些应用服务器都是以线程池模式来运行。所谓线程池模式,即只要有一个客户端,一个浏览器点击了一个页面或点击了一次提交,它就会发起一次请求到应用服务器,应用服务器的请求队列里被放入一个请求,该请求就会从线程池里申请一个线程进行后续的处理。

线程接受到该请求后,进行的后续处理,通常从数据库中或缓存中取到一些数据或更新一些数据。更新完以后,最后的结果会放入响应队列,响应队列也会从线程池中申请一个线程。

申请到县城后,再根据队列的优先级,返回到响应数据,最后返回到客户端,客户端用户就会看到最后的结果。例如他看到一个商品的价格或者他下的订单是否已经完成。

我们可以看见,若线程池只有一个,当大量的油并发过来以后,请求队列就会申请很多线程,后台服务器通常会为了保护他的物理资源,通常线程池是有一定上限的,例如一千。

请求队列将这1000个线程全部消耗掉,并且持续进行后续处理。 虽然他可能处理完毕,但是响应队列无法从线程池中再获取新的线程,客户端所体现出来的是后台服务器无法上次点击的动作。

所以单线程池的模式很容易导致线程阻塞。

图片2.png

若我们不用其他技术手段解决这种问题,我们可以用另外一种方式进行缓解,即双线程池模式。具体的场景和刚刚介绍的场景是一样的,都是具有成百上千,千万级的请求,进来以后我们把请求队列的线程池和响应队列的线程池分为两个。

线程1他的线程被消耗光,但线程2还有线程,所以响应还可以回到最初的客户端,但是请求队列中大量的请求过来后,在一定时间内处理不完,就会产生一些堆积现象,但是整体通过双线程池在一定程度上可以缓解阻塞情况,但是受到线程池大小的制约,所以我们每次请求的时间消耗的都相对比较长,实际上最终用户的体验是不足的。

最终解决这个问题是需要架构上的调整,使用的方法是同步转移步的方式。

图片3.png

如图所示,灰色部分是异步的处理,我们可以通过控制用户请求进来的速度,对整体的并发度进行控制。

例如在进行大型的电商网站设计时,一个交际是由多个环节组成的。若我们在网站上下一个订单,当应用服务器接受好后,他会把业务逻辑做后续的处理,例如他要做支付,做扣减库存,再制作一份物流订单。若我们把整个应用逻辑按照刚才的单线程模式或者双线程模式,若我们用同步模式处理它,一个逻辑应用下来可能需要几百毫秒,甚至一个处理就需要几秒,整个应用的并发度是无法提升的。

所以对于一个大型的电商网站,把业务逻辑拆成同步和异步两种类型。例如支付环节非常重要,一定要在这次请求中给客户一个反馈,告诉该客户的支付是否成功,把这个环节放在同步环节。

剩下的扣减库存,产生物流订单这些环节可以用异步环节处理。如此,同步处理的速度会很快,可能几十毫秒就可以把一个应用处理掉,这样可以大大增加应用的并发度。我们可以从图上看出应用服务器有一个队列机制,用来保护后续的操作。

从图中结合上述的例子,基本的逻辑是应用服务器会处理接到一个请求后会从请求线程中拿到一个线程,首先处理支付的业务,再把订单的信息传递到队列中,消息队列会把消息传递到业务处理模块中。业务处理模块有物流订单的处理模块,有扣减库存的处理模块。这些模块可以异步的在后台逐步的去消化这些订单数据。

有了这些架构,除了提高前端的响应速度和体验效果外,我们也可以控制后端的并发度。可以控制扣减库存的速度,产生物流订单的速度,因为后台的数据库压力承载能力是有限的,所以通过控制这些业务逻辑的处理速度,可以在一定程度上避免后台的数据库出现垮掉的情况。

通过同步转异步可以很好的解决大的并发处理过后的整体的控制。

图片4.png

整个同步转移部核心是消息架构,该架构是由消息产生者,消息服务平台以及消息消费者构成。

例如应用服务器接到客户下的订单,应用服务器就是消息的产生者,这些消息可以存放到服务平台中,通常情况下会以队列或主题的形式,我们通常称为 Q 和 topic这两种类型存在。

消息平台对应的另一方是消息消费者,例如库存的扣减模块和物流产生订单模块。这些都是消息的消费者或者订阅者。整个数据的流向是当消息产生者产生了信息存放到消息平台中,消费者会获取到这些信息,再进行后续的处理。因为消息平台需要保证消息的持久性,即只要信息被消息产生者存放到消息平台后,数据永远不会丢失,采取各种技术手段进行保障。

当消费者把数据取走后,信息就可以从消息平台中移除掉。被取走之前,一定要保证数据的可靠性。在阿里云也有类似的产品,即消息队列产品。

创建这样一个服务也是非常简单的,只要去录入消息的名字,后续可以通过应用往队列里写入需要传递的数据,后续的应用处理模块就可以订阅一个队列。后续的数据到达后,后续处理模块就可以把数据取出并进行处理。

通过同步转异步的模式可以大大加快应用的处理速度,在相同时间内相同的数据资源可以处理更多的请求。这样的架构在淘宝,阿里巴巴中被广泛的应用到,可以更好的服务于购物的客户。

相关文章
|
前端开发 JavaScript UED
|
前端开发
异步转同步的几种方法
在循环等待中,我们可以使用一个变量来指示异步操作是否已完成。然后,我们可以在循环中检查该变量,如果它指示异步操作已完成,则退出循环。
552 0
|
6月前
|
负载均衡 算法 前端开发
同步和异步
同步和异步
86 0
|
6月前
|
Java 数据处理 调度
异步、半同步、同步
异步、半同步、同步
138 0
|
6月前
|
存储 JavaScript 前端开发
同步和异步[多线程的异步执行操作]
同步和异步[多线程的异步执行操作]
52 0
|
消息中间件 缓存 前端开发
同步转异步处理|学习笔记
快速学习同步转异步处理
345 0
同步转异步处理|学习笔记
|
分布式计算 SpringCloudAlibaba 前端开发
JUC系列(七) ForkJion任务拆分与异步回调
ForkJion任务拆分与异步回调 也是业务中的常客了
JUC系列(七) ForkJion任务拆分与异步回调
|
前端开发
21、同步与异步(三种方法)
21、同步与异步(三种方法)
146 0
|
XML 前端开发 JavaScript