書接上回,繼續(xù)分享。

通用報文解析服務(wù),用C#開發(fā),經(jīng)歷了三版更新,支撐起了關(guān)區(qū)內(nèi)的絕大多數(shù)數(shù)據(jù)交換業(yè)務(wù),截止至今,每日收發(fā)報文約20萬,數(shù)據(jù)量約5G,平均延遲在1分鐘內(nèi)。

回想起那些半夜處理積壓報文的場景,不勝唏噓,決定把這個演進(jìn)過程向大家講述一下。回顧歷史,展望未來,如果能給大家一些啟發(fā),是再好不過的了。

(第三版)

三、通用報文解析服務(wù)V3.0——分布式,消息隊列

    上一篇說到了一個問題,引用的程序集由不同的團(tuán)隊負(fù)責(zé)維護(hù),都引用一套公共組件庫,在更新和發(fā)布時互相掣肘,導(dǎo)致無法保證有效的更新。其實這就是依賴管理的問題。

導(dǎo)致這個問題的根源是程序的架構(gòu):

Android培訓(xùn),安卓培訓(xùn),手機(jī)開發(fā)培訓(xùn),移動開發(fā)培訓(xùn),云培訓(xùn)培訓(xùn)

    其中公共組件庫由專門的小組開發(fā)維護(hù),不定期發(fā)布新版本。

  •     最初的時候,所有的解析器項目源代碼都在同一個VisualStudio解決方案中,更新公共組件庫代價很低,只需要編譯一下,管理方面也不需要逐個測試。就可以更新了。

  •     后來有了其他項目的解析器不斷加入,他們從開始開發(fā)時,就會獲取最新的公共組件庫版本,從而導(dǎo)致部署時,我需要更新到相應(yīng)的版本。項目少的時候還好吧,喊一下大家,都更新一下。

  •     終于有一天,問題來了。公共組件庫中有個方法名稱有拼寫錯誤,某次更新給修復(fù)了,由于我的大意直接更新到了生產(chǎn)環(huán)境,導(dǎo)致很多解析器不工作了,紛紛抱怨“找不到xxx方法”。沒辦法只能回滾程序,喊大家逐個更新公共組件庫,再重新編譯。

  •     以上還只是前奏,又有一次更新后,有個解析器報錯“找不到xxx方法”,但一看代碼這個方法還在啊……額只是多了一個可選參數(shù)。這里插一句,調(diào)用方的c#源碼雖然沒有變,但是編譯后的IL中間代碼確改變了,可選參數(shù)就是一個語法糖。然后又有人獲取的公共組件庫版本不對,導(dǎo)致反復(fù)更新了好幾次才最終消除這個錯誤。

    簡而言之,依賴管理從來不是一個簡單的問題,我決心徹底改變這個問題。

    在一些比較成熟的技術(shù)團(tuán)隊中,嚴(yán)格的管理流程能一定程度上預(yù)防這個問題,比如組件庫更新時,強(qiáng)制每個引用者都更新版本并更新至生產(chǎn)環(huán)境;或者組件庫更新時,必須檢查能否讓調(diào)用方成功編譯,即向后兼容。這些方案都有其代價,而且在我們這種作坊式的小團(tuán)隊中,很難實施。能變的,就只有程序架構(gòu)本身了。

    要解耦,就要把各個解析器的運行時完全分離,即改造為集中-分布式架構(gòu)。集中點和分布點之間的消息傳遞,我考慮過兩種方案,第一,通過數(shù)據(jù)庫,這其實就是上一篇中已經(jīng)實現(xiàn)了的所謂分布式架構(gòu);第二,主服務(wù)提供一個WCF,讓其他服務(wù)調(diào)取,獲得待解析的報文;第三,通過MQ等類似中間件傳遞。

    第一種會顯著增大數(shù)據(jù)庫壓力,尤其是分布點數(shù)量多時,放棄。第二種相當(dāng)于是自己造了一個MQ,還不如直接用現(xiàn)成的,干嘛非要重復(fù)發(fā)明輪子。在孫老的推薦下,我選擇了簡單好用輕量級的RabbitMQ。

    于是整個架構(gòu)變成了這樣:

Android培訓(xùn),安卓培訓(xùn),手機(jī)開發(fā)培訓(xùn),移動開發(fā)培訓(xùn),云培訓(xùn)培訓(xùn)

    我們用了RabbitMQ的Direct方式建立Exchange,文件擴(kuò)展名作為Route Key傳遞,就實現(xiàn)了特定的文件擴(kuò)展名報文發(fā)送至特定的Queue。

    我又多了一項工作,維護(hù)RabbitMQ(苦笑),但是好處也是明顯的。首先,每個項目各自的解析服務(wù)獨立運行,分頭維護(hù),我的運維壓力減輕。其次,各自更新互不干擾,唯一耦合的就是RabbitMQ和MessageDB,非常穩(wěn)定基本不變。

    當(dāng)然,為了不至于大家的Windows服務(wù)做的五花八門,我也提供了一套Demo和文檔。先期嘗試的三個項目,改造只用了一個星期就完成了。

    再后來,接觸了Docker容器,發(fā)現(xiàn)這也是一個極好的工具,而且官方提供了RabbitMQ的鏡像。用了Docker的好處是,系統(tǒng)的備份和故障后的恢復(fù)變得非常簡單快捷,一行命令搞定,而且可靠。

    現(xiàn)在唯一遇到的問題就是,RabbitMQ配置好Exchange、Queue等參數(shù)后,導(dǎo)出的鏡像不含有這些配置信息,完全是初始狀態(tài),很讓人費解,只好做了一套HttpAPI的命令行備用。如果有知道的朋友,歡迎留言賜教,不勝感激。

    好了,到這里基本就介紹完了。以后我打算分享一下我開發(fā)實用小工具的經(jīng)驗。具體就是實時監(jiān)控狀態(tài),減輕運維壓力,更能第一時間發(fā)現(xiàn)問題,滅問題于萌芽,解危機(jī)于無聲。

http://www.cnblogs.com/pleiades/p/6838926.html