Vert.xJava 微服務開發(fā)框架
Vert.x 是一個微服務開發(fā)框架,基于事件和異步,依托于全異步Java服務器Netty,并擴展了很多其他特性,以其輕量、高性能、支持多語言開發(fā)而備受開發(fā)者青睞,開發(fā)者可以通過它使用 JavaScript、Ruby、Groovy、Java、甚至是混合語言來編寫應用。
概念
- Vert.x是事件驅(qū)動的,其處理請求的高性能也是基于其事件機制。Vert.x的事件機制中有幾個非常重要的概念:Event Loop、Event Loop Vertical、Worker Vertical、Event Bus、Vert.x Module。
- Event Loop:即事件循環(huán),是由Vert.x啟動的事件處理線程,也是Vert.x項目對外開放的入口,Vert.x由此接收請求事件。一個Vert.x有一個或多個事件循環(huán)線程組成,線程最大數(shù)量為主機有效的CPU核數(shù)。
- Event Loop Vertical:事件的業(yè)務處理線程,存在于Event Loop中,用于處理非阻塞短任務。
- Worker Vertical : 事件的業(yè)務處理線程,用于處理長任務阻塞任務。
- Event Bus:即事件總線,是Vert.x事件模型中最核心的部分,所有的事件都經(jīng)由事件總線進行分發(fā),包括Vertical之間的通信事件。
- Vert.x Module : Vert.x項目模塊,一個應用通常由多個模塊組成,每個模塊一般包含多個Vertical。
事件模型流程
Vert.x以非阻塞IO的思想來實現(xiàn)高性能,非阻塞IO的實現(xiàn),基于Event Loop Vertical和Worker Vertical的分離,在Vert.x中,Event Loop用于接收,并將短業(yè)務操作交由其內(nèi)部的Vertical來處理,該模塊是非阻塞的,這樣可以保證請求的處理效率;阻塞任務通過Vert.x的事件機制脫離當前線程,轉(zhuǎn)移到Worker Vertical中執(zhí)行,并執(zhí)行結(jié)果返回給Event Loop Vertical。 這一過程完成的核心是Event Bus,Event Bus中注冊了所有的事件,通過事件匹配完成事件轉(zhuǎn)移和結(jié)果返回,從而將整個流程銜接起來。
Vert.x啟動時,會將Worker Vertical的事件處理函數(shù)加載到Event Bus,當一個HTTP請求發(fā)送到Vert.x構建的應用時,Event Loop首先接收到請求,并對請求做分析、包裝,然后將事件交給Event Bus來處理,Event Bus為此次請求事件添加一個事件ID,然后根據(jù)注冊的Worker Vertical事件尋找已經(jīng)注冊的監(jiān)聽函數(shù),若未找到則會拋棄該事件,若找到則會對處理類進行實例化,并同時使用事件ID在Event Bus中注冊一個返回結(jié)果處理事件,該事件為Event Vertical類型。下一步由Worker Vertical實例執(zhí)行事件處理函數(shù),事件處理函數(shù)中通常包含業(yè)務處理、數(shù)據(jù)庫操作等。Worker Vertical實例處理結(jié)束后,將返回結(jié)果和事件信息返回給Event Bus,Event Bus找到在其中注冊的Event Vertical實例,然后將返回數(shù)據(jù)交給該實例處理,Event Vertical實例進一步處理數(shù)據(jù)并將結(jié)果返回給瀏覽器。
數(shù)據(jù)傳遞
特點
如下代碼展示了 Web 服務器是如何通過 Vert.x 來處理靜態(tài)文件的:
// JavaScript
load('vertx.js')
vertx.createHttpServer().requestHandler(function(req) {
var file = req.path === '/' ? 'index.html' : req.path;
req.response.sendFile('webroot/' + file);
}).listen(8080)
# Ruby
require "vertx"
Vertx::HttpServer.new.request_handler do |req|
file = req.uri == "/" ? "index.html" : req.uri
req.response.send_file "webroot/#{file}"
end.listen(8080)
// Groovy
vertx.createHttpServer().requestHandler { req ->
def file = req.uri == "/" ? "index.html" : req.uri
req.response.sendFile "webroot/$file"
}.listen(8080)
// Java
import org.vertx.java.core.Handler;
import org.vertx.java.core.http.HttpServerRequest;
import org.vertx.java.deploy.Verticle;
public class Server extends Verticle {
public void start() {
vertx.createHttpServer().requestHandler(new Handler() {
public void handle(HttpServerRequest req) {
String file = req.path.equals("/") ? "index.html" : req.path;
req.response.sendFile("webroot/" + file);
}
}).listen(8080);
}
}
