摘要:輕量級,部署簡單。此外,本文也不是入門文檔,而是為了預(yù)防陷坑而給出的指導(dǎo)意見,故在閱讀本文之前還請先仔細(xì)閱讀的文檔??梢曌鞯囊粋€最小部署和運行單元,簡單的說,可類比為。,主,負(fù)責(zé)部署程序中其他的。嚴(yán)格來講,之后,上述第一點并不完全正確。
一直以來早有將這些年用Vert.x的經(jīng)驗整理一下的想法,奈何天生不是勤快人,直到最近扶墻老師問起,遂成此文。
選擇理由現(xiàn)在想想,我們應(yīng)該算是國內(nèi)用Vert.x的最早一批人,版本大概是1.2.x吧,當(dāng)時Vert.x內(nèi)置了一個比較坑爹的模塊系統(tǒng),看似不錯,但其實很坑爹。但即使這樣,我們當(dāng)時還是在技術(shù)選型上采用了它。理由大致如下:
性能,它的底層是netty,并且編程模型跟node.js如出一轍,可算得上是“node on JVM”。同時,性能評測上比node還高出不少。
簡單,它比netty更簡單,而且可以輕易的支持cluster。
Actor模型,Verticle + Eventbus,降低了并發(fā)編程的難度。
WebSocket,恰好當(dāng)時的項目需要這樣的方案,服務(wù)器主動向前臺推。并且Vert.x提供的EventbusBridge讓前端js的組織更好。
支持Groovy,用過的都知道,這里就不展開了。
輕量級,部署簡單。
于是乎,它順利成章地成為了我們當(dāng)時系統(tǒng)接入層的中流砥柱,在實踐中也確實發(fā)揮了很好的作用。
踩坑指南鑒于Vert.x當(dāng)前的版本是3.3.3,因此本文的內(nèi)容也主要針對這個版本而言,一些我們遇到并且已經(jīng)修復(fù)的bug,也就不會也沒有必要在此啰嗦了。
此外,本文也不是入門文檔,而是為了預(yù)防陷坑而給出的指導(dǎo)意見,故在閱讀本文之前還請先仔細(xì)閱讀Vert.x的文檔。
編程語言雖然Vert.x的一大亮點號稱是支持“多語言”,即同一個工程內(nèi)可以同時用Java、Groovy、Javascript等不同語言編寫Verticle,但我還是建議采用Java為主,最多輔以Groovy。原因是:我發(fā)現(xiàn)很多新出的Vert.x模塊還是對Java支持最好,對于其他的則就相當(dāng)一般了,起碼不會讓你感覺特意針對這個語言而開發(fā)的。加上本來Java 8之后支持lambda,Java程序員的苦逼生活其實已經(jīng)改善不少。
在dgate中,我主要采用Java + Groovy的方式,兩者分工也很明確:前者用于數(shù)據(jù)處理,后者則用于DSL和數(shù)據(jù)類。
此時,由于混用了兩者,并且可能會出現(xiàn)Groovy類要用到程序中Java類的情況,那么就要用到j(luò)oint compile。在build.gradle中需要配置如下:
sourceSets.main.java.srcDirs = [] sourceSets.main.groovy.srcDirs += ["src/main/java"]
即,將Java類也交由Groovy編譯器來編譯。
工程結(jié)構(gòu)雖然Vert.x可以內(nèi)嵌到其他框架中,但在實際項目上我還是偏愛多帶帶部署,項目的構(gòu)建方式則為:gradle + fatjar。具體例子,可以參見這個build.gradle文件。
我在Vert.x郵件組中經(jīng)常看到有新人問關(guān)于Vert.x的組織方式,其實這是沒有理解Vert.x的本質(zhì):Verticle。Verticle可視作Vert.x的一個最小部署和運行單元,簡單的說,可類比為Servlet。因此,整個應(yīng)用可以這樣來劃分:
Launcher,程序入口,負(fù)責(zé)調(diào)起Vert.x的環(huán)境。
MainVerticle,主Verticle,負(fù)責(zé)部署程序中其他的Verticle。
Verticle,程序處理邏輯,調(diào)用其他POJO/POGO。
POJO/POGO,普通類,供Verticle使用。
前兩者負(fù)責(zé)初始化,Verticle則類似Servlet一樣等待被觸發(fā)(來自TCP/Eventbus/HTTP的Request),在實際處理時會調(diào)用到其他類。
這也就是為何在上面的build.gradle中有這樣關(guān)鍵的兩行的原因:
manifest { attributes "Main-Class": "……" attributes "Main-Verticle": "……" }Logging
Vert.x默認(rèn)支持JUL,對于其他Logging框架也有支持。但我嫌每次運行要敲那么多命令很煩,那么可以在Launcher中強制設(shè)置環(huán)境變量:
System.setProperty("vertx.logger-delegate-factory-class-name", "io.vertx.core.logging.SLF4JLogDelegateFactory");
可參見dgate的Launcher代碼。
部署Verticle跟Servlet類似,多個Verticle之間也會有依賴關(guān)系,存在先后部署的需要。
對于單個Verticle之間的依賴,如A依賴B,很簡單,利用deployVerticle的回調(diào)就很好解決。因為代碼簡單,這里就不再多帶帶列出,還是那句話,看文檔。
對于依賴多個Verticle,如A依賴B和C,則需要有點技巧了:
第一也是最差的方式,就是采用callback hell方式,層層遞進(jìn)。
第二種方法采用rxJava,利用Observable的運算來完成。
第三種方式,利用Java的Atom對象,示例代碼(Groovy)如下:
private void deployVerties(List
看到Atom對象,你是否覺得也可以采用CountDownLatch對象?很不幸,不行。我當(dāng)時做過嘗試,整個代碼立馬被Block住,直到我按了Ctrl-C。原因在于:Block住了EventLoop。
至于deployVerticle(),它可以接受字符串和類實例。當(dāng)使用字符串時,若是非Java類,如Groovy,需要采用這樣的格式:"語言前綴:類全限定名"。如:
"groovy:hawkeyes.rtds.processor.MailMan"
此外,部署的Verticle實例并非越多越好,還跟CPU的核數(shù)相關(guān)。
Block操作Vert.x應(yīng)用最忌諱Blocking操作,對此有多種處理:
采用Worker Verticle
使用executeBlocking函數(shù)
凡是涉及IO的操作,都請考慮一下。
EventBusEventBus相當(dāng)于Vert.x應(yīng)用的神經(jīng)系統(tǒng),但有幾點需要注意:
若想給部署在另一臺機(jī)器上的Verticle發(fā)消息,這兩個Verticle必需是在一個集群中。
攔截EventBus的消息需要注意一下這個小地方。
嚴(yán)格來講,3.2之后,上述第一點并不完全正確。這兩個Verticle之間可以采用TCP EventBusBridge來進(jìn)行通信,具體參見這篇文章。
Cluster和內(nèi)存計算Cluster是當(dāng)時我選擇Vert.x的一個重要考量,而且將Vert.x應(yīng)用多帶帶打成fatjar還有一個附帶好處就是Vert.x的cli都可以直接使用,其中就包括cluster命令。
Vert.x的集群建立在Hazelcast之上,除了集群調(diào)度,它本身還能做內(nèi)存存儲,即具備了Redis的主要功能。并且查詢語法也比Redis(2.x)的要靈活,支持類SQL語法。更重要的是,其ReadThrough特性讓人欲罷不能,簡化了編程。當(dāng)然,還包括其他如分布式鎖、隊列、任務(wù)等等。
所謂ReadThrough,即“若內(nèi)存中沒有,則查詢將下傳到下一級(通常是DB)”。Hazelcast的ReadThrough可通過實現(xiàn)MapLoader接口來實現(xiàn)。這個例子很簡單,故可查看Hazelcast的文檔了解。這里重點講一下如何在Vert.x中去配置,因為Vert.x沒有對此提供直接支持。
首先,cluster.xml即為一個標(biāo)準(zhǔn)的Hazelcast配置文件,故可在此配置相應(yīng)的MapLoader即可:
在從未給集群Map賦過值且第一次運行下列代碼時,注意兩個名字要相同,則觸發(fā)ReadThrough:
vertx.sharedData().getClusterWideMap("map_name") {……}
如果想在Vert.x中獲得Hazelcast實例,則可以直接使用下面代碼:
Setinstances = Hazelcast.getAllHazelcastInstances() hz = instances.first()
這樣便可利用Hazelcast的其他功能。在3.3.3之后,Vert.x集群支持Ignite,它是比Hazelcast更強大的內(nèi)存計算工具。而且,在Vert.x 3.4-beta1中已經(jīng)不再是技術(shù)預(yù)覽版,日后我肯定會全面擁抱它。
Ignite/Hazelcast不像Redis那樣曝光率那么高,但鑒于其本身都是老牌內(nèi)存計算軟件,且在開源之前都在高強度生產(chǎn)環(huán)境(沒記錯的話是銀行系統(tǒng))實戰(zhàn)演練過,同時對比一下兩者之間的功能列表,你會發(fā)現(xiàn)這些工具其實更強大,尤其是Ignite。它們的文檔都不錯,值得一看。
Handler最后說一說Handler中需要注意的地方,它非常適合寫Restful API。
之前用Vert.x寫接入層代碼,主要集中在Core、Groovy和Shell部分。這次寫dgate,算是扎扎實實用了一下Web部分。至于歷史,我就不詳細(xì)說了,總之一句話:哥是看著它長大的,;)。
Handler其實很簡單,只需要注意幾點:
Vert.x request Handler除了處理功能,還兼具Filter的功能。若處理完畢,請求不想讓下一個request handler處理,則直接返回即可;否則,需要調(diào)用:routingContext.next()。
對于同一個URL可以注冊多個handler,以調(diào)用順序為準(zhǔn)。故,想先處理的,如驗證,往前放。
至于其他,沒啥可說的,都很簡單。
寫在最后最后,來句雞湯:遇坑不可怕,還得勇于嘗試方能有所收獲,希望對各位有幫助!
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/66686.html
摘要:主要是避免引入太多的復(fù)雜性,并且出于靈活部署的需要。以應(yīng)用為例,由于實際上是在上執(zhí)行,若它被阻塞,即導(dǎo)致后續(xù)請求全部無法得到處理。因此,最合適的做法就是對于簡單業(yè)務(wù),采用異步庫。本系列其他文章入坑須知入坑須知入坑須知 最開始覺得這個系列也就最多3篇了不起了(因為事不過三嘛),沒曾想居然迎來了第四篇! Kotlin 由于最近決定投身到區(qū)塊鏈的學(xué)習(xí)當(dāng)中的緣故,出于更好的理解它的基本概念,自...
摘要:對于集成測試,直接模擬實際的環(huán)境,再加上合適的,目前看來也還不錯。這里給出兩個例子集成測試單元測試都是基于寫的,各位可以體驗其酸爽度。好啦,本期內(nèi)容就此結(jié)束,請保持關(guān)注,期待下期繼續(xù)本系列其他文章入坑須知入坑須知 隨著Vert.x進(jìn)化到3.5.0,本系列也迎來了新篇章。 CORS的新變化 對于CORS,搞Web開發(fā)(不論你是前端,還是后端)的同志應(yīng)該不陌生,尤其是如今微服務(wù)盛行的時代,...
摘要:這一點其實是非常不妥的,有潛在的安全問題。這次,在項目中終于采用了以它為基礎(chǔ)的集群方案。相反,使用一個周期,但針對每個生成一個一次性的,模擬隨機(jī)發(fā)送。同時,要記得用完之后立即釋放。 當(dāng)初創(chuàng)建簡書賬號的時候曾立下宏愿,希望保持周更,無奈現(xiàn)實殘酷,整個5月都處于忙忙碌碌的狀態(tài),居然令這個本來并不算太宏偉的目標(biāo)難以為繼,最終導(dǎo)致5月份交了白卷!【好吧,我承認(rèn),是我意志不夠堅定,太懶了,;)】...
摘要:之前寫了一篇沒有加入的的小博文。一拆分結(jié)構(gòu)根據(jù)自己的習(xí)慣和固定套路,拆分目錄結(jié)構(gòu)和組件結(jié)構(gòu)。把的導(dǎo)航組件集中放在純粹是個人習(xí)慣。二代碼實現(xiàn)入口文件是用來做的數(shù)據(jù)持久化。添加事項后要通知其他組件更新數(shù)據(jù)。 讀前須知 這個項目是第一次使用Redux的實例,并不具有專業(yè)性的理論知識。純粹分享一次開發(fā)過程與心得。之前寫了一篇沒有加入Redux的React Native ToDoList的小博文...
摘要:而不是開始,將服務(wù)使用多線程的請求重量級的容器。是啟動多個輕便單線程的服務(wù)器和流量路由到他們。亮點應(yīng)用程序是事件驅(qū)動,異步和單線程的。通過使用事件總線傳遞消息通信。為了建立一個消息系統(tǒng),則需要獲得該事件總線。 摘要 如果你對Node.js感興趣,Vert.x可能是你的下一個大事件:一個建立在JVM上一個類似的架構(gòu)企業(yè)制度。 這一部分介紹Vert.x是通過兩個動手的例子(基于Vert.x...
閱讀 2900·2021-11-15 11:39
閱讀 1522·2021-08-19 10:56
閱讀 1097·2019-08-30 14:12
閱讀 3742·2019-08-29 17:29
閱讀 723·2019-08-29 16:21
閱讀 3425·2019-08-26 12:22
閱讀 1520·2019-08-23 16:30
閱讀 1026·2019-08-23 15:25