Vert.x的原理分析
1.Vert.x保护那些组件,我们需要那些?从哪里开始?
Vert.x包含几个不同的组件,旨在使您可以更轻松地用多种不同的语言编写引人注目的反应式应用程序。Vert.x是高度模块化的,你只需要使用所需的模块即可,并且不要忘了Vert.x是一个库,不是限制性容器,因此vert.x可以和其他组件一起使用,可以将Vert.x与所需的所有常用库一起使用。
vertx.包含非常多的组件,我下面介绍几个关键的常用组件。
Core: 也称为Vertx的核心,Vert.x核心包含非常底层的功能,包括对HTTP,TCP,文件系统访问和各种其他功能的支持。您可以在自己的应用程序中直接使用它,而Vert.x的其他组件也可以使用它,这也是为什么称之为核心的原因。
Vert.x-Web:是用于编写复杂的现代Web应用程序和HTTP微服务的工具包,如果你的微服务是提供高速的HTTP接口(不一定是restful 风格,但推荐采用restful风格), 那么vert.x web这个轻量级的库是很好的选择,你不必为你的微服务选择庞大、复杂的servlet框架,配置servlet容器,vert.x-web提供了很简洁高效的方式,仅仅启动一个本地应用程序,就能提供非常高性能的HTTP服务。
Vert.x Web client: 是易于使用的高级HTTP客户端。 Vert.x Web客户端是异步HTTP和HTTP / 2客户端, 他的优点是支持异步、支持HTTP2, 但不支持cookies的处理。 这样的客户端很多,相比apache的httpclient并没有太大的优势,笔者不建议使用,但大家可以了解一下,会不会成为下一个牛逼的开源组件,也未尝可知。
Web API Contract: 我翻译成 API 契约,它扩展了Vert.x Web以支持OpenAPI 3,提供了一个简单的接口来构建路由规则,并很容易的添加安全性和验证处理程序。
听起来有点难懂,我先解释一下什么是openAPI 3: 它是一套描述API的广泛采用的行业标准。OpenAPI规范(OAS)是为REST API定义的标准的,它用编程语言无关的接口描述,它使人和计算机都可以发现和理解接口定义的服务的功能,而无需看源代码,附加文档或网络抓包。 通过OpenAPI定义后,消费者可以使用最少的实现逻辑来理解远程服务并与之交互。 如果这听着还是难懂,更简单的理解,OpenAPI 提供了一套标准,我们的接口文档就用这套标准书写,写完之后人类很容易读懂,机器也很容易读懂,并生成相应的代码。听起来简直是人畜无害,有百利无一害。
但实际情况,这种方式在国内的很多企业还没有采用,很多小企业停留在开发人员随意定义接口,代码开发完了,才有接口文档的阶段,好一点的公司由架构师提前把接口文档写在word文档里面,供其他人参考。像笔者所在的大厂华为公司,采用API manager来管理API, API的定义采用open api 3.0 定义在一个yaml文件中,由架构师定义接口以后,开发人员就可以直接基于Yaml文件生成对应的客户端和服务端,效率还是比较高的。
给读者提一个问题,openAPI 和 RPC框架中的IDL由什么异同?
Web比较有代表性的就这些组件,还有些其他的组件,可以去vert.x的官网了解,这里有最及时和权威的资料,笔者的很多学习材料和心得也是参考官网而来的。
Vert.x Data Access: 数据访问,Vert.x提供了一些异步客户端,用于从程序访问各种数据源。 并不想强迫你使用这些客户端,你可以根据需要直接使用来数据库厂商的客户端(例如MongoDB提供自己的牛逼的异步和反应式客户端),但为什么vertx 还提供这些客户端呢,这是因为这些客户端提供了一个更简单的异步API,并可以使用多种语言。
例如:Reactive PostgreSQL client、Reactive MySQL client、MongoDB client、Redis client、Cassandra client
这一章节按需使用的吧,需要了解详细资料的移步vertx官网了解更多。vertx提供的组件还有很多,大部分读者可能都用不到,还是一样建议大家移步官网,在此我就不做更多的介绍了,后面章节我会把精力放在Vert.x Core 和 Vertx.web这两部分,这两部分是vert.x的核心,也是广大开发者有机会用到,对各位开发者最有价值的部分。
2.VERT.X原理介绍
Vert.x是基于在JVM上构建响应式程序的工具包(Vert.x is a tool-kit for building reactive applications on the JVM)。这句话的关键词一个是JVM, 一个是响应式程序。我们先看一下什么是响应式程序。
2.1 Reactor模式
在开始介绍Reactor模式之前,先看看传统的阻塞模式,在阻塞模式下,一个用户请求(任务),我们启动一个线程来处理,一个服务器它的线程资源是有限的,不可能无限制的启动新线程,所以tomcat的并发并不好,往往Tomcat会在200个并发请求下,再无能力处理更多的请求,所以就要去单个请求的处理时间要非常短,但即便如此,也无法应用互联网模式下的高并发流量。
而Vertx完成采用另一个机制,用一个线程来接受请求(也可以是几个,注意是几个,不是几百个),而把这个真正要执行的任务委托给另外一个线程来执行,从而不会堵塞当前线程,与NodeJS的原理非常类似,如下图(下图是网上借用的一个图):
2.2 Vert.x 的
事件模型
Vert.x是事件驱动的,其处理请求的高性能也是基于其事件机制。Vert.x的事件机制中有几个非常重要的概念:Event Loop、Event Loop Vertical、Worker Vertical、Event Bus、Vert.x Module。
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项目模块,一个应用通常由多个模块组成,每个模块一般包含多个Vertical。
上面这个几个模型非常关键,我把他总结成一个单词便于大家记忆: VE-WE(谐音是喂-喂,想不想是在两人在打电话),这里面第一个E=Event Loop, V=Eventloop Verticle. 他们都运行在主线程中。W= Worker 是工作线程,第二个E= Event Bus.
下面这张图描述了这几个模块之间的关系:Event Loop本质就是线程的死循环在等待用户的连接,接受到用户的连接之后,通过EVENT BUS叫给WORKER 处理,worker 线程处理完之后,通过event bus 通知event loop的线程,返回给客户端。因此可以看出来 event loop里面的 vertical 和 worker vertical 组成了一个vert.x module.
2.3 事件模型流程
Vert.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启动时,会将Worker Vertical的事件处理函数加载到Event Bus,当一个HTTP请求发送到Vert.x构建的应用时,Event Loop首先接收到请求,并对请求做分析、包装,然后将事件交给Event Bus来处理,Event Bus为此次请求事件添加一个事件ID,然后根据注册的Worker Vertical事件寻找已经注册的监听函数,若未找到则会抛弃该事件,若找到则会对处理类进行实例化,并同时使用事件ID在Event Bus中注册一个返回结果处理事件,该事件为Event Vertical类型。下一步由Worker Vertical实例执行事件处理函数,事件处理函数中通常包含业务处理、数据库操作等。Worker Vertical实例处理结束后,将返回结果和事件信息返回给Event Bus,Event Bus找到在其中注册的Event Vertical实例,然后将返回数据交给该实例处理,Event Vertical实例进一步处理数据并将结果返回给浏览器。
2.4 数据传递
事件驱动的处理过程,数据传递是非常重要的,Vert.x支持任意对象的数据格式。但使用对象时经常会遇到序列化和载入类的问题,比如在使用Java对象的时候,这种情况下使用JSON会更方便,这也是Vert.x推荐采用的方式。
3. 总结
Vert.x 包含很多模块比如Vert.x core, Vert.x Web, Vert.x Client ,Vert.x API, Vert.x Data Access , 其中Vert.x Core是核心提供最基础的TCP, HTTP请求处理功能,Vert.x Web用于构建高并发非租塞式HTTP 服务,是取代Servlet很好的替代品。
Vert.x的事件模型,最主要的概念VE-WE, 事件模型有如下几个特点:
1.非阻塞处理请求,异步执行阻塞程序,保证了请求处理的高效性。
2.使用Event Bus事件总线来进行通讯,可以轻松编写出分布式、松耦合、高扩展性的程序。
有了本篇文章Vert.x的事件模型介绍作为基础,下一篇文章我们进入Vert core部分,了解其功能和特点,揭开其神秘的面纱。