标签: 技术架构
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
对象,你几乎是寸步难行。
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
实例
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。