Vert.x是基于事件的,提供一个事件驱动编程模型
使用Vert.x作为服务器时,程序员只要编写事件处理器event handler即可。(当TCP socket有数据时,event handler被创建调用)
另外它还可以在以下几种情况激活:
Vert.x是一个异步非阻塞框架,可以有更高并发特性
使用它,可以灵活的部署与卸载相应的灰度控制(热部署,无需重启服务),函数式,serverless。需要什么,把配置加上去,就可以实现服务。
Vert.x的核心运行机制是事件循环,当Vert.x实例启动后,Vert.x框架在每个CPU的内核创建一个事件循环线程(Event Loop Vertical)。此事件循环线程永不结束,它不断监听出现的各种事件,如事件总线的事件到达WebSocket上的数据接收,HTTP上的请求到达HTTP响应结束,定时器触发等等,并把事件分发到注册了监听此事件的Verticle
,再继续监听其他的事件,如此反复直到Vert.x实例停止。
Vert.x的事件机制中有几个非常重要的概念:
Event Loop
:即事件循环,是由Vert.x启动的事件处理线程,也是Vert.x项目对外开放的入口,Vert.x由此接收请求事件。一个Vert.x有一个或多个事件循环线程组成,线程最大数量为主机有效的CPU核数。Event Loop Vertical
:事件的业务处理线程,存在于Event Loop中,用于处理非阻塞短任务。Worker Vertical
: 事件的业务处理线程,用于处理长任务阻塞任务。Event Bus
:即事件总线,是Vert.x事件模型中最核心的部分,所有的事件都经由事件总线进行分发,包括Vertical之间的通信事件。Vert.x Module
: Vert.x项目模块,一个应用通常由多个模块组成,每个模块一般包含多个VerticalVert.x以非阻塞IO的思想来实现高性能,非阻塞IO的实现,基于Event Loop Vertical
和Worker Vertical
的分离。
在Vert.x中,Event Loop
用于接收,并将短业务操作交由其内部的Vertical来处理,该模块是非阻塞的,这样可以保证请求的处理效率;阻塞任务通过Vert.x的事件机制脱离当前线程,转移到Worker Vertical
中执行,并执行结果返回给Event Loop Vertical
。 这一过程完成的核心是Event Bus
,Event Bus
中注册了所有的事件,通过事件匹配完成事件转移和结果返回,从而将整个流程衔接起来
下面以一个HTTP请求的处理过程详述Vert.x的事件处理流程。
事件驱动的处理过程,数据传递是非常重要的,Vert.x支持任意对象的数据格式。但使用对象时经常会遇到序列化和载入类的问题,比如在使用Java对象的时候,这种情况下使用JSON会更方便,这也是Vert.x推荐采用的方式
Vert.x 的核心 Java API 被我们称为 Vert.x Core。
Vert.x Core 提供了下列功能:
Vert.x Core中的功能相当底层——您在此不会找到诸如数据库访问、授权或高层Web应用的功能。您可以在Vert.x ext(扩展包)中找到这些功能。
Vert.x的扩展包是Vert.x的子项目集合,类似Web、Web Client、Data Access等
Vert.x Core小而轻,您可以只使用您需要的部分。它可整体嵌入现存应用中。我们并不会强迫您用特定的方式构造您的应用。
io.vertx vertx-core 3.4.2
这儿有三种不同类型的 Verticle:
Stardand Verticle
:这是最常用的一类 Verticle —— 它们永远运行在 Event Loop 线程上Worker Verticle
:这类 Verticle 会运行在 Worker Pool 中的线程上。一个实例绝对不会被多个线程同时执行Multi-Threaded Worker Verticle
:这类 Verticle 也会运行在 Worker Pool 中的线程上。一个实例可以由多个线程同时执行(因此需要开发者自己确保线程安全)当 Standard Verticle 被创建时,它会被分派给一个 Event Loop 线程,并在这个 Event Loop 中执行它的start
方法。当您在一个 Event Loop 上调用了 Core API 中的方法并传入了处理器时,Vert.x 将保证用与调用该方法时相同的 Event Loop 来执行这些处理器。
这意味着我们可以保证您的 Verticle 实例中所有的代码都是在相同Event Loop中执行
同样意味着您可以将您的应用中的所有代码用单线程方式编写,让 Vert.x 去考虑线程和扩展问题。您不用再考虑 synchronized 和 volatile 的问题,也可以避免传统的多线程应用经常会遇到的竞态条件和死锁的问题。
Worker Verticle 和 Standard Verticle 很像,但它并不是由一个 Event Loop 来执行,而是由Vert.x中的 Worker Pool 中的线程执行。Worker Verticle 被设计来调用阻塞式代码,它不会阻塞任何 Event Loop。
如果您不想使用 Worker Verticle 来运行阻塞式代码,您还可以在一个Event Loop中直接使用内联阻塞式代码
若您想要将 Verticle 部署成一个 Worker Verticle,您可以通过setWorker
方法来设置:
DeploymentOptions options = new DeploymentOptions().setWorker(true);
vertx.deployVerticle("com.mycompany.MyOrderProcessorVerticle", options);
Worker Verticle 实例绝对不会在 Vert.x 中被多个线程同时执行,但它可以在不同时间由不同线程执行。
一个 Multi-threaded Worker Verticle 近似于普通的 Worker Verticle,但是它可以由不同的线程同时执行。
警告:Multi-threaded Worker Verticle 是一个高级功能,大部分应用程序不会需要它。由于这些 Verticle 是并发的,您必须小心地使用标准的Java多线程技术来保持 Verticle 的状态一致性。
参考资料: