# vert.x学习笔记

时间:2022-10-04 18:06:26

标签: 技术架构


1. 自定义启动文件server.groovy分析(用到的vertx方法)

  • use GroovyShell to execute scripts to extend chain handler new GroovyShell(binding, compileConf)
  • 设置定时任务 vertx.setPeriodic(interval)
  • 启动httpserver vertx.createHttpServer()
  • 添加websocket支持. vertx.createSockJSServer
  • 启动tcpserver vertx.createNetServer()

2 vert.x 学习

vertx 特性
Vert.x基于全异步Java服务器Netty,并扩展出了很多有用的特性。Vert.x的亮点有:

  • 支持多种编程语言
  • 异步无锁编程
  • 对各种IO的丰富支持——目前Vert.x的异步模型已支持TCP、UDP、FileSystem、DNS、EventBus、Sockjs等;
  • 支持分布式开发(event bus总线实现)
  • 生态体系成熟(Eclipse 基金会管理维护.异步驱动已经支持了Postgres、MySQL、MongoDB、Redis等常用组件)
  • Reactor模式(耗时操作交换异步线程去做,执行完异步回调)

# vert.x学习笔记

vertx原理解释

在Vert.x里,如果你不使用Vertx对象,你几乎是寸步难行。

Vertx对象扮演着Vert.x控制中心的角色,同时它也提供了大量的功能,例如:

创建客户端和服务器
获得event bus引用
设置定时器

如果你将Vert.x嵌入到你的应用程序中,你可以向下面这样获得一个Vertx对象的引用

Vertx vertx = Vertx.vertx();

If you’re using Verticles
注意: 在绝大多数应用程序中,你只需要一个Vert.x实例,但是如果你想要创建多个Vert.x实例,这也是可以的,例如你想要将event bus或者服务器与客户端进行隔离

Vert.x APIs大多数是基于事件驱动的。这意味着,在Vert.x中,当你关注的事件发生时,Vert.x会自动通知你。
例如当下面这些事件发生时,Vert.x就会自动通知你

  • 定时器被触发
  • socket中接收到数据
  • 从磁盘中读取数据已经就绪
  • 异常发生
  • HTTP服务器接受到一个请求

我们需要通过向Vert.x APIs提供handler来处理Vert.x通知给我们的事件,例如下例中演示了我们每秒从定时器中接受一个事件
Vert.x API不会阻塞任何线程,因此你可以使用少量的线程来处理非常大的并发量

  • 我们在前文中提到过Vert.x是基于事件驱动的,当Vert.x事件准备好之后,就会向事件传递给被设置的handler上
  • 在大多数情况下,Vert.x会使用一个称为event loop的线程来调用你的handler

鉴于Vert.x以及你的应用程序不会产生任何阻塞操作,event loop会快速地将事件分发到不同的handler上
因为我们的任何操作都不会带来任何阻塞,因此一个event loop就可以在非常短的时间内,分发出去居多的事件。例如一个event loop就可以非常快速地处理数千个HTTP请求。

我们把这种模式称为Reactor Pattern.

你也许以前就听说过这种模式,例如Node.js就是这种模式的一种实现

在一个标准reactor实现中,会有一个单独的event loop线程进行可用事件轮询,只要有事件接听到,就将它发送到全部的handler上

但是这种实现有个小缺点,在任一时刻,它都会只运行在一个核心上,因此如果你想要你的单线程reactor应用程序在多核心服务器上进行拓展,那么你就需要启动并管理多个不同的reactor应用程序进程

但是Vert.x的工作模式与之不同。相比单线程event loop,每个Vertx实例都包含数个event loop. 在默认情况下,我们会根据所在机器的可用核心数来设置event loop数量,当然你也可以自己指定这个数量

我们把这种模式称为Multi-Reactor Pattern

注意:尽管Vertx实例会持有多个event loop,但是每一个handler都不会被并发执行, 而且在大多数情况下(工作者verticle除外),handler会被同一个event loop执行
  • event loop调用阻塞操作,event loop会一直等待,办法就是通过调用executeBlocking方法来执行阻塞代码
  • Vert.x引入了一个简单的可扩展的类actor的部署和并发模型.Verticle之于vertx相当于Actor模型中的actor
  • Vert.x中进行数据传播的大多是org.vertx.java.core.buffer.Buffer实例

用友iUAP马太航:Vert.x事件模型机制分析

  • Vert.x是事件驱动的,其处理请求的高性能也是基于其事件机制。Vert.x的事件机制中有几个非常重要的概念:Event Loop、Event Loop Vertical、Worker Vertical、Event Bus、Vert.x Module。

  • Event Loops:即事件循环,是由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。

  • Vert.x以非阻塞IO的思想来实现高性能,非阻塞IO的实现,基于Event Loop Vertical和Worker Vertical的分离。在Vert.x中,Event Loop用于接收请求,并将短业务操作交由其内部的Vertical来处理,该模块是非阻塞的,这样可以保证请求的处理效率;阻塞任务通过Vert.x的事件机制脱离当前线程,生成一个任务事件交由Event Bus进行管理,Event Bus中注册了所有的监听事件,通过事件匹配选择合适的Worker Vertical,并将任务交由Worker Vertical进行处理,Worker Vertical处理完成后,将数据和事件信息进行封装,返回给Event Bus,Event Bus再次匹配事件定位到来源Vertical,然后将数据返回给Vertical,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事件寻找已经注册的Worker Vertical监听函数,若未找到则会抛弃该事件,若找到则会对处理类进行实例化(此处使用线程池来管理),并同时使用事件ID在Event Bus中注册一个返回结果处理事件,该事件对应来源Event Loop Vertical。下一步由Worker Vertical实例执行事件处理函数,事件处理函数中通常包含业务处理、数据库操作等。Worker Vertical实例处理结束后,将返回结果和事件信息返回给Event Bus,Event Bus找到在其中注册的来源Event Loop Vertical实例,然后将返回数据交给该实例处理,Event Vertical实例进一步处理数据并将结果返回给浏览器。

事件驱动的处理过程,数据传递是非常重要的,Vert.x支持任意对象的数据格式。但使用对象时经常会遇到序列化和载入类的问题,比如在使用Java对象的时候,这种情况下使用JSON会更方便,这也是Vert.x推荐采用的方式。

Vert.x的事件模型,有如下几个特点:

  • 1.非阻塞处理请求,异步执行阻塞程序,保证了请求处理的高效性。
  • 2.使用Event Bus事件总线来进行通讯,可以轻松编写出分布式、松耦合、高扩展性的程序。
  • 3.使用Event Bus事件总线是Vert.x真正实现多语言支持的基础,目前Vert.x已支持Java、Javascript、Ruby、python、Groovy、Clojure、Ceylon。