目前已经使用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即可;
 
注解.png
 
定义Api接口.png
  • 2、我们在程序start的时候,直接指定我们需要监听的服务端口、Api的扫描路径、Verticle的注册路径,将对应的Api绑定对应的Router进行注册登记,利用Spring bean容器,将每一个Verticle绑定对应的Service;
 
Paste_Image.png
  • 3、我们利用反射来动态向Spring中获取对应bean来注册Verticle
 
Paste_Image.png
  • 4、我们知道Vertx是基于事件驱动型的,我们也是利用这一点,直接将Api定义层(Spring Controller)同具体业务实现层(Spring Service)是解耦的;Vertx中每一个Router应该对应一个Verticle来处理具体的业务,EventBus是通过eventbus来进行寻址并处理,所以我们利用class的getName()来作为每一个唯一的EventBusAddress
 
Verticle对应地址规则.png
  • 5、启动
 
Paste_Image.png

其实说到这里,基本一个简单的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上定义;

 
UserService.png

五、构建分布式服务

要想构建一个分布式服务,有很多方式;

 
Paste_Image.png

我们通过Vertx自带的Cluster来构建了eventbus的集群,在这里要感谢刘小溪,他们很早就使用的集群的服务,提供了vertx-zookeeper来做vertx eventbus的集群,我们借鉴了他们方案采用vertx-zookeeper来做eventbus集群;
我们整理的模式如下:

 
Paste_Image.png
主要有以下几点:
  • 1、舍弃原来的Api定义层,将Vertx的Router抽象出来,做成一个总的入口,做一些基础的服务,比如:授权;也就是一个单独的API GateWay;
  • 2、将业务拆分,构建成微服务模块;Api的地址对应唯一一个Verticle地址;每一个模块只有对应的业务处理层、和数据操作层;
 
Paste_Image.png
  • 3、将每一个模块的业务利用Vertx Cluster向EventBus Cluster中注册;
 
Vertx-Zookeeper集群.png
  • 4、由Router获得每一个http请求,通过eventbus cluster直接send到对应的Verticle上进行处理;
  • 5、在这里我们需要为对应的业务处理层做一些工作;每一个http请求都将有调用execute函数,由execute函数进行反射来调用具体的函数执行;
 
抽象execute函数.png
 
定义API Router.png
 
具体的业务函数.png

到这里,其实我们也已经基本构建了一个简单的分布式服务出来了;当然比较简陋,还需要不断的完善;目前这个体系已经上线了一个项目,运营下来还算不错;

六、任重而道远,还需要不断的完善

做分布式服务,大家都知道面临的几大问题,分布式事务的处理?跨应用的业务调用?
应用与应用的调用,基本使用RPC来处理;由于Vertx是异步,那么构建一个RPC其实并不难,但是我们具体的业务处理俨然已经从异步又变成了同步;在具体的业务处理中,并不是vertx的处理,所以这就需要我们思考如何来构建一个RPC服务?
我们也尝试使用vertx来构建rpc,但是失败了;我们自己使用netty+zookeeper实现了一个简单的RPC服务;我们自己实现的RPC服务比较简单功能不是很完善,所以我们决定将dubbo整合进来,毕竟dubbo是一个比较成熟的RPC服务,并且还有其他的用处;这个也需要看大家如何来理解,如果觉得dubbo比较重,也可以直接自己实现一个,或者改造成Vertx支持的同步的RPC。据说高版本的Vertx好像已经有这方面的支持了,期待大家的分享。
以上,大致是我们对vertx在项目中的使用情况,仅限于促进交流、学习,如阐述不清晰或有误,请各位指出!

利用Vert.x构建简单的API 服务、分布式服务的更多相关文章

  1. 在ASP.NET Core MVC中构建简单 Web Api

    Getting Started 在 ASP.NET Core MVC 框架中,ASP.NET 团队为我们提供了一整套的用于构建一个 Web 中的各种部分所需的套件,那么有些时候我们只需要做一个简单的 ...

  2. 微服务—分布式服务追踪sleuth和zipkin

    随着业务的发展,系统规模也会越来越大,各微服务间的调用关系也越来越错综复杂. 通常一个客户端发起的请求在后端系统中会经过多个不同的微服务调用来协同产生最后的请求结果, 在复杂的微服务架构系统中,几乎每 ...

  3. 美团 OCTO 分布式服务治理系统

    OCTO 是美团千亿调用量的分布式服务通信框架及服务治理的系统,可实现服务注册.服务自动发现.服务管理.容错处理.数据可视化.服务监控报警.服务分组等.本文总结了 OCTO 架构原理.Java 应用的 ...

  4. 构建简单的 C++ 服务组件,第 1 部分: 服务组件体系结构 C++ API 简介

    构建简单的 C++ 服务组件,第 1 部分: 服务组件体系结构 C++ API 简介 熟悉将用于 Apache Tuscany SCA for C++ 的 API.您将通过本文了解该 API 的主要组 ...

  5. 使用Topshelf组件构建简单的Windows服务

    很多时候都在讨论是否需要了解一个组件或者一个语言的底层原理这个问题,其实我个人觉得,对于这个问题,每个人都有自己的看法,个人情况不同,选择的方式也就会不同了.我个人觉得无论学习什么,都应该尝试着去了解 ...

  6. 简单聊聊SOA和微服务

    转自:https://juejin.im/post/592f87feb123db0064e5ef7c  (2017-06) 简单聊聊SOA和微服务 架构设计中的朴素主义 前两天和一个朋友聊天,他向我咨 ...

  7. Top11 构建和测试API的工具

    立刻像专业人士一样构建API 组织正在改变他们已经在软件应用项目中成功的微服务架构模型,这就是大多数微服务项目使用API(应用程序接口)的原因. 我们要为微服务喝彩,因为它相对于其他的模型有各种先进的 ...

  8. 基于Dubbo框架构建分布式服务(一)

    Dubbo是Alibaba开源的分布式服务框架,我们可以非常容易地通过Dubbo来构建分布式服务,并根据自己实际业务应用场景来选择合适的集群容错模式,这个对于很多应用都是迫切希望的,只需要通过简单的配 ...

  9. 基于Dubbo框架构建分布式服务

    Dubbo是Alibaba开源的分布式服务框架,我们可以非常容易地通过Dubbo来构建分布式服务,并根据自己实际业务应用场景来选择合适的集群容错模式,这个对于很多应用都是迫切希望的,只需要通过简单的配 ...

随机推荐

  1. Hadoop启动datanode失败,clusterId有问题

    问题: 搭建伪Hadoop集群的时候,运行命令: hdfs namenode -format 格式化或者说初始化namenode. 然后用命令: start-dfs.sh 来启动hdfs时,jps发现 ...

  2. [转] boost:lexical_cast用法

    转载地址:http://www.habadog.com/2011/05/07/boost-lexical_cast-intro/ 一.lexical_cast的作用lexical_cast使用统一的接 ...

  3. Struts 2中访问Servlet API的几种方法小结

    1.使用ActionContext Action运行期间所用到的数据都保存在ActionContext中,例如session.客户端提交的参数等,ActionContext是Action的一个上下文对 ...

  4. android开发学习 ------- 【转】 android事件分发机制 和 自定义view涉及的事件分发

    参考  https://blog.csdn.net/carson_ho/article/details/54136311   ,写的很完美,原理入门的一篇博客,看这一篇就够了 https://www. ...

  5. c# 实现窗体移动

    一般情况下: .添加下列代码到你的窗体中: #region 轻松移动 bool isInMove; Point oldPoint; void InitializeEasyMove() { isInMo ...

  6. 关于如何用jq定位到某个元素的索引

    在点击事件触发时候,通常如果有同样的className的列表我们都需获取它的索引来知道到底点击的是那一个 $('.info_content').mousemove(function(){ var ro ...

  7. 安卓ListView基础应用

    listview简单描述 主页面: package com.example.listview; import com.lidroid.xutils.ViewUtils; import com.lidr ...

  8. PyCharm如何配置断点调试功能

    1. 点击菜单 PyCharm -> Preferences.. 2. 在左侧菜单栏找到Project:Django - > Project Interpreter 并点击配置 Proje ...

  9. python_111_动态导入模块

    lib下aa.py文件内容: class C: def __init__(self): self.name='alex' from lib import aa#正常导入 print(aa.C) 动态导 ...

  10. CPP-基础:C++中为什么需要一个头文件,一个cpp文件

    把文件分成头文件和源文件完全是为了方便扩展和组织程序 这么说吧 我们可能会自定义很多函数 而这些函数分别会在不同的地方被调用 甚至有些时候我们需要把一堆函数打包起来一起调用 比如#include &q ...