Vert.x的核心是一组被称为“Vert.x Core”的Java API。
仓库
Vert.x提供了以下功能:
- 编写TCP客户端和服务器
- 编写支持WebSockets的客户端和服务器
- 事件总线
- 共享数据-局部map和集群中的分布式map
- 定时和延迟的任务
- 部署和卸载Verticle
- 数据报套接字
- DNS客户端
- 文件系统的访问
- 高可用
- 本地传输
- 集群
核心中的功能都很底层,类似数据库访问,权限控制或者高级web功能在Vert.x ext(扩展)中提供。
Vert.x核心包很小很轻量,可以只使用所需要的部分,就完全集成到现有的项目中——并不强制要求应用满足指定的结构才能使用Vert.x
可以在任何Vert.x核心支持的语言立使用它。它自动为每种语言生成和Java API惯用的等价物。
后文中。core都指的是Vert.x core。
如果是使用Maven或者Gradle的项目,添加以下依赖即可使用Vert.x Core API:
- Maven(在
pom.xml
中添加):
io.vertx
vertx-core
${vert.x.version}
- Gradle(在
build.gradle
文件中添加)
dependencies {
compile 'io.vertx:vertx-core:3.5.3'
}
1. Vertx对象
Vert.x的使用离不开Vertx对象,按如下方式创建一个Vertx实例:
Vertx vertx = Vertx.vertx();
注意:大多数应用只需要一个Vert.x实例,但是如果需要可以创建多个Vertx.x实例,例如需要隔离多个事件总线或者对不同的服务器和客户端分组。
1.1 Vertx对象配置
创建Vertx时能够进行一些配置,例如:
Vertx vertx = Vertx.vertx(new VertxOptions().setWorkerPoolSize(40));
VertxOptions
对象有诸多选项以供配置,例如集群(clustering),高可用(high availability),池大小(pool sizes)等等。详见Javadoc。
1.2 创建Vert.x集群
创建Vert.x集群(参阅事件总线一章关于集群的内容)通常需要使用异步变量来创建Vertx对象。
为了把集群中的不同Vert.x实例组织在一起需要一些时间(可能有几秒钟)。为了不阻塞调用线程(the calling Thread),结果会以异步方式返回。
2. 流式API
Vert.x支持流式API。
流式API指的是对多个方法的调用能被链式地写在一起,例如:
request.response().putHeader("Content-Type", "text/plain").write("some text").end();
这在Vert.x中很常见,但是不是强制使用,也可以这么写:
HttpServerResponse response = request.response();
response.putHeader("Content-Type", "text/plain");
response.write("some text");
response.end();
3. 事件驱动
Vert.x 的API大部分是事件驱动(event driven)的。也就是说关注的事情发生后,Vert.x会发送事件(event)。
例如如下事件:
- 定时器被触发
- socket收到数据
- 磁盘数据读取完毕
- 触发异常
- HTTP服务器收到请求
通过向Vert.x API提供提供handlers来处理这些事件,例如需要每秒钟收到一个定时器事件:
vertx.setPeriodic(1000, id -> {
// This handler will get called every second
System.out.println("timer fired!");
});
收到HTTP请求:
server.requestHandler(request -> {
// This handler will be called every time an HTTP request is received at the server
request.response().end("hello world!");
});
事件触发后,Vert.x会异步调用handler。
4. 非阻塞
除了极少数例外(例如以'Sync'结尾的文件系统操作),所有Vert.x中的API都不会阻塞调用线程。
如果一个结果能被立即获得,它就会被立即返回,否则需要提供一个处理器(handler)来在稍后接受事件。
Vert.x API没有线程阻塞意味着少量线程就能处理大量并发。
传统的阻塞API线程阻塞通常发生在:
- 从socket中读取数据
- 向硬盘中写入数据
- 向接受者发送数据,然后等待回应
- 其他情况
以上案例中,线程在等待结果的时候不能处理任何其他任务。
这样如果需要用阻塞API处理大量并发就需要很多线程来防止应用卡住。