這篇文章內(nèi)容會很短,主要是想給大家分享下我最近在做一個簡單的rabbitmq客戶端類庫的封裝的經(jīng)驗(yàn)總結(jié),說是簡單其實(shí)一點(diǎn)都不簡單。為了節(jié)省時間我主要按照Library的執(zhí)行順序來介紹,在你看來這里僅僅是一個簡單的經(jīng)驗(yàn)總結(jié),但是在我看來這些經(jīng)驗(yàn)只有在你真正的封裝rabbitmq客戶端庫的時候且將你的客戶端安全穩(wěn)定的發(fā)布上線后才會真的發(fā)現(xiàn)這些問題。
目前成都創(chuàng)新互聯(lián)已為超過千家的企業(yè)提供了網(wǎng)站建設(shè)、域名、網(wǎng)絡(luò)空間、網(wǎng)站托管運(yùn)營、企業(yè)網(wǎng)站設(shè)計(jì)、監(jiān)利網(wǎng)站維護(hù)等服務(wù),公司將堅(jiān)持客戶導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長,共同發(fā)展。
比如你的庫只是鏈接單個Node的時候和鏈接高可用集群的HAProxy時候是完全兩回事。當(dāng)你未能在你的庫里使用反向注入LOG接口的時候一旦在線上發(fā)生網(wǎng)絡(luò)解析和序列化等一系列在線問題時候你是多么無能為力。當(dāng)你使用同步循環(huán)獲取隊(duì)列消息的時候一旦發(fā)生異常你的鏈接就會斷掉等等這些細(xì)節(jié)。我總結(jié)了我在編寫這個library的時候慢慢穩(wěn)定下來的過程和經(jīng)驗(yàn)。至少目前來看網(wǎng)絡(luò)上的文章,當(dāng)然我是指.NET/C#方面的,都沒有講到這些問題,大部分的文章都是簡單的介紹了一個最最基本的使用和最最基本的demo而已,達(dá)不到企業(yè)級使用的要求。在這個過程中,感謝我的團(tuán)隊(duì)和給過我指導(dǎo)的同事,讓我明白了一些技術(shù)道理。
好東西不能石沉大海,尤其是.NET領(lǐng)域更需要這樣的東西來填補(bǔ)這一空缺。廢話不多說了,進(jìn)入主題,那些編寫框架和組件的大道理這里就不講了,我只說重點(diǎn)。
就是說你的接受Channel和發(fā)送的Channel要分離開,如果不分開會出現(xiàn)偶發(fā)性的消息串掉的錯誤,我這里現(xiàn)在沒有環(huán)境無法重現(xiàn)截圖。我是在做壓力測試的時候,用了一個Channel的時候Debug拋出來的異常。如果你有潔癖建議把IConnection也分離開。這樣不容易出錯,就算出錯排錯也會很容易。

(圖1:分開接受和發(fā)送的IConnection、Channel)
還有一點(diǎn),不要將這些對象直接散落在直接使用的Client類中,要建立起一個使用上下文,就算你暴露在外面的是一個具體的類但是那個類也是一個空殼子。
我們可以在創(chuàng)建隊(duì)列的時候設(shè)置此隊(duì)列是持久化的,但是隊(duì)列中的消息要在我們發(fā)送某個消息的時候打上需要持久化的狀態(tài)標(biāo)記。

(圖2:標(biāo)記此消息是需要持久化的)

(圖3:在線程內(nèi)部方法中加try{}catch{})
這個點(diǎn)很多做封裝的人會容易忽視掉,我這里補(bǔ)充下為了保持這個文章的完整性。
其實(shí)在我之前的“.NET應(yīng)用架構(gòu)設(shè)計(jì)—服務(wù)端開發(fā)多線程使用小結(jié)(多線程使用常識)”一文中有講到過。

這個時候你的try{}catch{}其實(shí)是不會捕獲到任何ListenInit方法中的異常的,因?yàn)樗诹硗庖粋€線程上下文中執(zhí)行的。具體原理這里就不解釋了。但是可以很容易的理解就是,你這個方法一旦執(zhí)行就會立馬返回了。

(圖4:監(jiān)聽Shutdown事件,記錄下LOG便于排查和監(jiān)管服務(wù)的穩(wěn)定性)

(圖5:組件內(nèi)部的LOG接口)
此接口就是你內(nèi)部用來將信息傳輸出去的渠道,而且這個渠道是活的,有各個應(yīng)用系統(tǒng)決定怎么記錄。
簡單處理你還需要一個LOG接口服務(wù)定位器對象,要不然你拿不到這個接口實(shí)例。

(圖6:LOG location對象)
如果我們是使用死循環(huán)的方式在接受消息,那么一旦當(dāng)你的接受消息的程序出現(xiàn)異常那么你的while直接就會跳出,你的鏈接可能是還鏈接在服務(wù)器上但是你的channel已經(jīng)斷開,說白了你的消息是不會接受到的,而且這樣的開發(fā)方法很不穩(wěn)定也不優(yōu)雅。我們可以使用面向事件的消費(fèi)者來接受消息。

(圖7:使用Eventing類型的消費(fèi)者接受消息)
默認(rèn)情況下,一個隊(duì)列里不管多少消息當(dāng)你一個TCP連接打上去之后會LOCK住所有的消息,也就是說一個連接徹底占用了所有的消息,此時消息不會被其他集群的機(jī)器消費(fèi)。

(圖8:一次只取一個消息進(jìn)行消費(fèi))
但是如果你對消息的處理的前后順序有要求就不能這么做,你需要獨(dú)立注冊一個隊(duì)列,然后將這樣的一此只消費(fèi)一個消息配置話。

(圖9:創(chuàng)建出一個會自動重連的Connection對象)

(圖10:設(shè)置心跳超時時間)
如果你連接單臺節(jié)點(diǎn)的時候不設(shè)置這個值是沒問題的,但是如果你連接的是類似HAProxy虛擬節(jié)點(diǎn)的時候就會出現(xiàn)TCP被斷開的可能性。如果你不設(shè)置這個心跳超時時間,它默認(rèn)是不進(jìn)行心跳保持的,就會出現(xiàn)網(wǎng)絡(luò)中的某個設(shè)置斷開空閑的TCP連接資源。就這個問題一直搞的我們的團(tuán)隊(duì)到第二天兩點(diǎn)鐘。大家要記住這個點(diǎn)。

(圖11:重新放入隊(duì)列,推送給其他消費(fèi)著)
最后,我是基于Rabbitmq.Client 版本3.5.3.0的基礎(chǔ)上開發(fā)的,這個大家要注意。版本不一樣會有一定的差異性。希望此文對大家在使用rabbitmq的同志有幫助,謝謝。
github:https://github.com/Plen-wang/rabbitmqclient
作者:王清培
出處:http://wangqingpei557.blog.51cto.com/
本文版權(quán)歸作者和51CTO共有,歡迎轉(zhuǎn)載,但未經(jīng)作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責(zé)任的權(quán)利。
本文題目:封裝RabbitMQ.NETLibrary的一點(diǎn)經(jīng)驗(yàn)總結(jié)
網(wǎng)站路徑:http://chinadenli.net/article14/jggige.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供服務(wù)器托管、搜索引擎優(yōu)化、網(wǎng)站內(nèi)鏈、小程序開發(fā)、網(wǎng)站營銷、外貿(mào)建站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)