一、背景

在传统J2EE开发中,用户对生产系统的部署都需依赖昂贵的服务器中间件(如WebLogic、WebSphere,当然也有免费的tomcat等),这些服务器上面部署了大型的程序包,它们运行缓慢,消耗大量的内存,运维人员也需要对服务器有足够了解。随着异步非阻塞、微服务等概念的出现,近年来也涌现了很多不依赖传统容器的服务框架。2009年,Node.js项目启动,它支持异步非阻塞的、基于事件驱动的I/O。如果服务器的线程使用得当,Node.js可以极大地提升响应速度,单个服务器的吞吐量可以媲美一个Java EE服务器集群。同时基于JAVA NIO、AIO(jdk1.7后)原理,也涌现出了一批如Netty、mina等优秀网络框架。其中vert.x、undertow等就是基于这些优秀框架(undertow基于XNIO)诞生的异步无阻塞的网络框架,

二、vert.x 简介

vert.x,是一个JVM下、轻量级、高性能的应用平台,非常适用于最新的移动端后台、互联网、企业应用,基于Netty实现的异步无阻塞的网络框架,诞生于2011年,当时叫node.x,不过后来因为某些原因改名位Vert.x。经过5年多的发展,现在已经到了3.3.3版本。

Vert.x是一个异步无阻塞的网络框架,其参照物是node.js。基本上node.js能干的事情,Vert.x都能干。而且Vert.x还支持分布式,与多核利用。通过Hazelcast管理各个Vert.x节点的信息,然后通过EventBus在节点之间互相发消息,于此同时Vert.x还能支持应用的高可用。

vert.x体系架构

vert-frame

我们的业务逻辑其实都是基于verticle来实现的,然后Vert.x框架会将你的verticle绑定到相关的线程模型上,这里verticle1,verticle2是I/O密集型项目,所有的逻辑都会跑在NIO Worker上。而Verticle3会有一些同步的耗时的请求,则会被绑定到Worker线程模型上。另外两个Vert.x节点则通过EventBus互相通信,而EventBus通过HazelCast来获取整个集群里的节点信息。注意这里每一个verticle其实都是一个线程(启动的时候指定实例数目参数即可),这样可以充分的利用多核。而node.js其实只能通过Cluster来提升多核利用

一个典型的Vert.x部署场景: vert-deploy

图中业务逻辑被拆成很多小的verticle。这里你可以把这些小的verticle看成是微服务,然后水平扩展这些服务,同时也可以把自己的业务按CPU密集与I/O密集型拆分。服务与服务之间可以通过EventBus互相调用,另外Vert.x的EventBus调用目标verticle的时候会按RoundRobin算法来做balance

三、vert.x中基本概念

vert-module

Verticle

Vert.x的代码执行包,它可以用JS、Ruby等多语言来编写,在同一个Vert.x实例中可以同时执行多个Verticle,一个应用可能由多个Verticle组成,他们被部署到不同的网络节点上,彼此之间通过在Vert.x的事件总线(event bus)上交换信息来通信。对于具体的verticle可以直接从命令行启动,但是通常会将它打包成modules

Module

Vert.x应用由一个或多个modules来实现.一个模块由多个verticles来实现.你可以把module想象出一个个Java package.里面可能是特定业务的实现,或者公共的服务实现(那些可以重用的服务).Vert.x编写好的module,可以发布到maven的仓库里.以zip包装成二进制格式.或者发布到vert.x module 注册中心.实际上这种以模块方式的开发,支撑着整个Vert.x生态系统

Vert.x 实例

Verticles 其实是跑在 Vert.x实例上的.所谓Vert.x实例其实就是一个运行在某一个JVM上的Vert.x对象实例.可以将多个Verticles运行在一个Vert.x实例上,而vert.x实例可以跑在单个JVM上,也可以跑在其他JVM上,通过分布式event bus来维持通信.注意vert.x实例其实是由vertx命令行启动的.你可以指定实例数目在单个JVM上

Event Loop Vertical

事件的业务处理线程,存在于Event Loop中,用于处理非阻塞短任务

Event Bus

它是Vert.X的核心,在集群中容器之间的通信,各个Verticle之间的通讯都是经过Event Bus来实现的

Shared Data(共享数据)

它是Vert.X提供的一个简单共享Map和Set,用来解决各个Verticle之间的数据共享。

Worker Vertical (阻塞处理)

事件的业务处理线程,用于处理长任务阻塞任务。 事件处理之外肯定会发生其长时间数据处理请求.比如处理一个图片上传,然后转存到磁盘上等.或者一次长时间的排序计算等.

在Verticle类型里,有一种特别的verticle叫做Worker.不同于标准的verticle,他不使用event loop.而是采用vert.x内部的另一个线程池叫做worker pool.其区别在于,worker verticles不会并行的执行Handler.而是阻塞式的,等待上一个Handler处理完了,才会再执行后面的请求.你可以想象出队列的方式执行某些请求.所以为了支持标准的与阻塞式的worker verticles, Vert.x提供了一种混合线程模型,你可以选择适当的模型用于你的应用.

四、vert.x特性

多语言支持

能在JVM上运行的常见语言,都可以直接编写基于Vert.X的应用,目前官方支持的有 Java, JavaScript, CoffeeScript, Ruby, Python or Groovy

多服务器客户端支持

支持编写TCP、UDP客户端和服务器,HTTP客户端和服务器和Websocket支持,Vert.x-Web模块能够实现基于http的微服务框架

支持多异步客户端

Vert.x提供了不同的异步客户端,用于从应用程序访问各种数据存储。 当然Vert.x也没有限制你必须用vert.x的客户端,你也可以到下载各软件自己的客户端(如mongoDB自己的),不过vert.x的异步API,提供多了多种语言支持Java、JavaScript、Groovy、Ruby等多语言的支持。从目前官网列出的异步API有:MongoDB client、JDBC client、SQL common、Redis client、MySQL / PostgreSQL client 等。

除了数据访问层API支持,Vert.x还实现了Mail Client、STOMP Client & Server、TCP 客户端A等PI,同时vert.x也对Eventbus、apache Camel、RabbitMQ等桥接集成了实现,的并支持Java、JavaScript、Groovy、Ruby等多语言。

认证和授权

Vert.x目前已经支持Auth common、JDBC auth、JWT auth、Shiro auth、MongoDB auth、OAuth 2等多种认证和授权API,并支持Java、JavaScript、Groovy、Ruby等多语言。

微服务支持

在Vert.x3.3.0中,vert.x提供了两个微服务相关特性:服务发现和断路器。其中服务发现是在服务运行时发现,服务位置不要硬编码,可以使用Consul、Kubernetes、redis Docker links等扩展服务发现的支持;另外断路器

集群支持

vert.x Verticle支持集群部署、支持Verticle的高可用和故障备份。在一个Verticle突然崩溃时,Verticle会被迁移到另外的vert.x实例上。

五、vert.x的使用

vert.x社区目前已经很活跃,在国内vert.x的用还很少见到,但是在国外已经有很多大公司将vert.x运用到自己的项目中了,以下为vert.x官网列出的部分公司: vert-company