Vert.x 简介
Vert.x是一个工具集,用来在JVM上构建反应式应用。反应式的应用能够随着负载的增加而伸缩,也能够在故障中保持灵活。
传统的实现方式面临的问题
传统的实现高并发的方式是很多的线程。一个进程中很多的线程,共同分享进程里内存空间。早期,当并发量不大时,我们可以使用一个连接一个线程的模式。但是当并发量增长时,大量的线程将会使我们的操作系统内核疲于应对上下文的切换。
虽然现代操作系统的有出色的线程调度机制,但是处理5万个线程也不可能像处理5000个线程一样简单。同时,常见一个线程需要几ms,消耗掉1MB的内存。
Vert.x的特点
- Vert.x是基于事件的
提供一个事件驱动的编程模型,开发人员只需关注事件处理器的编写。同时需要在程序中时刻注意不要阻塞事件线程。 - 参照物是node.js
- 支持异步无锁编程
Don’t call us, we’ll call you.因此可以做到只需几个线程就可以处理大量的并发。
Vert.x的缺点
- 必须使用JDK8以上,熟悉Lambda语法。
- 对于复杂的业务可能会出现callback hell。
- 思维方式转变,契约创建,异常处理,开发过程相对要复杂。
Vert.x技术体系
- 核心模块
vertx-core为核心模块,提供HTTP,TCP,文件系统访问,EventBus,WebSocket,延时与重复执行,缓存等基础功能。 - Web模块
编写Web服务处理对HTTP支持外,还需要路由、Session、请求数据读取、RESTful支持等,vertx-web提供API支持。 - 数据访问模块
对于常见的数据库都有官方or社区版本支持,也很完善,https://github.com/vert-x3/vertx-awesome 可查询丰富的信息。 - Reactive响应式编程
支持reactive编程,简化异步编程的难度。 - 中间件支持
支持常见的中间件,RabbitMQ Client、Kafka Client 等 - 支持微服务
比如服务发现(Vert.x Service Discovery)、断路器(Vert.x Circuit Breaker)、配置中心(Vert.x Config)等。
Vert.x的重要概念
- Verticle
是vert.x部署与运行的代码块,verticle之间通过EventBus实现通信。verticle有点类似于Actor Model。通常情况下会在同一个vert.x实例中部署很多个verticle。有两种类型的verticle: - 1.Standard verticle
会被eventloop中的线程执行,而且vert.x保证每次都是同一个线程执行。 - 2.Worker verticle
会被workpool中的线程执行,而且vert.x保证每次只有一个线程在执行。 - EventBus
集群中各个容器之间的通信,各个verticle之间的通信都是经过EventBus实现的。 - SharedData
用来在多个verticle之间做数据的共享。
Get started
作为对比,我们看看ajax的代码
console.log("1");
$.ajax({
"url" : "/hello",
"type" : "post",
"dataType" : "json",
"success" : function(val) {
console.log("2");
}
});
console.log("3");
再来看看vert.x的代码
public class MainVerticle extends AbstractVerticle {
@Override
public void start() throws Exception {
// Create a Router
Router router = Router.router(vertx);
// Mount the handler for all incoming requests at every path and HTTP method
router.route().handler(context -> {
// Get the address of the request
String address = context.request().connection().remoteAddress().toString();
// Get the query parameter "name"
MultiMap queryParams = context.queryParams();
String name = queryParams.contains("name") ? queryParams.get("name") : "unknown";
// Write a json response
context.json(
new JsonObject()
.put("name", name)
.put("address", address)
.put("message", "Hello " + name + " connected from " + address)
);
});
// Create the HTTP server
vertx.createHttpServer()
// Handle every request using the router
.requestHandler(router)
// Start listening
.listen(8888)
// Print the port
.onSuccess(server ->
System.out.println(
"HTTP server started on port " + server.actualPort()
)
);
}
}