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