Vertx简介
今天看了一篇很不错的关于Vertx的简介,转载下。
原文链接:http://www.csdn.net/article/2015-12-21/2826533?utm_source=tuicool&utm_medium=referral
Vert.x的由来
Vert.x诞生于2011年,当时叫node.x,不过后来因为某些原因改名位Vert.x。经过三年多的发展,现在已经到了3.2版本,社区也越来越活跃,在最新的官网Vertx.io上,作者用一句话介绍了它,JVM上的Reative开发套件。Vert.x目前是见过最功能最强大,第三方库依赖最少的Java框架,它只依赖Netty4以及Jacskon,另外如果你需要建立分布式的Vert.x则再依赖HazelCast这个分布式框架,注意Vert.x3必须基于Java8。由于基于JVM,所以Vert.x可以用其他语言来实现你的业务。默认官方维护的语言是Groovy,JavaScript以及
JRuby。
Vert.x是一个异步无阻塞的网络框架,其参照物是node.js。基本上node.js能干的事情,Vert.x都能干。Vert.x利用Netty4的EventLoop来做单线程的事件循环,所以跑在Vert.x上的业务不能做CPU密集型的运算,这样会导致整个线程被阻塞。
图1是一个简单的通过Vert.x起HTTP服务的例子(Java实现)。你可以从官方找到其他语言实现。
图1 Vert.x实现HTTP服务
刚才上面提到了Vert.x的分布式,Vert.x与node.js有一个很大不同点,在于Vert.x支持分布式,与多核利用。通过Hazelcast管理各个Vert.x节点的信息,然后通过EventBus在节点之间互相发消息,于此同时Vert.x还能支持应用的高可用,只需简单的在启动时加参数-ha即可。具体的可以去官网查看一下用法。下面是Vert.x提供的核心API。
HTTP/HTTPS Server/Client
Websocket SockJS
TCP/SSL Server/Client
UDP / DNS
Files / Timer
Json / Buffer / Flow Control
EventBus ( 集群 )
Distribution (Lock, Map, Counter)
Vert.x的执行单元叫verticle。即程序的入口,每个语言可能实现的方式不一样,比如Java需要继承一个AbstractVerticle抽象类,而javascript则直接require(“vertx”)就可以了。
verticle分两种,一种是基于EventLoop的适合I/O密集型的,还有一种是适合CPU密集型的worker verticle。而verticle之间相互通信只能通过Eventbus,可以支持point to point 的通信,也可以支持publish & subscribe通信方式。
我们重点说一下基于EventLoop的verticle。这个本质上是跟node.js一样的。下面的图其实就是node.js的翻版。
图2 node.js的翻版
所有业务逻辑其实都会跑在Netty里的EventLoop上,而EventLoop通过循环事件队列来执行所有的业务逻辑,这样可以把一些I/O操作频繁的事件及时从CPU上剥离开来,最后通过注册一个回调Handler来处理所有的事件回调。
另外一种worker verticle。主要是用来处理同步处理的。比如第三方框架没有异步接口,最典型就是JDBC。所以可以通过worker verticle来退化到传统的基于多线程模型的实现。这也是匹配一些原项目的手段。
图3是Vert.x的内部整体架构
图3 Vert.x的内部整体架构
大家可以看到,我们的业务逻辑其实都是基于verticle来实现的,然后Vert.x框架会将你的verticle绑定到相关的线程模型上,这里verticle1,verticle2是I/O密集型项目,所有的逻辑都会跑在NIO Worker上。而Verticle3会有一些同步的耗时的请求,则会被绑定到Worker线程模型上。另外两个Vert.x节点则通过EventBus互相通信,而EventBus通过HazelCast来获取整个集群里的节点信息。注意这里每一个verticle其实都是一个线程(启动的时候指定实例数目参数即可),这样可以充分的利用多核。而node.js其实只能通过Cluster来提升多核利用。
Vert.x的部署场景及开发痛点
图4是一个典型的Vert.x部署场景。
图4 Vert.x部署场景
我们会把逻辑拆成小的verticle。这里你可以把这些小的verticle看成是微服务,然后水平扩展这些服务,同时也可以把自己的业务按CPU密集与I/O密集型拆分。服务与服务之间可以通过EventBus互相调用,另外Vert.x的EventBus调用目标verticle的时候会按RoundRobin算法来做balance。
我们来看看Vert.x开发的痛点,这其实是所有异步开发都会遇到的痛点,就是Callback Hell。因为你所有的业务逻辑都会被拆成一个个不连贯的代码块,也就是说一个业务逻辑如果涉及到I/O操作你必须要通过回调接口来继续完成,这样就丢失了局部变量,而且异常捕获也会变得非常麻烦。
图5是一个Callback Hell的例子
图5 Callback Hell代码示例
这里代码的含义是通过EventBus给service-address1发送一个消息,然后等待返回后再把结果发送给service-address2,再等待service-address2的返回结果发送给service-address3。这里形成了调用链,即下一步的行为依赖上一步的返回结果。这个在前端用Ajax的同学肯定很熟悉。
那解决办法呢,node.js里是用promise,而Vert.x可以使用Java8自带的CompletableFuture来实现同样的效果。图6就是用CompletableFuture改写的例子
图6 Callback Hell代码示例
大家可以发现代码变得更扁平了,没有那么多的嵌套,然后通过一些介词比如,then, when等来组合各个异步的业务逻辑,最后在一个地方统一的捕获异常。
这里大量用了Java8的新功能,比如Lambda表达式,如果觉得奇怪的同学,建议先去熟悉一下Java8的Lambda表达式。
图7 CompletableFuture代码示例
那有没有更好的实现方式了呢,能不能变成同步方式呢。这里Vert.x提供了一个库vertx-sync可以实现Fiber。通过Fiber来防止线程Block,从而将异步代码完全的变成同步代码。
这里代码瞬间变得非常清晰,完全是同步的样式。vertx-sync其实是依赖了quasar这个Java库,它通过修改Java字节码来实现相关的逻辑,这里其实是在EventLoop线程里又开辟了一个线程池,所有的在EventLoop里的同步的方法会被这个线程池接管,处理完后会再返回给EventLoop线程。这样可以避免EventLoop线程被阻塞。
图8 vertx-sync代码示例
但是个人不推荐在生产环境使用这个库,因为它毕竟不是语言级别的支持Fiber。需要JVM启动的时候通过javaAgent来加载相关的quasar库。
这里还有一个库,在今天特别的火——RxJava。这个其实是Reactive的Java实现,官方也提供了相关的支持,但是Reactive比较复杂,除非的业务涉及很多的流式操作,否则不建议你使用。下面是官方的一个例子。
简单说明一下,这里定义了一个EventBus,用来接受发给heat-sensor的消息,然后每隔1秒钟对累积的消息进行一次批处理,这里通过Java8的Stream接口做了一次求平均值,最后将结果通过EventBus发给news-feed这个verticle做进一步的处理。
这里大家可以发现RxJava可以做更多的事情,前提是大家要对FRP编程思想能够接受。
Vert.x3常用工具
最后在提一下几个Vert.x3的一些小工具。
一个是metrics。这个可以用来统计整个Vert.x内部的一些指标信息,比如HTTP请求数,TCP接受或者发送的流量等等,具体可以看官方文档,通过这个接口我们可以实时的统计Vert.x内部性能信息。
另外Vert.x提供了专门针对异步代码的单元测试框架vertx-test-unit。
通过redeploy这个参数可以动态的热部署整个verticle,这个对开发调试时非常有用。
最重要的是Vert.x3内置了EventLoopChecker这个动态监测所有EventLoop线程的工具,默认EventLoop被阻塞了2秒钟的时候会触发报警,如果持续阻塞则会直接打印那一块的异常栈到日志里,非常方便开发者来检查自己的异步代码。
Vert.x目前在国内还不是很火,但是在国外已经有很多企业在使用了,比较注明的比如英孚教育、Hulu、以及做JVM监控的一家公司jClarity等。
Vertx简介的更多相关文章
- RxJava RxAndroid【简介】
资源 RxJava:https://github.com/ReactiveX/RxJava RxAndroid :https://github.com/ReactiveX/RxAndroid 官网:h ...
- ASP.NET Core 1.1 简介
ASP.NET Core 1.1 于2016年11月16日发布.这个版本包括许多伟大的新功能以及许多错误修复和一般的增强.这个版本包含了多个新的中间件组件.针对Windows的WebListener服 ...
- MVVM模式和在WPF中的实现(一)MVVM模式简介
MVVM模式解析和在WPF中的实现(一) MVVM模式简介 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 MVVM模式解析和在 ...
- Cassandra简介
在前面的一篇文章<图形数据库Neo4J简介>中,我们介绍了一种非常流行的图形数据库Neo4J的使用方法.而在本文中,我们将对另外一种类型的NoSQL数据库——Cassandra进行简单地介 ...
- REST简介
一说到REST,我想大家的第一反应就是“啊,就是那种前后台通信方式.”但是在要求详细讲述它所提出的各个约束,以及如何开始搭建REST服务时,却很少有人能够清晰地说出它到底是什么,需要遵守什么样的准则. ...
- Microservice架构模式简介
在2014年,Sam Newman,Martin Fowler在ThoughtWorks的一位同事,出版了一本新书<Building Microservices>.该书描述了如何按照Mic ...
- const,static,extern 简介
const,static,extern 简介 一.const与宏的区别: const简介:之前常用的字符串常量,一般是抽成宏,但是苹果不推荐我们抽成宏,推荐我们使用const常量. 执行时刻:宏是预编 ...
- HTTPS简介
一.简单总结 1.HTTPS概念总结 HTTPS 就是对HTTP进行了TLS或SSL加密. 应用层的HTTP协议通过传输层的TCP协议来传输,HTTPS 在 HTTP和 TCP中间加了一层TLS/SS ...
- 【Machine Learning】机器学习及其基础概念简介
机器学习及其基础概念简介 作者:白宁超 2016年12月23日21:24:51 摘要:随着机器学习和深度学习的热潮,各种图书层出不穷.然而多数是基础理论知识介绍,缺乏实现的深入理解.本系列文章是作者结 ...
随机推荐
- array01.js
//1.获取指定范围内的随机数 function getRadomNum(min,max){ return Math.floor(Math.random() * (max - min + 1)) + ...
- Java: 数据类型
核心:对事物的某种规范 前提: 1.JAVA:JAVA程序的运行是以堆栈的操作来完成的 堆栈以帧为单位保存线程的状态. JVM对堆栈只进行两种操作:以帧为单位的压栈和出栈操作. 理解 ...
- 【bzoj4864】神秘物质
Description 给出一个长度为n的序列,第i个数为ai,进行以下四种操作: merge x e:将当前第x个数和第x+1个数合并,得到一个新的数e: insert x e:在当前第x个数和第x ...
- java+spark-sql查询excel
Spark官网下载Spark Spark下载,版本随意,下载后解压放入bigdata下(目录可以更改) 下载Windows下Hadoop所需文件winutils.exe 同学们自己网上找找吧,这里就不 ...
- Vue中Mixins使用
mixins是一种分发Vue组件中可复用功能的一种灵活方式. mixins是一个JavaScript对象,可以包含组件中的任意选项,比如Vue实例中生命周期的各个钩子函数,也可以是data.compo ...
- Python爬虫之『urlopen』
本文以爬取百度首页为示例来学习,python版本为python3.6.7,完整代码会在文章末附上 本次学习所用到的python框架:urllib.request 本次学习所用到的函数: urllib. ...
- 洛谷 P2105 K皇后
P2105 K皇后 题目描述 小Z最近捡到了一个棋盘,他想在棋盘上摆放K个皇后.他想知道在他摆完这K个皇后之后,棋盘上还有多少了格子是不会被攻击到的. (Ps:一个皇后会攻击到这个皇后所在的那一行,那 ...
- 中小型WEB系统权限日志数据表设计
中小型WEB系统权限日志数据表设计 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMjc1MDU3OA==/font/5a6L5L2T/fontsi ...
- 阿里云 django的一次web维护记录
首先, 丢给我一个阿里云的server的账号/password,之前没有玩过阿里云,想想应该也是ssh服务来远程登陆. 环境: centos+nginx+uwsgi+python2.7+django. ...
- oracle 10g standby database 实时应用 redo 数据
-------physical standby database: real-time apply 须要配置 standby redo log: 启用实时应用, 日志应用服务会直接应用接收的redo ...