摘要:這一點其實是非常不妥的,有潛在的安全問題。這次,在項目中終于采用了以它為基礎的集群方案。相反,使用一個周期,但針對每個生成一個一次性的,模擬隨機發送。同時,要記得用完之后立即釋放。
當初創建簡書賬號的時候曾立下宏愿,希望保持周更,無奈現實殘酷,整個5月都處于忙忙碌碌的狀態,居然令這個本來并不算太宏偉的目標難以為繼,最終導致5月份交了白卷!【好吧,我承認,是我意志不夠堅定,太懶了,;)】
最終的負罪感導致了本文的誕生,同時也意味著一個新坑的開啟。作為Vert.x的使用者,我會定期更新獲得的經驗,希望為同好提供一些小小的幫助,掃除前進的障礙。同時,作為一個懶人和見異思遷者,事先聲明,我沒有辦法保證我的興趣不會發生轉移,所以,我也不知道這個坑能開多久,望大家注意。
那么,讓我們進入主題。
HTTPS請求這是在跟某運營商的NB-IOT平臺對接時解決的問題,其實最終的整個代碼并不復雜,類似下面(采用雙向認證方式):
httpClient = vertx.createHttpClient(new HttpClientOptions() .setSsl(true) .setPfxKeyCertOptions(new PfxOptions().setPath("xxx.pkcs12").setPassword("xxx")) .setTrustStoreOptions(new JksOptions().setPath("xx.jks").setPassword("xxx")) .setVerifyHost(false));
基本上跟文檔上的例子差不多,值得注意的地方就是最后一行代碼:setVerifyHost(false),當時這個運營商的平臺也處于測試狀態,并沒有域名,是自簽證書,設置為false,客戶端不驗證服務端證書的合法性,則可規避這一點,讓整個開發可以不受影響繼續下去。
JWT的密鑰隨著微服務的流行,JWT也變得流行起來,但有一點開發經常忽視的是直接將生成JWT要用到的證書包含在源代碼中。這一點其實是非常不妥的,有潛在的安全問題。
一個常識是:開發測試用的證書和產品環境的證書要分開,由不同的人來負責管理!
比如,在dgate中,產品環境的證書由運維通過下面的環境變量指定(例子):
export dgate_key_store=./test1.jceks export dgate_key_type=jceks export dgate_key_password=test123
在生成JWT對象時,從環境變量里直接拿這些值,供未來使用。
HTTP Form/Upload請求這是在實現dgate遇到的需求,小伙伴們強烈要求支持Form提交和文件上傳,于是就有了RelayHandler的誕生。它的實際作用就是請求的透傳,即將請求內容原封不動的搬到后端服務那里去。
實現很簡單,看代碼就知道,但在編寫測試代碼時就遇到了需要發起Form和Upload的問題。這個需求要是放在現在很簡單,因為Vert.x從3.4開始提供了WebClient模塊,用它可以很輕易的實現這樣的需求。
可在當時,這個模塊還沒有出來咧!那就只能自己動手了,因為并沒有那么麻煩,本質上就是按照HTTP協議的要求,向Request寫入對應格式的內容就行了。這一點可以從RequestUtils的form和upload方法實現里看出來。
UDP的Socket這是在另一個項目中遇到趣事,其實既不是需求也不是問題,而是錦上添花,方便調試。在這個項目中,我們用Vert.x實現了一個UDP Server,用戶的設備會直接向這個Server發包。在一定的條件下,如時鐘不對,Server會向設備發起一個校時命令。
作為負責任的開發,我們當然不會依賴用戶的硬件設備來進行調試啦!也就是說,我們自己是實現了一個MockClient的,它完全實現了設備和服務器的通信協議。內測沒問題之后就到了聯調階段了,可偏偏我們已經發出了校時命令(終端有輸出),但硬件卻說沒有收到!
要命的是,通過Linux的tcpdump來抓包,居然在UDP Server的地址和端口上沒有抓到對應的包!這真是渾身是嘴也說不清啊!而且,自己寫的Mock與Server總是能夠順暢的通信!
遇到這么個怪問題那就不得不上網絡調試的終極大殺器Wireshark了,看看到底發生了什么。很快,問題定位出來了,下發命令確實已經發出,只不過是從另一個端口發出去的。這是因為寫代碼時,覺得UDP反正就沒有連接的概念,只要有對方的地址信息那就直接發送過去就好了。于是,在發送前重新創建了一個DatagramSocket實例,通過它直接發出去了。
實際的修改也很簡單,用UDP Server對應的那個DatagramSocket實例發送就好了。最后的結果當然是皆大歡喜。
與Ignite的集成我之前不止一次的表達出對于Ignite的喜愛,覺得它比Redis要好(注:最近有所改變,因為Redis提供了對于HpyerLogLog開箱即用的支持,而Ignite則貌似沒有。)。這次,在項目中終于采用了以它為基礎的Vert.x集群方案。
整個集成和使用并不復雜,這是我們做過的事情:
引入依賴和ignite.xml
在Launcher中強制設置為Cluster模式,簡化命令行啟動:
@Override public void beforeStartingVertx(VertxOptions options) { //Force to use cluster mode options.setClustered(true); }
為了方便后續獲得配置里的緩存,需要對ignite在啟動時進行初始化,于是我們寫了一個工具類,其主要用處就是在啟動前從Vert.x中獲得Ignite并保存起來,方便后續按名字獲取緩存時直接使用。初始化代碼如下(同樣是在Laucher里面,但由于要獲得Vertx實例,故放在afterStartingVertx里):
if (ignite == null) { vertxInstance = vertx; ClusterManager clusterManager = ((VertxInternal) vertx).getClusterManager(); String uuid = clusterManager.getNodeID(); ignite = Ignition.ignite(UUID.fromString(uuid)); ... }
有了Ignite實例之后,其他的功能,如Read/Write Through、Cache事件等等,就是按照Ignite文檔的指示來做了。這部分的內容已經屬于Ignite的領域且文檔也有詳細的闡述,這里就不再贅述。
壓力測試作為服務器應用,怎么能不來一把壓測來對其性能摸底呢?在實際過程中,新手最容易忘記的問題就是:沒有修改操作系統的最大可用句柄數,導致壓力還沒上來就進行不下去了。
除此之外,用Vert.x自寫壓測代碼時也需要注意:
對于UDP服務器來講,注意設置足夠大小的接收緩存,否則會導致Client的包被丟棄,且沒有任何錯誤提示。表象就仿佛服務器掛了或沒有能力處理一樣,而實際的壓力其實遠遠沒有達到服務器的極限。參見下面的代碼:
vertx.createDatagramSocket( new DatagramSocketOptions() .setReceiveBufferSize(UDP_RECEIVE_BUFFER_SIZE) .setSendBufferSize(UDP_SEND_BUFFER_SIZE)) .listen(..., "0.0.0.0", asyncResult -> { ... }
在壓測發起端,避免為每個Client生成一個長時間存在的周期Timer。相反,使用一個周期Timer,但針對每個Client生成一個一次性的Timer,模擬隨機發送。同時,要記得用完之后立即釋放。類似的結構如下:
vertx.setPeriodic(20000, tid -> { mockClients.forEach((uid, socket) -> { vertx.setTimer(ThreadLocalRandom.current().nextInt(10, 10000) , id -> { logger.info("...", uid); send(...); vertx.cancelTimer(id); }); }); });
自此,這段時間積壓下來,覺得有必要寫寫的內容已經全部傾倒完畢,敬請期待下一期(如果真有的話,;))。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/11261.html
摘要:主要是避免引入太多的復雜性,并且出于靈活部署的需要。以應用為例,由于實際上是在上執行,若它被阻塞,即導致后續請求全部無法得到處理。因此,最合適的做法就是對于簡單業務,采用異步庫。本系列其他文章入坑須知入坑須知入坑須知 最開始覺得這個系列也就最多3篇了不起了(因為事不過三嘛),沒曾想居然迎來了第四篇! Kotlin 由于最近決定投身到區塊鏈的學習當中的緣故,出于更好的理解它的基本概念,自...
摘要:對于集成測試,直接模擬實際的環境,再加上合適的,目前看來也還不錯。這里給出兩個例子集成測試單元測試都是基于寫的,各位可以體驗其酸爽度。好啦,本期內容就此結束,請保持關注,期待下期繼續本系列其他文章入坑須知入坑須知 隨著Vert.x進化到3.5.0,本系列也迎來了新篇章。 CORS的新變化 對于CORS,搞Web開發(不論你是前端,還是后端)的同志應該不陌生,尤其是如今微服務盛行的時代,...
摘要:輕量級,部署簡單。此外,本文也不是入門文檔,而是為了預防陷坑而給出的指導意見,故在閱讀本文之前還請先仔細閱讀的文檔。可視作的一個最小部署和運行單元,簡單的說,可類比為。,主,負責部署程序中其他的。嚴格來講,之后,上述第一點并不完全正確。 一直以來早有將這些年用Vert.x的經驗整理一下的想法,奈何天生不是勤快人,直到最近扶墻老師問起,遂成此文。 選擇理由 現在想想,我們應該算是國內用V...
摘要:而不是開始,將服務使用多線程的請求重量級的容器。是啟動多個輕便單線程的服務器和流量路由到他們。亮點應用程序是事件驅動,異步和單線程的。通過使用事件總線傳遞消息通信。為了建立一個消息系統,則需要獲得該事件總線。 摘要 如果你對Node.js感興趣,Vert.x可能是你的下一個大事件:一個建立在JVM上一個類似的架構企業制度。 這一部分介紹Vert.x是通過兩個動手的例子(基于Vert.x...
摘要:之前寫了一篇沒有加入的的小博文。一拆分結構根據自己的習慣和固定套路,拆分目錄結構和組件結構。把的導航組件集中放在純粹是個人習慣。二代碼實現入口文件是用來做的數據持久化。添加事項后要通知其他組件更新數據。 讀前須知 這個項目是第一次使用Redux的實例,并不具有專業性的理論知識。純粹分享一次開發過程與心得。之前寫了一篇沒有加入Redux的React Native ToDoList的小博文...
閱讀 3476·2021-11-19 09:40
閱讀 1492·2021-10-13 09:41
閱讀 2655·2021-09-29 09:35
閱讀 2710·2021-09-23 11:21
閱讀 1693·2021-09-09 11:56
閱讀 830·2019-08-30 15:53
閱讀 844·2019-08-30 15:52
閱讀 598·2019-08-30 12:47