Vert.x 异步Actor框架实战记录 – Part1概念介绍

JavaScript 的进攻

图片 1

Vert.x 异步Actor框架 – Part1介绍

小编整理了一些java进阶学习资料和面试题,需要资料的请加JAVA高阶学习Q群:664389243
这是小编创建的java高阶学习交流群,加群一起交流学习深造。群里也有小编整理的2019年最新最全的java高阶学习资料!

JavaScript 的进攻

一个新系统,需要集中管理公司的几个现有业务系统的基础数据。其中每个被管系统有N多实例,全球多地区异地部署。
架构挑战:

公元 2014 年,Java 第八代国王终于登上了王位。

公元 2014 年,Java 第八代国王终于登上了王位。

  • 被管系统基础数据变更需要实时收集到新系统
  • 新系统的用户指令需要实时下达到被管系统。即双向实时(双工)。
  • 网络连接单向建立:只能由被管系统主动连接新系统,并保持长连接
  • 比较多的被管系统实例,连接数不少
  • 网络情况不稳定:由于是全球部署
  • 新系统本身需要支持分布式部署。需要正确路由不同节点的用户指令到不同节点的被管系统长连接
  • 快速响应不确认的需求变化和动态调整,模块依赖性必须低,内聚性好。需要支持消息的广播和点对点传播
  • 支持灰度发布

第一次早朝,国王坐在高高的宝座上,看着毕恭毕敬的大臣,第一次体会到了皇权的威力。

第一次早朝,国王坐在高高的宝座上,看着毕恭毕敬的大臣,第一次体会到了皇权的威力。

面对以上挑战,传统的双向RPC+负载均衡架构不适合。事件驱动的框架(EDA)成为主要考虑方向
。而一个好用的EDA架构设计,需要一套成熟的架构和开发模式支持。实施时需要一套成熟的框架支持以减少工作量和提高稳定性。以下为技术选型的思考结果和说明。

德高望重的 IO 大臣颤悠悠地走上前来:“启禀陛下,昨日收到战报,有个叫做
Node.js 的番邦又一次向我国进攻,我边防将士死伤惨重。”

德高望重的 IO 大臣颤悠悠地走上前来:“启禀陛下,昨日收到战报,有个叫做
Node.js 的番邦又一次向我国进攻,我边防将士死伤惨重。”

1.基本概念

“Node.js? 那是什么东西?” 国王心中一乐, 还真有人自不量力,想蚍蜉撼树。
想我 Java
帝国人口之众多,疆域之广阔,踩死你小番邦还不像踩死一只蚂蚁似的。

“Node.js? 那是什么东西?” 国王心中一乐, 还真有人自不量力,想蚍蜉撼树。
想我 Java
帝国人口之众多,疆域之广阔,踩死你小番邦还不像踩死一只蚂蚁似的。

1.1 Actor Model 模式

“那是用 JavaScript 写的一个框架。” IO 大臣看到国王不知道
Node.js,心里一沉。

“那是用 JavaScript 写的一个框架。” IO 大臣看到国王不知道
Node.js,心里一沉。

What:什么是Actor模式

Actors communicate with each other by sending asynchronous messages.
Those messages are stored in other actors’ mailboxes until they’re
processed.

出处:http://www.brianstorti.com/the-actor-model/

形象点说,每个Actor是一个人,他有多个输入源(耳、鼻、眼),同一时间他只能就输入源来响应做一件事。他有自己的记忆(状态)。他耐性不好,向其它人口头下达指令后,不等其它人做完就忙其它的事情去了。

每个Actor可认为一个Event
Loop可简单理解为线程(实际可能多个Actor共享线程)。它有以下组件:

  • 事件信箱
  • 内部状态数据

Actor Event Loop的状态有:

  • 等待信箱事件
  • 处理事件中(运行中)

一般,研发会使用异步IO编程方法,来实现具体的Actor。即,具体Actor的关心的IO读写事件也会放入Actor自己的信箱。处于【处理事件中】的事件消费程序,不会有IO引起的Block等待。

“JavaScript?爱卿说笑了,一个在浏览器中运行的东西,怎么可能进攻我 Java
后端。”

“JavaScript?爱卿说笑了,一个在浏览器中运行的东西,怎么可能进攻我 Java
后端。”

Why: Actor模式的用处

  • 简化多线程编程:单线程的Actor程序,可以保证内部状态不并发访问。不再需要考虑多线程共享状态下的各种问题。
  • 天然分布式设计:Actor间基于消息的通讯,天然地支持分布式的部署,如果使用合适的Actor容器,多Actor实例的管理等,天然地实现了“微服务”架构。
  • HA:Actor
    容器可以用统一的健康探测消息,来测试Actor的健康情况。需要时可以重启新的Actor
  • 其它Event Driven Arch(EDA)的好处。

“陛下有所不知,这 JavaScript 发展迅猛,不仅占领了前端,还通过 Node.js
向后端,尤其是我国渗透,臣还听说他们用 Electron 开始蚕食桌面开发了!”

“陛下有所不知,这 JavaScript 发展迅猛,不仅占领了前端,还通过 Node.js
向后端,尤其是我国渗透,臣还听说他们用 Electron 开始蚕食桌面开发了!”

Who:谁在用Actor模式

  • Erlang
  • Akka
  • Vert.x
  • ……

“竟有这等事!难道他们想通吃?我们不是有 Tomcat 吗?派 Tomcat 去把
Node.js 给镇压了。”

“竟有这等事!难道他们想通吃?我们不是有 Tomcat 吗?派 Tomcat 去把
Node.js 给镇压了。”

1.2 Vert.x

国王开始怨恨自己的父亲 JDK 7 世和祖父 JDK 6 世没把这个 Node.js
当成一回事,没有把 Node.js
给扼杀在摇篮之中,把这个祸害留给了自己,心里开始发虚。

国王开始怨恨自己的父亲 JDK 7 世和祖父 JDK 6 世没把这个 Node.js
当成一回事,没有把 Node.js
给扼杀在摇篮之中,把这个祸害留给了自己,心里开始发虚。

What:什么是Vert.x

官话是这样说的:
Eclipse Vert.x is a tool-kit for building reactive applications on the
JVM.

  • Scale:Eclipse Vert.x is event driven and non blocking. This means
    your app can handle a lot of concurrency using a small number of
    kernel threads. Vert.x lets your app scale with minimal hardware.
  • Polyglot:You can use Vert.x with multiple languages including Java,
    JavaScript, Groovy, Ruby, Ceylon, Scala and Kotlin.
  • General purpose:Vert.x is incredibly flexible – whether it’s simple
    network utilities, sophisticated modern web applications, HTTP/REST
    microservices, high volume event processing or a full blown back-end
    message-bus application, Vert.x is a great fit.
  • fun:Enjoy being a developer again.Unlike restrictive traditional
    application containers, Vert.x gives you incredible power and
    agility to create compelling
    , scalable, 21st century applications
    the way you want to, with a minimum of fuss, in the language you
    want.

我关注的是最后一点:)
有人说它是java界的Node.js。但它自称性能上,多语言上超越Node.js。有人说它是瑞士军刀,管饭还管车,因为他是个异步框架,Web框架,也送Event
Bus,支持Actor模式,支持微服务管理和发现等等……我真心怀疑它能做得精吗?

Actor框架
Actor,在Vert.x中叫Verticle。(http://vertx.io/docs/vertx-core/java/#_verticles)

Event Bus
事件总线,支持事件广播、点到点发送、点对点发送与回复(Reply)
http://vertx.io/docs/vertx-core/java/#event_bus

并发编程框架

  • inline异步任务(Verticle中异步调用阻塞代码的类似ForkJoinPool)
  • Future的串并联使用,异步任务与结果的封装
  • 莱坞原则的异步Callback编程

异步IO编程框架

异步IO编程框架1

异步IO编程框架2

响应式编程
如果你认为OOP或好莱坞原则的异步Callback编程已经OUT了,或者已经被Callback
Hell坑过。那么可以试试Reactive。Vert.x 支持Rx-ified using
RxJava

集群
跨JVM的集群Event Bus,基于hazelcast来实现集群的发现和消费订阅的登记
http://vertx.io/docs/vertx-core/java/#_cluster_managers

集群

非阻塞异步 IO

非阻塞异步 IO

1.2.1 Vert.x 中的Actor模式怎么玩

Actor模式在Vert.x中这样体现:

  • Actor –> Verticle
  • 信箱 –> 一般的事件,如Event Bus
    消息到达池。还有其它事件,如Http/Websocket/异步JDBC请求或事件池、inline异步任务(Verticle中异步调用阻塞代码的类似ForkJoinPool)的结果池。
  • Actor的信箱消费线程–> Event Loop

所以,黄金规则是Verticle中不能写阻塞的代码,如果一定要用,解决方法是:放在后台工作线程池中阻塞

线程大臣走上前来:“陛下,Tomcat 已经率军和 Node.js
恶战了几日,败下阵来, 这 Node.js 有个独门武器,叫做‘非阻塞异步 IO’。”

线程大臣走上前来:“陛下,Tomcat 已经率军和 Node.js
恶战了几日,败下阵来, 这 Node.js 有个独门武器,叫做‘非阻塞异步 IO’。”

1.2.2 Vert.x EventBus是什么

Vert.x EventBus是个普通的无中心消息框架

  • 消息框架支持:
  • 事件广播
  • 点到点发送
  • 点对点发送与回复(ACK)

**事件广播**

**点到点发送**

**点对点发送与回复(ACK)**

事件总线的作用:

  • 事件的发生源模块,事件的监听模块完全解藕。
  • 事件可以支持广播、路由、点对点等方法传递。生产者不关心订阅者的数量、实现逻辑。
  • 生产者与订阅者可以关注自己的subject。生产者与订阅者间没有相互的依赖关系。

SLA:

  • 消息没有持久化,可能丢失。消息的投递以最大努力为原则,即不保证成功

Vert.x EventBus是个分布式消息框架

Vert.x EventBus是个分布式消息框架

  • 支持机器间EventBus的集群共享(可选基于hazelcast),消息和Subject可以在集群中传播。
  • 在有分布式部署,功能和服务热插拔,HA要求的情况下可以灵活支撑。
  • 集群自治,同时支持成员的发现和异常发现

Vert.x EventBus是个打通到客户端的消息框架,是个All in one工具集

Web socket EventBus支持

由于它包含一个EventBus SockJS
Bridge。模块,浏览器可以通过它提供的JS库,使用sockjs协议(Server-Sent
Events/Websocket/HTTP
poll)来接入EventBus。官方文档:http://vertx.io/docs/vertx-web/java/#_sockjs_event_bus_bridge
好处:

  • 后端的事件,可以实时通知到浏览器(提供event bus
    javascript库),实时推浏览器的广播变得相对容易实现。想想一个长后台任务完成,或监控事件发发时,一切都变得实时响应到用户端。
  • 浏览器也可以向后端发送异步指令和请求。

“非阻塞? 我听说我们的 Tomcat 也能实现非阻塞啊!” 国王有点惊讶。

“非阻塞? 我听说我们的 Tomcat 也能实现非阻塞啊!” 国王有点惊讶。

官网外的资料:

  • https://www.slideshare.net/jettro/creating-polyglot-and-scalable-applications-on-the-jvm-using-vertx
  • http://slidedeck.io/michaelkuty/vertx-gdg

“不行的,陛下,Tomcat
在处理连接的时候能实现非阻塞,但是在真正处理请求的时候还是需要同步操作,一个请求对应一个线程来处理,不像
Node.js 那样,都是异步操作,只有一个主线程在忙活。”
线程大臣做了一个简明扼要的汇报,不知道国王能否听懂。

“不行的,陛下,Tomcat
在处理连接的时候能实现非阻塞,但是在真正处理请求的时候还是需要同步操作,一个请求对应一个线程来处理,不像
Node.js 那样,都是异步操作,只有一个主线程在忙活。”
线程大臣做了一个简明扼要的汇报,不知道国王能否听懂。

“众位爱卿,你们说说该怎么办? 总不能让这小小番邦屡次欺负我堂堂 Java
帝国吧。”

“众位爱卿,你们说说该怎么办? 总不能让这小小番邦屡次欺负我堂堂 Java
帝国吧。”

“臣倒是有一计,” 集合大臣说道,“这 Node.js
虽然来势汹汹,但是它也有个致命的缺点,那 JavaScript
是个动态语言,无法进行编译时类型检查,错误只有等到运行时才能暴露出来。用它开发个小项目还可以,一旦项目变大,代码变多,人员变多,那就会变成噩梦了。”

“臣倒是有一计,” 集合大臣说道,“这 Node.js
虽然来势汹汹,但是它也有个致命的缺点,那 JavaScript
是个动态语言,无法进行编译时类型检查,错误只有等到运行时才能暴露出来。用它开发个小项目还可以,一旦项目变大,代码变多,人员变多,那就会变成噩梦了。”

“爱卿说说具体怎么办?”

“爱卿说说具体怎么办?”

“我们可以派一些卧底去 Node.js,
到处传播这样的消息,瓦解他们的军心和士气,让他们认为 Node.js
写的系统,很快就会腐化,最终还是要用我堂堂正正的 Java 语言来重写。”

“我们可以派一些卧底去 Node.js,
到处传播这样的消息,瓦解他们的军心和士气,让他们认为 Node.js
写的系统,很快就会腐化,最终还是要用我堂堂正正的 Java 语言来重写。”

“嗯,此乃心理战也,至少会稳住一些墙头草,准奏,由爱卿来安排。 ”
国王说道,“不过,此法治标不治本,还是得想办法直接把他们打败。”

“嗯,此乃心理战也,至少会稳住一些墙头草,准奏,由爱卿来安排。 ”
国王说道,“不过,此法治标不治本,还是得想办法直接把他们打败。”

“陛下真乃一代圣君,”
线程大臣马上开始拍马屁,与此同时,巧妙地把矛头转向老不死的 IO 大臣:“我
Java 帝国在第 4 代国王的时候就出现了非阻塞
IO,这么多年过去了,居然还没发展出类似 Node.js 的系统,实在是不应该啊。”

“陛下真乃一代圣君,”
线程大臣马上开始拍马屁,与此同时,巧妙地把矛头转向老不死的 IO 大臣:“我
Java 帝国在第 4 代国王的时候就出现了非阻塞
IO,这么多年过去了,居然还没发展出类似 Node.js 的系统,实在是不应该啊。”

“老不死”的 IO 大臣是何等精明:“陛下明鉴, 我 Java
帝国应用服务器一直以来都是 Tomcat
独大,他们采用了线程池,每个请求一个线程的方式,我也不好干预。”

“老不死”的 IO 大臣是何等精明:“陛下明鉴, 我 Java
帝国应用服务器一直以来都是 Tomcat
独大,他们采用了线程池,每个请求一个线程的方式,我也不好干预。”

IO 大臣把责任推得一干二净。

IO 大臣把责任推得一干二净。

“没错,” 集合大臣为 IO
大臣打抱不平,两肋插刀,“还有一点就是这异步编程,听起来很好,但是写起来可就要命了,那么多的回调,简直就是反人类,臣民们戏称为回调地狱,没人愿意那么写,发展不起来也很正常。”

“没错,” 集合大臣为 IO
大臣打抱不平,两肋插刀,“还有一点就是这异步编程,听起来很好,但是写起来可就要命了,那么多的回调,简直就是反人类,臣民们戏称为回调地狱,没人愿意那么写,发展不起来也很正常。”

线程大臣马上接口:“此言差矣,陛下已经教会了臣民们如何使用 Lambda
表达式,并且现在也出现了 RxJava,已经没什么回调地狱了!”

线程大臣马上接口:“此言差矣,陛下已经教会了臣民们如何使用 Lambda
表达式,并且现在也出现了 RxJava,已经没什么回调地狱了!”

“那是现在,以前可没有!”

“那是现在,以前可没有!”

“……”

“……”

国王看到这几位大臣要打起来,马上施展和稀泥之术:“众位爱卿各有道理,你们且说说,怎么才能打败着来势汹汹的
Node.js 吧。”

国王看到这几位大臣要打起来,马上施展和稀泥之术:“众位爱卿各有道理,你们且说说,怎么才能打败着来势汹汹的
Node.js 吧。”

没人说话。

没人说话。

国王只好退朝。

国王只好退朝。

京城酒馆

京城酒馆

京城的小酒馆向来是一个多方消息的集散地。

京城的小酒馆向来是一个多方消息的集散地。

一个金发碧眼的小伙子正在“危言耸听”:“听说了没有,Node.js
又赢了几仗,Tomcat 大军死伤惨重,有不少臣民都投奔到那个番邦去了。”

一个金发碧眼的小伙子正在“危言耸听”:“听说了没有,Node.js
又赢了几仗,Tomcat 大军死伤惨重,有不少臣民都投奔到那个番邦去了。”

“这异步操作真的有这么厉害?” 有人问道。

“这异步操作真的有这么厉害?” 有人问道。

小伙子喝了一口酒:
“其实不是异步操作更好,而是在高并发的环境异步操作更有效,大家都知道,
一个机器能支持的线程数目是有限的,不可能一直增加。Tomcat
那种一个请求一个线程的方式很快就会遇到瓶颈。”

小伙子喝了一口酒:
“其实不是异步操作更好,而是在高并发的环境异步操作更有效,大家都知道,
一个机器能支持的线程数目是有限的,不可能一直增加。Tomcat
那种一个请求一个线程的方式很快就会遇到瓶颈。”

“你说说,到底有什么好处?”有人刨根问底。

“你说说,到底有什么好处?”有人刨根问底。

“现在服务器端的操作无非就是操作文件,读写数据库,访问远程服务,这些都是所谓阻塞操作。”
小伙子展开了一张图:

“现在服务器端的操作无非就是操作文件,读写数据库,访问远程服务,这些都是所谓阻塞操作。”
小伙子展开了一张图:

图片 2

图片 3

“橙色的都是 IO 操作,绿色的才是真正的线程执行, IO
操作非常耗时,线程大部分时间都浪费在了等待上面!如果能让线程不要等待,去做别的事情,那用少量的线程,甚至一个线程就可以了。”

“橙色的都是 IO 操作,绿色的才是真正的线程执行, IO
操作非常耗时,线程大部分时间都浪费在了等待上面!如果能让线程不要等待,去做别的事情,那用少量的线程,甚至一个线程就可以了。”

众人纷纷点头, 这小伙子已经看出了问题的关键,现在的很多系统,都是 IO
密集的, 高并发情况下,如果一个请求一个线程,浪费巨大。

众人纷纷点头, 这小伙子已经看出了问题的关键,现在的很多系统,都是 IO
密集的, 高并发情况下,如果一个请求一个线程,浪费巨大。

“想我 Java 虚拟机如此强悍,如果能实现异步操作,那还不把 Node.js
秒成渣?!”小伙子狠狠地用手锤了一下桌子。

“想我 Java 虚拟机如此强悍,如果能实现异步操作,那还不把 Node.js
秒成渣?!”小伙子狠狠地用手锤了一下桌子。

正在此时,酒馆冲进一队士兵,赶走众人,围住小伙子,领头的喝问到:“大胆刁民,竟然到处宣扬异步思想,给我带走!”

正在此时,酒馆冲进一队士兵,赶走众人,围住小伙子,领头的喝问到:“大胆刁民,竟然到处宣扬异步思想,给我带走!”

士兵恶狠狠地把他五花大绑,推出门去, 留下一堆人在那里议论纷纷。

士兵恶狠狠地把他五花大绑,推出门去, 留下一堆人在那里议论纷纷。

IO 王府

IO 王府

“我让你们把他请来,怎么绑来了?快松绑!” IO
大臣呵斥完下属,转头亲切地问道:“叫什么名字啊?”

“我让你们把他请来,怎么绑来了?快松绑!” IO
大臣呵斥完下属,转头亲切地问道:“叫什么名字啊?”

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*
*
Website