美文网首页
异步化介绍

异步化介绍

作者: wz的技术窝 | 来源:发表于2019-07-27 19:26 被阅读0次

1.异步化介绍

1.1 同步和异步,阻塞和非阻塞

同步和异步,阻塞和非阻塞, 这个几个词已经是老生常谈,但是常常还是有很多同学分不清楚,以为同步肯定就是阻塞,异步肯定就是非阻塞,其实他们不是一回事。

同步和异步关注的是结果消息的通信机制 

- 同步:同步的意思就是调用方需要主动等待结果的返回 

- 异步:异步的意思就是不需要主动等待结果的返回,而是通过其他手段比如,状态通知,回调函数等。

阻塞和非阻塞主要关注的是等待结果返回调用方的状态

阻塞:是指结果返回之前,当前线程被挂起,不做任何事

非阻塞:是指结果在返回之前,线程可以做一些其他事,不会被挂起。

可以看见同步和异步,阻塞和非阻塞主要关注的点不同,有人会问同步还能非阻塞,异步还能阻塞?当然是可以的,下面为了更好的说明他们的组合之间的意思,用几个简单的例子说明: 

1.同步阻塞:同步阻塞基本也是编程中最常见的模型,打个比方你去商店买衣服,你去了之后发现衣服卖完了,那你就在店里面一直等,期间不做任何事(包括看手机),等着商家进货,直到有货为止,这个效率很低。

2.同步非阻塞:同步非阻塞在编程中可以抽象为一个轮询模式,你去了商店之后,发现衣服卖完了,这个时候不需要傻傻的等着,你可以去其他地方比如奶茶店,买杯水,但是你还是需要时不时的去商店问老板新衣服到了吗。

3.异步阻塞:异步阻塞这个编程里面用的较少,有点类似你写了个线程池,submit然后马上future.get(),这样线程其实还是挂起的。有点像你去商店买衣服,这个时候发现衣服没有了,这个时候你就给老板留给电话,说衣服到了就给我打电话,然后你就守着这个电话,一直等着他响什么事也不做。这样感觉的确有点傻,所以这个模式用得比较少。

4.异步非阻塞:异步非阻塞这也是现在高并发编程的一个核心,也是今天主要讲的一个核心。好比你去商店买衣服,衣服没了,你只需要给老板说这是我的电话,衣服到了就打。然后你就随心所欲的去玩,也不用操心衣服什么时候到,衣服一到,电话一响就可以去买衣服了。

1.2.同步阻塞 PK 异步非阻塞

上面已经看到了同步阻塞的效率是多么的低,如果使用同步阻塞的方式去买衣服,你有可能一天只能买一件衣服,其他什么事都不能干,如果用异步非阻塞的方式去买,买衣服只是你一天中进行的一个小事。

我们把这个映射到我们代码中,当我们的线程发生一次rpc调用或者http调用,又或者其他的一些耗时的IO调用,发起之后,如果是同步阻塞,我们的这个线程就会被阻塞挂起,直到结果返回,试想一下如果IO调用很频繁那我们的CPU使用率其实是很低很低。正所谓是物尽其用,既然CPU的使用率被IO调用搞得很低,那我们就可以使用异步非阻塞,当发生IO调用时我并不马上关心结果,我只需要把回调函数写入这次IO调用,我这个时候线程可以继续处理新的请求,当IO调用结束结束时,会调用回调函数。而我们的线程始终处于忙碌之中,这样就能做更多的有意义的事了。

这里首先要说明的是,异步化不是万能,异步化并不能缩短你整个链路调用时间长的问题,但是他能极大的提升你的最大qps。一般我们的业务中有两处比较耗时: 

- cpu: 

cpu耗时指的是我们的一般的业务处理逻辑,比如一些数据的运算,对象的序列化。这些异步化是不能解决的,得需要靠一些算法的优化,或者一些高性能框架。 

- iowait: 

io耗时就像我们上面说的,一般发生在网络调用,文件传输中等等,这个时候线程一般会挂起阻塞。而我们的异步化通常用于解决这部分的问题。

1.3.哪些可以异步化?

上面说了异步化是用于解决IO阻塞的问题,而我们一般项目中可以使用异步化如下: 

- servlet异步化,springmvc异步化 

- rpc调用如(dubbo,thrift,grpc,spring cloud),http调用异步化 

- 数据库调用,缓存调用异步化

- mq异步化

下面我会从上面几个方面进行异步化的介绍.

1.3.1 servlet和springmvc异步化

同步阻塞模式的服务容器处理流程。

上面的模式优点在于编码简单,适合在项目启动初期,访问量较少,或者是CPU运算较多的项目

缺点在于,业务逻辑线程和servlet容器线程是同一个,一般的业务逻辑总得发生点IO,比如查询数据库,比如产生RPC调用,这个时候就会发生阻塞,而我们的servlet容器线程肯定是有限的,当servlet容器线程都被阻塞的时候我们的服务这个时候就会发生拒绝访问,线程不然我当然们可以通过增加机器的一系列手段来解决这个问题,但是俗话说得好靠人不如靠自己,靠别人替我分担请求,还不如我自己搞定。所以在servlet3.0之后支持了异步化,我们采用异步化之后就会变成如下:

在这里我们采用新的线程处理业务逻辑,IO调用的阻塞就不会影响我们的serlvet了,实现异步serlvet的代码也比较简单

相关效果:

可以看到容器的线程已经释放,相关业务逻辑执行交给了业务线程池。这样做可以极大地提升接口吞吐量。

springmvc有两种方式支持异步化:

一种采用DeferredResult方式,可以设置超时时间。:

另外一种是通过callable来执行:

在默认情况下,未设置TaskExecutor时,默认是使用SimpleAsyncTaskExecutor这个线程池,但此线程不是真正意义上的线程池,因为线程不重用,每次调用都会创建一个新的线程。可通过控制台日志输出可以看出,每次输出线程名都是递增的。所以最好我们来自定义一个线程池。

1.3.2 rpc的异步化(拿grpc举例子,dubbo等)

典型应用场景:

调用多个rpc服务接口进行聚合。服务之间没有依赖关系

先举例子:

做一个简单的grpc接口服务端:

用户端调用的时候存在几种方式:

一种是同步调用。比如for循环接口去根据userid拿数据。这种方式显然比较低效,因为用户和用户之间并不存在依赖关系。可以并行获取

我们想到可以并行来做:

比如采用线程池:

threadpoolexecutor,executors生成固定线程池。或者java8的CompletableFuture等。这些是我们能想到的多线程调用方式

除此之外有另外一种,比如grpc或者dubbo这些,可以通过框架层面返回future这种来实现get或者callback

比如第一种,grpc的调用,使用的是blocking的stub。循环调用100次:

查看耗时:

第二种方式我们采用异步的future的stub

首先采用future模式,首先获取所有future放到list,然后for循环获取

11

这种效果很明显。比之前快600ms将近

第二种采用自定义的线程池。采用guava的listenablefuture来做,添加callback来实现:

相关效果:

由1773→1143→1087。这个可以明显看到采用异步化的stub带来的明显的性能提升

原理其实也比较简单。rpc回传一个异步的callback返回给我们的业务。我们持有一个异步io的future句柄。通过future的get或者异步轮训来做

1.3.3 数据库的异步化操作:

对于数据库调用一般的框架并没有提供异步化的方法,这里推荐自己封装或者使用网上开源的,

美团有个开源的https://github.com/ainilife/zebra-dao/blob/master/README_ZH.md 

目前已经整合到新美大的zebra分库分表框架中

能很好的支持异步化。

上面的例子在我的项目中有可以找到源码:

https://github.com/lzcc2003/joyce

相关文章

  • 异步化介绍

    1.异步化介绍 1.1 同步和异步,阻塞和非阻塞 同步和异步,阻塞和非阻塞, 这个几个词已经是老生常谈,但是常常还...

  • 第6章 异步化与缓存原则

    第6章 异步化与缓存原则 系统性能相关的核心措施 异步化 缓存 6.1 业务流程异步化 6.2 数据库事务异步化 ...

  • ES6 Primise异步编程

    异步操作流程化的手段 #Promise处理异步操作 Promise,使异步操作变得流程化的手段之一,例如“异步A ...

  • WWDC21-Swift并发

    swift语言中的并发介绍 wwdc21-认识Swift中异步与等待 wwdc21-结构化并发

  • Promise对象

    Promise 是 JavaScript 异步操作解决方案。介绍 Promise 之前,先对异步操作做一个详细介绍...

  • HDFS内存存储原理(Lazy Persist)

    介绍 HDFS支持由Data Node管理的写入到堆栈内存的功能。Data Node会异步的将数据从内存持久化至磁...

  • AFN异步单任务请求和异步多任务请求

    此处介绍AFNetingWorking 异步单任务请求和异步多任务请求的两种方式。 为什么要使用异步请求 异步请求...

  • 企业IT架构转型之道——阿里巴巴中台战略 第六章

    异步化与缓存原则 本章介绍了一些分布式系统的基本理论,然后结合阿里的工程实践来介绍相关的经验 个人经验,高性能高并...

  • 温故之.NET 异步

    这篇文章包含以下内容 异步基础 基于任务的异步模式 部分 API 介绍 异步基础 所谓异步,对于计算密集型的任务,...

  • 认识异步编程

    认识异步编程 本章主要介绍异步编程的概念和作用,Java中异步编程的场景以及不同异步编程场景应使用什么技术实现。 ...

网友评论

      本文标题:异步化介绍

      本文链接:https://www.haomeiwen.com/subject/mmzerctx.html