1. 程式人生 > >vert.x詳細介紹,全非同步框架

vert.x詳細介紹,全非同步框架

Vert.x是一個基於JVM、輕量級、高效能的應用平臺,非常適用於最新的移動端後臺、網際網路、企業應用架構。Vert.x基於全非同步Java伺服器Netty,並擴展出了很多有用的特性

介紹:

Vert.x誕生於2011年,當時叫node.x,不過後來因為某些原因改名位Vert.x。經過三年多的發展,現在已經到了3.3.3版本,社群也越來越活躍,在最新的官網Vertx.io上,作者用一句話介紹了它,JVM上的Reative開發套件。Vert.x目前是見過最功能最強大,第三方庫依賴最少的Java框架,它只依賴Netty4以及Jacskon,另外如果你需要建立分散式的Vert.x則再依賴HazelCast這個分散式框架,注意Vert.x3必須基於Java8。由於基於JVM,所以Vert.x可以用其他語言來實現你的業務。

Vert.x是一個非同步無阻塞的網路框架,其參照物是node.js。基本上node.js能幹的事情,Vert.x都能幹。Vert.x利用Netty4的EventLoop來做單執行緒的事件迴圈,所以跑在Vert.x上的業務不能做CPU密集型的運算,這樣會導致整個執行緒被阻塞。

特性:

1、同時支援多種程式語言——目前已經支援了Java、Scala、JavaScript、Ruby、Python、Groovy、Clojure、Ceylon等。對程式設計師來說,直接好處就是可以使用各種語言豐富的LIB,同時也不再為程式語言選型而糾結;

2、非同步無鎖程式設計——經典的多執行緒程式設計模型能滿足很多Web開發場景,但隨著移動網際網路併發連線數的猛增,多執行緒併發控制模型效能難以擴充套件,同時要想控制好併發鎖需要較高的技巧,目前Reactor非同步程式設計模型開始跑馬圈地,而Vert.x就是這種非同步無鎖程式設計的一個首選;

3、對各種IO的豐富支援——目前Vert.x的非同步模型已支援TCP、UDP、FileSystem、DNS、EventBus、Sockjs等;

極好的分散式開發支援——Vert.x通過EventBus事件匯流排,可以輕鬆編寫分散式解耦的程式,具有很好的擴充套件性;

4、生態體系日趨成熟——Vert.x歸入Eclipse基金會門下,非同步驅動已經支援了Postgres、MySQL、MongoDB、Redis等常用元件,並且有若干Vert.x在生產環境中的應用案例。

Vert.x是基於事件的,提供一個事件驅動程式設計模型,使用Vert.x作為伺服器時,程式設計師只要編寫事件處理器event handler即可. 當TCP socket有資料時,event handler理解被建立呼叫,另外它還可以在以下幾種情況啟用: '當事件匯流排Event Bus接受到訊息時,' '當接收到HTTP訊息時,' 當一個連線斷開時',' '當計時器超時時.'

作為服務層處理邏輯這一層基本上對應的傳統Java裡的領域模型處理層.各種Service呼叫,以及對資料層的呼叫.差不多是一個承上啟下的一層.傳統的模型裡,這一層基本上都是同步呼叫,即使有非同步呼叫,也是與業務邏輯分離的非同步.如果全非同步會導致業務邏輯碎亂.程式碼很難描述清楚.到這裡你會發現Vert.x其實不太好融合到業務性很強的服務層裡.其主要原因如下
1、自身是非同步體系,不適合描述順序邏輯性強的業務
2、由於非同步的問題,訪問資料層也必須是非同步,導致業務模型進一步碎片化.

Vert.x的執行單元叫verticle。即程式的入口,每個語言可能實現的方式不一樣,比如Java需要繼承一個AbstractVerticle抽象類

verticle分兩種,一種是基於EventLoop的適合I/O密集型的,還有一種是適合CPU密集型的worker verticle。而verticle之間相互通訊只能通過Eventbus,可以支援point to point 的通訊,也可以支援publish & subscribe通訊方式。


重要的介面
org.vertx.java.core.Handler

Vert.x執行時的核心介面, 用於結果回撥處理,你大部分的邏輯程式碼都會在這裡執行.所以無需解釋.

org.vertx.java.core.Context
這個名詞的含義就是一個基於Vert.xAPI搭建起來的可執行的程式.這裡我們就簡單的理解繼承了org.vertx.java.platform.Verticle的Java類或者其他語言的指令碼

那Context介面就代表著一次可執行單元的上下文,這裡的上下文只幹一件事情就是處理Handler裡的內容void runOnContext(Handler<Void> action);,

在Vert.x裡有兩種上下文,即EventLoop與Worker,而Worker又會分按順序執行的Worker與多執行緒Worker.這裡我們就先看成兩類EventLoop與Worker,什麼是EventLoop呢.
在Vert.x裡所有的事件包括IO都是依賴於Netty的EventLoop介面,而這個介面在Netty裡會一定的頻率呼叫.即當發生IO事件時,Netty會按時間比率分配CPU資源去響應這個事件.
在Vert.x裡你可以簡單的理解為IO相關的事件就可以了,用了一個特定的執行緒池來響應這類請求.而Worker在Vert.x裡預設是一套按順序執行的Handler,即按照先來先到的順序依次執行,此類的請求是另一個執行緒池執行.


所有業務邏輯其實都會跑在Netty裡的EventLoop上,而EventLoop通過迴圈事件佇列來執行所有的業務邏輯,這樣可以把一些I/O操作頻繁的事件及時從CPU上剝離開來,最後通過註冊一個回撥Handler來處理所有的事件回撥

org.vertx.java.core.Vertx
這個其實就是API,非Vert.x擴充套件者,能用到的所有的東西都在這裡了.基於上面的三個介面,其實就能抽象出一個非同步的模型,通過Vertx介面呼叫一個API,API內部會持有一個Context,在API本身的非業務邏輯執行完後,將Handler傳入Context執行.這大概就是整個Vert.x內部執行的流程,三個介面抽象出一個世界這便是軟體設計的哲學.

重要概念

Verticle

基於Vert.x框架實現的程式碼包,就是一個Verticle,簡單點說,一個可以被Vert.x框架執行的程式碼呼叫了Vert.xAPI的程式碼就是一個Verticle.他可以用Scala Clojure JS Ruby等語言實現.多個Verticle例項可以並行的被執行.一個基於Vert.x的服務也許需要多個verticles來實現,而且要部署在多臺伺服器上.他們之間通過vert.x事件進行通訊.你可以之間通過vert.x命令啟動,也可以將verticle包裝成vert.x modules.

Module

Vert.x應用由一個或多個modules來實現.一個模組呢由多個verticles來實現.你可以把module想象出一個個Java package.裡面可能是特定業務的實現,或者公共的服務實現(那些可以重用的服務).Vert.x編寫好的module,可以釋出到maven的倉庫裡.以zip包裝成二進位制格式.或者釋出到vert.x module 註冊中心.實際上這種以模組方式的開發,支撐著整個Vert.x生態系統.Module更多的資訊,我需要單獨開一個系列來講解.

Event Bus

它是Vert.X的核心,在叢集中容器之間的通訊,各個Verticle之間的通訊都是經過Event Bus來實現的,後期會推出一篇專門關於這個的文章,敬請等待。

Shared Data

它是Vert.X提供的一個簡單共享Map和Set,用來解決各個Verticle之間的資料共享

框架圖


例項:

public class HelloWorldEmbedded {
	public static void main(String[] args) {
	    // Create an HTTP server which simply returns "Hello World!" to each request.
	    Vertx.vertx().createHttpServer().requestHandler(req -> req.response().end("Hello World!")).listen(8080);
	  }

}

啟動一個verticle
 vertx.deployVerticle(DingtalksrvVertical.class.getName(), deploymentOptions, result -> {
		      if (result.succeeded()) {
		        String deployId = result.result();
		        System.out.println("Dingtalksrv 部署成功 [" + deployId + "]");
		        future.complete();
		      } else {
		        System.out.println("Dingtalksrv 部署失敗  " + result.cause().getMessage());
		        future.fail(result.cause());
		      }
		    });

啟動服務
HttpServerOptions options = createOptions();
    server = vertx.createHttpServer(options);
    server.requestHandler(mainRouter::accept);
    server.listen(result -> {
      if (result.succeeded()) {
        
      } else {
       
      }
    });
mainRouter = Router.router(vertx);
mainRouter.mountSubRouter("/api", router);
Router router = Router.router(vertx);
router.route(HttpMethod.POST, "/hello").handler(HelloHandler()::handleRequest);
非同步封裝
executor.executeBlocking((Future<T> f) -> {
      try {
          jdbc_routine();
        }
        f.complete();
      } catch (SQLException e) {
        f.fail(e);
      }
    }, handler);

Vert.x3支援很多常用工具:metrics、熱部署、consul、kafka、mongo、redis等

有興趣可以到github上檢視相應元件

Vert.x的執行單元叫verticle。即程式的入口,每個語言可能實現的方式不一樣,比如Java需要繼承一個AbstractVerticle抽象類

verticle分兩種,一種是基於EventLoop的適合I/O密集型的,還有一種是適合CPU密集型的worker verticle。而verticle之間相互通訊只能通過Eventbus,可以支援point to point 的通訊,也可以支援publish & subscribe通訊方式。