目前已经使用Vertx已经一年多了,虽然没有太多的造诣,但也已在项目中推广了下;从最初的vertx搭建web服务,到项目上线运营,还算比较稳定。再到后来尝试搭建基于vertx的分布式服务,一路下来也积累了些经验,在这里也从几个方面来聊一聊。
一、初识Vertx
我们当时需要改造一个项目,在技术选型上有不同的意见;朋友推荐让我们尝试使用vertx来构建我们的服务;
主要出于以下几点:
1、 我们趋向于前后端分离,服务端主要提供API服务,前端采用Node.js+vue来构建;而Vertx体现了他的优势;
2、我们想摒弃一些重的组件,比如不用web容器,当时也倾向于springboot;我们希望服务轻量,容易上手,灵活性高;
站在技术创新的角度,我们看到vertx有很多优点,所以最后我们选择了Vertx来改造我们的项目,尝试使用。`
二、初次体验Vertx
刚开始体验,明显感觉方便简单,仅仅依赖vertx-core、vertx-web两个jar包;在体验上也有了新的感觉,当然了,他必须运行在jdk8以上的版本;因为vertx采用了jdk高版本的一些语法支持,比如lambda语法等;Vertx是异步事件驱动型,所以执行效率要高,并且是解耦模式;
我们在试用的过程中,尝到了甜头,所以准备试点有一个项目;
三、使用Vertx改造项目
在开始时,我们了解关于vertx 的一些使用,然后将项目业务处理改成异步的,但是我们在开始就遇到了一个问题,抵触;由于一些写法和传统的写法不同,加之我们要将原有的项目业务逻辑改成vertx所支持的异步遇到困难,甚至有些还不知道怎么去实现;
我们开始整理了一个简单的逻辑:
大家都知道vertx的性能不在话下,其实大部分的框架性能都不错,当我们嵌套业务后,才会面临一些性能、并发的问题,处理不及时、查询数据慢等等,这些其实在某些时候是与框架没有太大联系,比如说当我们使用了数据库,使用了文件的频繁读写,那么IO将是我们面临的最大问题;
我们希望团队还是能按照原来的模式协作,所以我们开始考虑将Vertx与Spring结合;
我们使用Vertx来做我们web服务,使用原有的Spring+Mybatis来做我们的业务;当然,有好处,也有坏处;好处就是能够平滑过渡到和以前差不多,更多的还是专注于业务实现;坏处就是有点违背了Vertx初衷,我们在业务具体的处理过程中依旧是同步的;在这里我只说我们的实现方式,其他的就留给大家各自来评论。
Vertx有很多比较好的技术,比如我们用的最多的Router、EventBus、WebSocket等等,在这里要说下Router,因为Router将是我们入口,
Router的功能非常大,支持正则匹配、占位符、二级路由等;在这里我就不多加赘述,可以阅读参考 http://vertx.io/docs/vertx-web/java/#_reroute
构建的大致步骤如下:
- 1、我们使用Vertx来构建我们的API Server,定义API接口并直接由EventBus来调用具体的业务调用;说白了,我们只需要将原有的Controller转变成Vertx的Router即可;
- 2、我们在程序start的时候,直接指定我们需要监听的服务端口、Api的扫描路径、Verticle的注册路径,将对应的Api绑定对应的Router进行注册登记,利用Spring bean容器,将每一个Verticle绑定对应的Service;
- 3、我们利用反射来动态向Spring中获取对应bean来注册Verticle
- 4、我们知道Vertx是基于事件驱动型的,我们也是利用这一点,直接将Api定义层(Spring Controller)同具体业务实现层(Spring Service)是解耦的;Vertx中每一个Router应该对应一个Verticle来处理具体的业务,EventBus是通过eventbus来进行寻址并处理,所以我们利用class的getName()来作为每一个唯一的EventBusAddress
- 5、启动
其实说到这里,基本一个简单的Vertx-Web服务就已经搭建完成了。我们没有完全的用vertx来构建,出于几个方便的考虑;
A、项目改造工程大;
B、业务需求不确定性大,且有些场景不太适合异步;
C、如果全部按照个人思路来写代码,维护性工作比较大,不太贴近流程化管理;
所以我们利用Vertx部分特性及有点,整合Spring、Mybais来衔接项目;具体的可以参考 https://gitee.com/NeilPrivate/vertx-framework
四、项目中的优化
我们在后来的项目中,我们舍弃了Api这层;为何呢?因为Api只是定义层,没有具体的实现,显得是多余的;我们之前有过一个项目,是SpringMVC+Spring+Mybatis,我们就把Controller舍掉了,直接抽象一个Controller,然后利用反射,在分摊到不同的Service上,特定的Controller就成Api转发层,一些通常的监控、控制、鉴权都直接在一个入口把控了;我们在后来也是借鉴如此,我们将Api直接下放,直接在Service上定义;
五、构建分布式服务
要想构建一个分布式服务,有很多方式;
我们通过Vertx自带的Cluster来构建了eventbus的集群,在这里要感谢刘小溪,他们很早就使用的集群的服务,提供了vertx-zookeeper来做vertx eventbus的集群,我们借鉴了他们方案采用vertx-zookeeper来做eventbus集群;
我们整理的模式如下:
主要有以下几点:
- 1、舍弃原来的Api定义层,将Vertx的Router抽象出来,做成一个总的入口,做一些基础的服务,比如:授权;也就是一个单独的API GateWay;
- 2、将业务拆分,构建成微服务模块;Api的地址对应唯一一个Verticle地址;每一个模块只有对应的业务处理层、和数据操作层;
- 3、将每一个模块的业务利用Vertx Cluster向EventBus Cluster中注册;
- 4、由Router获得每一个http请求,通过eventbus cluster直接send到对应的Verticle上进行处理;
- 5、在这里我们需要为对应的业务处理层做一些工作;每一个http请求都将有调用execute函数,由execute函数进行反射来调用具体的函数执行;
到这里,其实我们也已经基本构建了一个简单的分布式服务出来了;当然比较简陋,还需要不断的完善;目前这个体系已经上线了一个项目,运营下来还算不错;
六、任重而道远,还需要不断的完善
做分布式服务,大家都知道面临的几大问题,分布式事务的处理?跨应用的业务调用?
应用与应用的调用,基本使用RPC来处理;由于Vertx是异步,那么构建一个RPC其实并不难,但是我们具体的业务处理俨然已经从异步又变成了同步;在具体的业务处理中,并不是vertx的处理,所以这就需要我们思考如何来构建一个RPC服务?
我们也尝试使用vertx来构建rpc,但是失败了;我们自己使用netty+zookeeper实现了一个简单的RPC服务;我们自己实现的RPC服务比较简单功能不是很完善,所以我们决定将dubbo整合进来,毕竟dubbo是一个比较成熟的RPC服务,并且还有其他的用处;这个也需要看大家如何来理解,如果觉得dubbo比较重,也可以直接自己实现一个,或者改造成Vertx支持的同步的RPC。据说高版本的Vertx好像已经有这方面的支持了,期待大家的分享。
以上,大致是我们对vertx在项目中的使用情况,仅限于促进交流、学习,如阐述不清晰或有误,请各位指出!