vert.x详细介绍,全异步框架
Vert.x是一个基于JVM、轻量级、高性能的应用平台,非常适用于最新的移动端后台、互联网、企业应用架构。Vert.x基于全异步Java服务器Netty,并扩展出了很多有用的特性
github: https://github.com/vert-x3
介绍:
Vert.x诞生于2011年,当时叫node.x,不过后来因为某些原因改名位Vert.x。经过三年多的发展,现在已经到了3.3.3版本,社区也越来越活跃,在最新的官网Vertx.io上,作者用一句话介绍了它,JVM上的Reative开发套件。Vert.x目前是见过最功能最强大,第三方库依赖最少的Java框架,它只依赖Netty4以及Jacskon,另外如果你需要建立分布式的Vert.x则再依赖HazelCast这个分布式框架,注意Vert.x3必须基于Java8。由于基于JVM,所以Vert.x可以用其他语言来实现你的业务。
Vert.x是一个异步无阻塞的网络框架,其参照物是node.js。基本上node.js能干的事情,Vert.x都能干。Vert.x利用Netty4的EventLoop来做单线程的事件循环,所以跑在Vert.x上的业务不能做CPU密集型的运算,这样会导致整个线程被阻塞。
特性:
1、同时支持多种编程语言——目前已经支持了Java、Scala、JavaScript、Ruby、Python、Groovy、Clojure、Ceylon等。对程序员来说,直接好处就是可以使用各种语言丰富的LIB,同时也不再为编程语言选型而纠结;
2、异步无锁编程——经典的多线程编程模型能满足很多Web开发场景,但随着移动互联网并发连接数的猛增,多线程并发控制模型性能难以扩展,同时要想控制好并发锁需要较高的技巧,目前Reactor异步编程模型开始跑马圈地,而Vert.x就是这种异步无锁编程的一个首选;
3、对各种IO的丰富支持——目前Vert.x的异步模型已支持TCP、UDP、FileSystem、DNS、EventBus、Sockjs等;
极好的分布式开发支持——Vert.x通过EventBus事件总线,可以轻松编写分布式解耦的程序,具有很好的扩展性;
4、生态体系日趋成熟——Vert.x归入Eclipse基金会门下,异步驱动已经支持了Postgres、MySQL、MongoDB、Redis等常用组件,并且有若干Vert.x在生产环境中的应用案例。
Vert.x是基于事件的,提供一个事件驱动编程模型,使用Vert.x作为服务器时,程序员只要编写事件处理器event handler即可. 当TCP socket有数据时,event handler理解被创建调用,另外它还可以在以下几种情况激活: '当事件总线Event Bus接受到消息时,' '当接收到HTTP消息时,' 当一个连接断开时',' '当计时器超时时.'
作为服务层处理逻辑这一层基本上对应的传统Java里的领域模型处理层.各种Service调用,以及对数据层的调用.差不多是一个承上启下的一层.传统的模型里,这一层基本上都是同步调用,即使有异步调用,也是与业务逻辑分离的异步.如果全异步会导致业务逻辑碎乱.代码很难描述清楚.到这里你会发现Vert.x其实不太好融合到业务性很强的服务层里.其主要原因如下
1、自身是异步体系,不适合描述顺序逻辑性强的业务
2、由于异步的问题,访问数据层也必须是异步,导致业务模型进一步碎片化.
Vert.x的执行单元叫verticle。即程序的入口,每个语言可能实现的方式不一样,比如Java需要继承一个AbstractVerticle抽象类
verticle分两种,一种是基于EventLoop的适合I/O密集型的,还有一种是适合CPU密集型的worker verticle。而verticle之间相互通信只能通过Eventbus,可以支持point to point 的通信,也可以支持publish & subscribe通信方式。
重要的接口
org.vertx.java.core.Handler
Vert.x运行时的核心接口, 用于结果回调处理,你大部分的逻辑代码都会在这里执行.所以无需解释.
org.vertx.java.core.Context
这个名词的含义就是一个基于Vert.xAPI搭建起来的可运行的程序.这里我们就简单的理解继承了org.vertx.java.platform.Verticle的Java类或者其他语言的脚本
那Context接口就代表着一次可执行单元的上下文,这里的上下文只干一件事情就是处理Handler里的内容void runOnContext(Handler<Void> action);,
在Vert.x里有两种上下文,即EventLoop与Worker,而Worker又会分按顺序执行的Worker与多线程Worker.这里我们就先看成两类EventLoop与Worker,什么是EventLoop呢.
在Vert.x里所有的事件包括IO都是依赖于Netty的EventLoop接口,而这个接口在Netty里会一定的频率调用.即当发生IO事件时,Netty会按时间比率分配CPU资源去响应这个事件.
在Vert.x里你可以简单的理解为IO相关的事件就可以了,用了一个特定的线程池来响应这类请求.而Worker在Vert.x里默认是一套按顺序执行的Handler,即按照先来先到的顺序依次执行,此类的请求是另一个线程池执行.
所有业务逻辑其实都会跑在Netty里的EventLoop上,而EventLoop通过循环事件队列来执行所有的业务逻辑,这样可以把一些I/O操作频繁的事件及时从CPU上剥离开来,最后通过注册一个回调Handler来处理所有的事件回调
org.vertx.java.core.Vertx
这个其实就是API,非Vert.x扩展者,能用到的所有的东西都在这里了.基于上面的三个接口,其实就能抽象出一个异步的模型,通过Vertx接口调用一个API,API内部会持有一个Context,在API本身的非业务逻辑执行完后,将Handler传入Context执行.这大概就是整个Vert.x内部执行的流程,三个接口抽象出一个世界这便是软件设计的哲学.
重要概念
Verticle
基于Vert.x框架实现的代码包,就是一个Verticle,简单点说,一个可以被Vert.x框架执行的代码调用了Vert.xAPI的代码就是一个Verticle.他可以用Scala Clojure JS Ruby等语言实现.多个Verticle实例可以并行的被执行.一个基于Vert.x的服务也许需要多个verticles来实现,而且要部署在多台服务器上.他们之间通过vert.x事件进行通信.你可以之间通过vert.x命令启动,也可以将verticle包装成vert.x modules.
Module
Vert.x应用由一个或多个modules来实现.一个模块呢由多个verticles来实现.你可以把module想象出一个个Java package.里面可能是特定业务的实现,或者公共的服务实现(那些可以重用的服务).Vert.x编写好的module,可以发布到maven的仓库里.以zip包装成二进制格式.或者发布到vert.x module 注册中心.实际上这种以模块方式的开发,支撑着整个Vert.x生态系统.Module更多的信息,我需要单独开一个系列来讲解.
Event Bus:
它是Vert.X的核心,在集群中容器之间的通信,各个Verticle之间的通讯都是经过Event Bus来实现的,后期会推出一篇专门关于这个的文章,敬请等待。
Shared Data:
它是Vert.X提供的一个简单共享Map和Set,用来解决各个Verticle之间的数据共享
框架图
实例:
- public class HelloWorldEmbedded {
- public static void main(String[] args) {
- // Create an HTTP server which simply returns "Hello World!" to each request.
- Vertx.vertx().createHttpServer().requestHandler(req -> req.response().end("Hello World!")).listen(8080);
- }
- }
启动一个verticle
- vertx.deployVerticle(DingtalksrvVertical.class.getName(), deploymentOptions, result -> {
- if (result.succeeded()) {
- String deployId = result.result();
- System.out.println("Dingtalksrv 部署成功 [" + deployId + "]");
- future.complete();
- } else {
- System.out.println("Dingtalksrv 部署失败 " + result.cause().getMessage());
- future.fail(result.cause());
- }
- });
启动服务
- HttpServerOptions options = createOptions();
- server = vertx.createHttpServer(options);
- server.requestHandler(mainRouter::accept);
- server.listen(result -> {
- if (result.succeeded()) {
- } else {
- }
- });
- mainRouter = Router.router(vertx);
- mainRouter.mountSubRouter("/api", router);
- Router router = Router.router(vertx);
- router.route(HttpMethod.POST, "/hello").handler(HelloHandler()::handleRequest);
异步封装
- executor.executeBlocking((Future<T> f) -> {
- try {
- jdbc_routine();
- }
- f.complete();
- } catch (SQLException e) {
- f.fail(e);
- }
- }, handler);
Vert.x3支持很多常用工具:metrics、热部署、consul、kafka、mongo、redis等
有兴趣可以到github上查看相应组件
Vert.x的执行单元叫verticle。即程序的入口,每个语言可能实现的方式不一样,比如Java需要继承一个AbstractVerticle抽象类
verticle分两种,一种是基于EventLoop的适合I/O密集型的,还有一种是适合CPU密集型的worker verticle。而verticle之间相互通信只能通过Eventbus,可以支持point to point 的通信,也可以支持publish & subscribe通信方式。