全异步架构

背景:

语言层面nodeJS算是一个巨大的创新,第一次引入全异步API,从而风靡一时,后来go lang也凭借goroutine简洁高效的并发特性在网络与DB中间件领域崭露头角。只有JVM虽然早就支持多线程模型也有NIO与AIO优秀的异步特性但NIO侧重服务器的IO处理上,脱离了人民群众,要知道码农门才不需要直接操作NIO与AIO,基本一个netty足矣~多线程的写法又很丑陋低效,而程序员们care的是如何能写出甚至媲美go lang的并发代码!这一切在2017年的kotlin coroutine的release而成为现实。coroutine借鉴了C#与golang等语言的优秀并发特性将其在JVM上实现,而从间接的帮助java重新焕发了生机。

另外Spring 5.0带来崭新的reactive特性,算是正式将java推向reactive lang。为什么这么说呢,因为java本身虽然早就支持多线程,但是多线程的写法特别不优雅也很容易出错也不方便调试。服务器端虽然支持异步servlet、NIO与AIO等非阻塞功能,但是例如jdbc还是同步阻塞的。 就像NIO目前netty独霸天下一样,类似go lang简洁高效的异步编程近几年的需求越来越强烈,这几年jvm平台也诞生了众多优秀的异步编程思想与框架,例如以akka为代表的actor与以rxjava为代表的reactive模式。虽然这些异步框架性能也都可以与go lang媲美但是编程方式还是要丑陋与困难的多,而这一切在kotlin coroutine的正式发布后得以彻底改变,jvm也将迎来了全异步新时代。

何谓全异步呢我先给大家介绍下现有大家用的比较多的spring cloud微服务架构,通用的架构是

这里假设DB为mysql,那么从一个请求从LB进来的整个流程除了特殊处理一般都是阻塞的,每个请求占用一个线程,虽然Tomcat内部使用线程池技术来缓冲创建线程的性能损失,整体的cpu利用率还是很低的,一旦10000个请求瞬间进来,线程池会立刻被打满,若后台任务执行也较慢,很快Tomcat会处于无法提供服务状态。即使Tomcat使用了异步servlet,cloud APP内部使用多线程,整个应用的性能与go lang比还是差多了,为什么呢?根本原因在于go lang 协程对CPU利用的高效。协程可以简单理解为轻量级的线程,每个线程池队列中的任务可以简单当成一个协程任务来理解。当你在jvm创建100个线程去处理并发问题时候,协程甚至可以开到10000+,由此带来的效率提升是巨大的。下面给给大家介绍全异步的架构:

整体架构从服务器到代码再到DB全是非阻塞,一个请求进来马上就会被返回给客户端,客户端在回调中非阻塞等待服务器执行完成,整个过程都是非阻塞的。下面我逐一解释,首先netty本身就是NIO非阻塞的行家,其使用非常高效的EventLoop模式可充分利用线程资源。再是DB,这里与之前的区别在于加上了reactive,因为java jdbc本身还是阻塞的,所以这里暂时排除在外,reactive DB主要指类似MongoDB,redis等支持非阻塞请求的数据库。最后详细说说reactive spring APP,这里除了只最新的reactive spring外,还有一个非常重要的部分是kotlin coroutine。没有coroutine协程,reactive 可以高效但不简洁,coroutine+reactive将JVM多线程编程推向了新的甚至可以超越go lang 的高度。下面隆重给大家介绍coroutine技术以及与常见多线程模型的对比(这块coroutine的作者正好在Qcon2018上分享了他的coroutine,我这就直接借用他的经典范例了~)。

首先看看js丑陋的callback吧,类似如下代码(kotlin的写法)

然后各种语言发明了Futures,Promises还有Rx系列解决这种callback hell,大致做法如下,使用then去掉了lambda嵌套:

好像还不优雅,then来then去的,我们来看看kotlin的做法

是不是很震惊,异步代码竟然写的与同步代码一样,因为kotlin默认各个suspend异步函数就是“串行”执行的,表面上是串行的阻塞代码其实内部使用coroutine调度实现自动的依赖顺序执行。另外除了自身语法糖外,kotlin coroutine官方还做了如下集成,可极大简化那些框架的编程方式。

顺便说一句kotlin coroutine对spring也有集成,spring boot官方甚至直接推出了kotlin模板,一切的一切都是为了编程的根本:简洁与高效。

让我们一起拥抱全异步架构吧~

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180522G1MRBE00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券