Vert.x是什么
Vert.x(http://vertx.io/)是一個基於JVM、輕量級、高性能的應用平台,非常適用於最新的移動端后台、互聯網、企業應用架構。
Vert.x框架基於事件和異步,依托於全異步Java服務器Netty,並擴展了很多其他特性,以其輕量、高性能、支持多語言開發而備受開發者青睞。
官網是這么說的,Vert.x is a tool-kit for building reactive applications on the JVM. 我理解或者說是亂翻譯的意思是,Vert.x是一個開發基於JVM的響應式應用的工具。官網:
http://vertx.io/
自帶屬性
- Polyglot(多種語言支持)
簡單點講,就是只要是JVM上的主流語言,都可以直接編寫基於Vert.x的應用.目前官方推出的有java, Javascript, Groovy, Ruby,和Ceylon
- Simplicity(簡單)
這里的簡單意味着你編寫的代碼是完全
基於異步事件
的,類似Node.JS,與此同時.你不需要關注線程上的同步,與鎖之類的概念,所有的程序都是
異步執行並且通信是無阻塞的
- Scalability(擴展性)
因為基於Actor模型,所以你的程序都是一個點一個點的單獨在跑,一群點可以組成一個服務,某個點都是可以水平擴展,動態替換,這樣你的程序,基本就可以達到無限制的水平擴展
- Concurrency(並發性)
此並發並非JDK庫的並發,當你Coding的時候,不再關注其鎖,同步塊,死鎖之類的概念,你就可以隨性所欲的寫自己的業務邏輯.Vert.x本身內置三種線程池幫你處理
- 模塊化
Vert.x本身內置強大的模塊管理機制,當你寫完一個Vert.x業務邏輯的時候,你可以將其打包成module,然后部署到基於Maven的倉庫里,與現有主流的開發過程無縫結合.so easy…
- 分布式消息傳輸
Vert.x基於分布式Bus消息機制實現其Actor模型,簡單點講每個Vert.x實例都可以與其他節點內置的通信接口,底層上實現框架內部的消息同步與傳輸,類似Erlang的ping pong自檢消息.而我們的業務邏輯如果依賴其他Actor則通過Bus簡單的講消息發送出去就可以了
- 支持WebSocket
支持WebSocket協議兼容SockJS
- 對各種IO的豐富支持
目前Vert.x的異步模型已支持TCP、UDP、FileSystem、DNS、EventBus、Sockjs等
- 異步無鎖編程
經典的多線程編程模型能滿足很多Web開發場景,但隨着移動互聯網並發連接數的猛增,多線程並發控制模型性能難以擴展,同時要想控制好並發鎖需要較高的技巧,目前Reactor異步編程模型開始跑馬圈地,而Vert.x就是這種異步無鎖編程的一個首選
- 生態體系日趨成熟
Vert.x歸入Eclipse基金會門下,異步驅動已經支持了Postgres、MySQL、MongoDB、Redis等常用組件,並且有若干Vert.x在生產環境中的應用案例
官網首頁最后還說了一句:Vert.x is
fun
並且顯擺了下都有哪些公司在使用它們,
那好吧
。
Reactor模式
和傳統Java框架的多線程模型相比,Vert.x Netty是 Reactor模式的Java實現
通常Tomcat會在100個並發長請求下堵塞,而Vertx將長任務委托給另外一個線程來執行,從而不會堵塞當前線程,與NodeJS的原理非常類似,如下圖:

基本概念
Verticle
Vert.x的代碼執行包,它可以用JS、Ruby等多語言來編寫,在同一個Vert.x實例中可以同時執行多個Verticle,一個應用可能由多個Verticle組成,他們被部署到不同的網絡節點上,彼此之間通過在Vert.x的事件總線(event bus)上交換信息來通信。對於具體的verticle可以直接從命令行啟動,但是通常會將它打包成modules
Module
Vert.x應用由一個或多個modules來實現.一個模塊由多個verticles來實現.你可以把module想象出一個個Java package.里面可能是特定業務的實現,或者公共的服務實現(那些可以重用的服務).Vert.x編寫好的module,可以發布到maven的倉庫里.以zip包裝成二進制格式.或者發布到vert.x module 注冊中心.實際上這種以模塊方式的開發,支撐着整個Vert.x生態系統
Vert.x 實例
Verticles 其實是跑在 Vert.x實例上的.所謂Vert.x實例其實就是一個運行在某一個JVM上的Vert.x對象實例.可以將多個Verticles運行在一個Vert.x實例上,而vert.x實例可以跑在單個JVM上,也可以跑在其他JVM上,通過分布式event bus來維持通信.注意vert.x實例其實是由vertx命令行啟動的.你可以指定實例數目在單個JVM上
Event Loops
即事件循環,是由Vert.x啟動的事件處理線程,也是Vert.x項目對外開放的入口,Vert.x由此接收請求事件。一個Vert.x有一個或多個事件循環線程組成,線程最大數量為主機有效的CPU核數。
上面提到Vert.x實例,每個Vert.x實例內部維持幾個線程,線程數目基本與CPU核數一致.這些線程在Vert.x內部叫做事件循環(Event Loop)這個思想在很多事件驅動的架構都有,典型的就是IOS事件,它操作系統內部也有一個事件監控線程,不停捕捉外部的事件,比如touch,多點觸摸等.然后分配到指定的處理函數上,在vert.x里這些處理函數是Handler接口.在Vert.x里這些事件可以是從Socket里讀到數據,或者是一個定時器觸發,亦或是一個HTTP請求接受到.一個部署好的verticle都會得到一個event loop,來處理相關的事件.相關的后續的處理都會在這個event loop解決掉(也就是一個線程里),注意在同一個時間里有且只有一個線程處理.即Handler接口里是線程同步的.這點非常類似 reactor pattern.
不要在Event Loops寫一些阻塞代碼,因此下面code不應該存在
- Thread.sleep()
- Object.wait()
- CountDownLatch.await()
而且如果是長時間的計算也不應該存在.更不可能發生長時間的IO堵塞,典型的就是JDBC查詢
Event Loop Vertical
事件的業務處理線程,存在於Event Loop中,用於處理非阻塞短任務
Event Bus
它是Vert.X的核心,在集群中容器之間的通信,各個Verticle之間的通訊都是經過Event Bus來實現的
Shared Data(共享數據)
它是Vert.X提供的一個簡單共享Map和Set,用來解決各個Verticle之間的數據共享。
消息通過Bus可以在各個Vert.x實例直接傳輸.但是如果多個Verticle在一個Vert.x實例內,是可以避免進行消息傳輸的.比如單個JVM內,你不會通過Socket互相在兩個Java 對象之間傳輸消息吧.但是因為實例隔離,因為Actor模型,所以對象數據如果要傳到Handler里,必須通過消息傳輸.
Vert.x提供了一個簡單的共享Map與Set來解決這個問題.數據被存儲到一個不可變的數據結構了,各個實例直接通過此API獲取數據.(看例子更容易)
Worker Vertical (阻塞處理)
事件的業務處理線程,用於處理長任務阻塞任務。
事件處理之外肯定會發生其長時間數據處理請求.比如處理一個圖片上傳,然后轉存到磁盤上等.或者一次長時間的排序計算等.
在Verticle類型里,有一種特別的verticle叫做Worker.不同於標准的verticle,他不使用event loop.而是采用vert.x內部的另一個線程池叫做worker pool.其區別在於,worker verticles不會並行的執行Handler.而是阻塞式的,等待上一個Handler處理完了,才會再執行后面的請求.你可以想象出隊列的方式執行某些請求.所以為了支持標准的與阻塞式的worker verticles, Vert.x 提供了一種混合線程模型,你可以選擇適當的模型用於你的應用.
worker verticle是一種阻塞式的方法,但是不可以做到並發水平擴展的

參考: