Vert.x简介
1. Vert.x 介绍
Vert.x是Eclipse软件基金会顶级JAVA开源项目之一,它基于netty的、运行在jvm之上的、支持多种编程语言的高性能异步、非阻塞、响应式开发工具包。
Vert.x is a tool-kit and not a framework that ships with black magic: what you write is actually what you get to execute, as simple as that.
So what makes Vert.x a great option for writing your next cloud-native or twelve-factor app?
Vert.x设计
- 响应式的(Responsive):一个响应式系统需要在合理的时间内处理请求。
- 弹性的(Resilient):一个响应式系统必须在遇到异常(崩溃,超时,
500
错误等等)的时候保持响应的能力,所以它必须要为异常处理 而设计。 - 可伸缩的(Elastic):一个响应式系统必须在不同的负载情况下都要保持响应能力,所以它必须能伸能缩,并且可以利用最少的资源来处理负载。
- 消息驱动(Message driven):一个响应式系统的各个组件之间通过 异步消息传递 来进行交互。
- 支持多种语言:只要能运行在JVM上的语言,基本都支持(Java、JavaScript、Ruby、Python、Groovy、Clojure、Ceylon等)。
- 简单的并发模型:就像写单线程代码一样简单,多线程并发由Vert.x控制。
- 支持Event Bus:在同一个Vert.x集群,各个Verticle 实例间可以通过event bus通信。同时也支持跨进程的TCP Event Bus (tcp-eventbus-bridge)
- Vert.x与Netty的关系:Vert.x使用Netty处理所有的IO。
- 是借鉴Erlang和Akka架构设计,能充分利用多核处理器性能并实现高并发编程需求的框架。
2. Vert.x与spring boot区别
Spring Boot 不香了?
- Vert.x 是轻量级的
- Vert.x 高并发
但同时Vertx也有它的缺点,就拿Vert.x Web相比Spring MVC来说,Vertx更加灵活,但同时也需要开发人员web原生开发有更深刻的了解,包括各种请求返回头的添加以及各种拦截器、自定义消息转换等的处理,都需要开发人员自行配置。这显然是大部分开发人员所不愿意的,所以导致了Vert.x目前并不怎么流行,但这些并不影响Vert.x本身的优秀。
Spring boot 已经很熟悉了,开箱即用,企业级应用开发框架。
3. Vert.x快速开始
- JDK 1.8 or higher
- A text editor or IDE
- Maven 3 or higher
- curl or HTTPie or a browser to perform HTTP requests
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()
)
);
}
}
打包mvn package
,运行
$ mvn exec:java
HTTP server started on port 8888
apr 03, 2020 11:49:21 AM io.vertx.core.impl.launcher.commands.VertxIsolatedDeployer
INFO: Succeeded in deploying verticle
4.一些术语
- Verticle
Vertx部署和运行的代码。Verticles可以使用多种语言实现。
- Vert.x Instance
Vert.x instance运行在JVM里,Verticle运行在Vert.x instance里。多个Verticles在一个Vert.x instance里异步执行。多个Vert.x instances可以通过Event Bus组成集群。
-
Concurrency
- Standard Verticle:始终在同一个Event Loop线程上执行,同一个Verticle 中的逻辑可以避免资源竞争和死锁。
- Worker Verticle:在worker threads上执行,Vertx保证最多同时只有一个worker thread在执行逻辑,避免竞争和死锁。但是在不同的时刻,可能由不同的线程在执行。
- Multi-threaded worker verticle:和Worker Verticle类似,但是不保证线程安全,在同一时刻,可能由多个线程在执行。
-
Event-based Programming Model
使用“事件驱动”的模式去编写代码,采用异步回调handler的方式去处理事件,不能被阻塞!
- Event Loops
Vert.x的核心线程池,默认每个Verticle运行在自己的Event Loop线程上,不能被阻塞!
- Message Passing
不同的Verticle可以通过Event Bus通信,集群模式下不同主机上的Verticle也可以通过Event Bus通信,来实现distributed applications。
- Shared data
不同的Verticle之间可以通过 Shared Data 共享数据
- hazelcast
Vert.x 使用 Hazelcast 作为一个In-Memory Data Grid (IMDG). Hazelcast 是一个内嵌的组件。
如果使用集群模式,Vert.x 默认使用Hazelcast来管理在各个不同Host上的Instance通信。Hazelcast 也是一种分布式的存储,Hazelcast 是Vert.x Event Bus 在集群模式下的实现基础,也是Vertx分布式共享内存的Shared Map的基础。
分布式应用程序可以使用Hazelcast进行分布式缓存、同步、集群、处理、发布/订阅消息等。Hazelcast基于Java实现,并提供C/C++,.NET,REST,Python、Go和Node.js客户端。Hazelcast遵守内存缓存协议,可以内嵌到Hibernate框架,并且可以和任何现有的数据库系统一起使用。hazelcast相关资料博客
Vert.x 还可以使用zookeeper等其他分布式组件
5.Vert.x工作模型
Verticle 是执行单元,在同一个Vertx实例中可以同时执行多个Verticle。Verticle在event-loop线程上执行,多个Vert.x instances可以在多个host上执行,各个Verticles 通过event bus通信。
6.Event Bus
是Vert.x的神经系统
每个 Vert.x 实例都有一个事件总线实例,vertx.eventBus()
即可获取事件总线
事件总线允许应用程序的不同部分相互通信,无论它们使用哪种语言编写,也不管它们是在同一个 Vert.x 实例中,还是在不同的 Vert.x 实例中。
它甚至可以桥接,以允许在浏览器中运行的客户端JavaScript在同一事件总线上进行通信。
事件总线形成一个跨多个服务器节点和多个浏览器的分布式对等消息传递系统。
事件总线支持发布/订阅、点对点和请求-响应消息传递。
事件总线 API 非常简单。它基本上涉及注册处理程序,注销处理程序以及发送和发布消息。
事件总线不仅仅存在于单个 Vert.x 实例中。通过将网络上的不同 Vert.x 实例聚类在一起,它们可以形成单个分布式事件总线。
示例:
- 在事件总线中注册一个处理(consumer)
EventBus eb = vertx.eventBus();
eb.consumer("news.uk.sport", message -> {
System.out.println("I have received a message: " + message.body());
});
- 发布消息(publish)
eventBus.publish("news.uk.sport", "Yay! Someone kicked a ball");
- 发送消息(send)
eventBus.send("news.uk.sport", "Yay! Someone kicked a ball");
这是点对点消息传递模式
消息的顺序性
Vert.x将以与从任何特定发件人发送消息相同的顺序将消息传递到任何特定的处理程序
消息对象
Message
- 设置消息头
DeliveryOptions options = new DeliveryOptions();
options.addHeader("some-header", "some-value");
eventBus.send("news.uk.sport", "Yay! Someone kicked a ball", options);
- 确认消息/发送回复
接收方
MessageConsumer<String> consumer = eventBus.consumer("news.uk.sport");
consumer.handler(message -> {
System.out.println("I have received a message: " + message.body());
message.reply("how interesting!");
});
发送方
eventBus.request("news.uk.sport", "Yay! Someone kicked a ball across a patch of grass", ar -> {
if (ar.succeeded()) {
System.out.println("Received reply: " + ar.result().body());
}
});
7. 微服务
比较好的学习项目blueprint微服务
官方demo