封裝RabbitMQ.NETLibrary的一點(diǎn)經(jīng)驗(yàn)總結(jié)-創(chuàng)新互聯(lián)

這篇文章內(nèi)容會(huì)很短,主要是想給大家分享下我最近在做一個(gè)簡(jiǎn)單的rabbitmq客戶端類庫(kù)的封裝的經(jīng)驗(yàn)總結(jié),說(shuō)是簡(jiǎn)單其實(shí)一點(diǎn)都不簡(jiǎn)單。為了節(jié)省時(shí)間我主要按照Library的執(zhí)行順序來(lái)介紹,在你看來(lái)這里僅僅是一個(gè)簡(jiǎn)單的經(jīng)驗(yàn)總結(jié),但是在我看來(lái)這些經(jīng)驗(yàn)只有在你真正的封裝rabbitmq客戶端庫(kù)的時(shí)候且將你的客戶端安全穩(wěn)定的發(fā)布上線后才會(huì)真的發(fā)現(xiàn)這些問(wèn)題。

站在用戶的角度思考問(wèn)題,與客戶深入溝通,找到佳木斯網(wǎng)站設(shè)計(jì)與佳木斯網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗(yàn),讓設(shè)計(jì)與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個(gè)性化、用戶體驗(yàn)好的作品,建站類型包括:網(wǎng)站建設(shè)、做網(wǎng)站、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣、域名與空間、網(wǎng)站空間、企業(yè)郵箱。業(yè)務(wù)覆蓋佳木斯地區(qū)。

比如你的庫(kù)只是鏈接單個(gè)Node的時(shí)候和鏈接高可用集群的HAProxy時(shí)候是完全兩回事。當(dāng)你未能在你的庫(kù)里使用反向注入LOG接口的時(shí)候一旦在線上發(fā)生網(wǎng)絡(luò)解析和序列化等一系列在線問(wèn)題時(shí)候你是多么無(wú)能為力。當(dāng)你使用同步循環(huán)獲取隊(duì)列消息的時(shí)候一旦發(fā)生異常你的鏈接就會(huì)斷掉等等這些細(xì)節(jié)。我總結(jié)了我在編寫(xiě)這個(gè)library的時(shí)候慢慢穩(wěn)定下來(lái)的過(guò)程和經(jīng)驗(yàn)。至少目前來(lái)看網(wǎng)絡(luò)上的文章,當(dāng)然我是指.NET/C#方面的,都沒(méi)有講到這些問(wèn)題,大部分的文章都是簡(jiǎn)單的介紹了一個(gè)最最基本的使用和最最基本的demo而已,達(dá)不到企業(yè)級(jí)使用的要求。在這個(gè)過(guò)程中,感謝我的團(tuán)隊(duì)和給過(guò)我指導(dǎo)的同事,讓我明白了一些技術(shù)道理。

好東西不能石沉大海,尤其是.NET領(lǐng)域更需要這樣的東西來(lái)填補(bǔ)這一空缺。廢話不多說(shuō)了,進(jìn)入主題,那些編寫(xiě)框架和組件的大道理這里就不講了,我只說(shuō)重點(diǎn)。

1.發(fā)送鏈接、通道和接受鏈接、通道要關(guān)注點(diǎn)分離

就是說(shuō)你的接受Channel和發(fā)送的Channel要分離開(kāi),如果不分開(kāi)會(huì)出現(xiàn)偶發(fā)性的消息串掉的錯(cuò)誤,我這里現(xiàn)在沒(méi)有環(huán)境無(wú)法重現(xiàn)截圖。我是在做壓力測(cè)試的時(shí)候,用了一個(gè)Channel的時(shí)候Debug拋出來(lái)的異常。如果你有潔癖建議把IConnection也分離開(kāi)。這樣不容易出錯(cuò),就算出錯(cuò)排錯(cuò)也會(huì)很容易。

封裝RabbitMQ.NET Library 的一點(diǎn)經(jīng)驗(yàn)總結(jié)

(圖1:分開(kāi)接受和發(fā)送的IConnection、Channel)

還有一點(diǎn),不要將這些對(duì)象直接散落在直接使用的Client類中,要建立起一個(gè)使用上下文,就算你暴露在外面的是一個(gè)具體的類但是那個(gè)類也是一個(gè)空殼子。

2.客戶端發(fā)送消息的時(shí)候要標(biāo)記上消息的持久化狀態(tài)

我們可以在創(chuàng)建隊(duì)列的時(shí)候設(shè)置此隊(duì)列是持久化的,但是隊(duì)列中的消息要在我們發(fā)送某個(gè)消息的時(shí)候打上需要持久化的狀態(tài)標(biāo)記。

封裝RabbitMQ.NET Library 的一點(diǎn)經(jīng)驗(yàn)總結(jié)

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

3.要在監(jiān)聽(tīng)的線程入口后加try{}catch{}

封裝RabbitMQ.NET Library 的一點(diǎn)經(jīng)驗(yàn)總結(jié)

(圖3:在線程內(nèi)部方法中加try{}catch{})

這個(gè)點(diǎn)很多做封裝的人會(huì)容易忽視掉,我這里補(bǔ)充下為了保持這個(gè)文章的完整性。

其實(shí)在我之前的“.NET應(yīng)用架構(gòu)設(shè)計(jì)—服務(wù)端開(kāi)發(fā)多線程使用小結(jié)(多線程使用常識(shí))”一文中有講到過(guò)。

封裝RabbitMQ.NET Library 的一點(diǎn)經(jīng)驗(yàn)總結(jié)

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

4. 初始化的監(jiān)聽(tīng)連接的時(shí)候要訂閱Shutdown事件記錄下LOG

封裝RabbitMQ.NET Library 的一點(diǎn)經(jīng)驗(yàn)總結(jié)

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

5. 要在內(nèi)部定義一個(gè)LOG反向注入接口

封裝RabbitMQ.NET Library 的一點(diǎn)經(jīng)驗(yàn)總結(jié)

(圖5:組件內(nèi)部的LOG接口)

此接口就是你內(nèi)部用來(lái)將信息傳輸出去的渠道,而且這個(gè)渠道是活的,有各個(gè)應(yīng)用系統(tǒng)決定怎么記錄。

簡(jiǎn)單處理你還需要一個(gè)LOG接口服務(wù)定位器對(duì)象,要不然你拿不到這個(gè)接口實(shí)例。

封裝RabbitMQ.NET Library 的一點(diǎn)經(jīng)驗(yàn)總結(jié)

(圖6:LOG location對(duì)象)

6. 千萬(wàn)不要使用while(true)接受消息

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

封裝RabbitMQ.NET Library 的一點(diǎn)經(jīng)驗(yàn)總結(jié)

(圖7:使用Eventing類型的消費(fèi)者接受消息)

7.設(shè)置一次只接受一個(gè)消息,而不是直接LOCK住所有的隊(duì)列消息

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

封裝RabbitMQ.NET Library 的一點(diǎn)經(jīng)驗(yàn)總結(jié)

(圖8:一次只取一個(gè)消息進(jìn)行消費(fèi))

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

8.自動(dòng)重新連接,不需要手動(dòng)處理自動(dòng)連接

封裝RabbitMQ.NET Library 的一點(diǎn)經(jīng)驗(yàn)總結(jié)

(圖9:創(chuàng)建出一個(gè)會(huì)自動(dòng)重連的Connection對(duì)象)

9.心跳超時(shí)時(shí)間(集群、高可用部署時(shí)至關(guān)重要的設(shè)置)

封裝RabbitMQ.NET Library 的一點(diǎn)經(jīng)驗(yàn)總結(jié)

(圖10:設(shè)置心跳超時(shí)時(shí)間)

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

10.消費(fèi)失敗的消息要重新放入隊(duì)列

封裝RabbitMQ.NET Library 的一點(diǎn)經(jīng)驗(yàn)總結(jié)

(圖11:重新放入隊(duì)列,推送給其他消費(fèi)著)

總結(jié):

最后,我是基于Rabbitmq.Client 版本3.5.3.0的基礎(chǔ)上開(kāi)發(fā)的,這個(gè)大家要注意。版本不一樣會(huì)有一定的差異性。希望此文對(duì)大家在使用rabbitmq的同志有幫助,謝謝。

github:https://github.com/Plen-wang/rabbitmqclient

作者:王清培

出處:http://wangqingpei557.blog.51cto.com/

本文版權(quán)歸作者和51CTO共有,歡迎轉(zhuǎn)載,但未經(jīng)作者同意必須保留此段聲明,且在文章頁(yè)面明顯位置給出原文連接,否則保留追究法律責(zé)任的權(quán)利。

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無(wú)理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。

當(dāng)前題目:封裝RabbitMQ.NETLibrary的一點(diǎn)經(jīng)驗(yàn)總結(jié)-創(chuàng)新互聯(lián)
分享鏈接:http://muchs.cn/article30/dphgso.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供微信小程序Google、網(wǎng)站制作網(wǎng)站設(shè)計(jì)、網(wǎng)站收錄、動(dòng)態(tài)網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都app開(kāi)發(fā)公司