Lind.DDD.LindMQ的(de)一(yi)些想法
很久(jiu)就想寫(xie)一(yi)(yi)套(tao)屬于自己的消(xiao)息隊列(lie)組(zu)件(jian),前(qian)段(duan)時候看了湯雪華同(tong)學的EQueue,感覺還是(shi)(shi)不錯的,他(ta)也是(shi)(shi)看了rabbitMQ之后寫(xie)的Equeue,在設計上與前(qian)者(zhe)有類似(si)的地方,而(er)大叔(shu)這(zhe)(zhe)次準備寫(xie)一(yi)(yi)個LindMQ,當前(qian)整體(ti)架構都(dou)差不多,無非是(shi)(shi)生(sheng)產者(zhe),管(guan)道,消(xiao)費者(zhe)三個角(jiao)色,而(er)核心部分就是(shi)(shi)管(guan)道Broker這(zhe)(zhe)個東(dong)西了,為(wei)生(sheng)產者(zhe)提供(gong)(gong)了push操(cao)(cao)作;而(er)為(wei)消(xiao)費者(zhe)又(you)提供(gong)(gong)了Pull操(cao)(cao)作;為(wei)了解耦考慮,他(ta)們之前(qian)沒有直接(jie)的引用關系,通訊采(cai)用tcp的方式,Broken的消(xiao)息存儲(chu)介質我(wo)(wo)們使用redis,生(sheng)產者(zhe)和(he)消(xiao)費者(zhe)與Broker的通訊我(wo)(wo)們采(cai)用FastSocket這(zhe)(zhe)個組(zu)件(jian)。
LindMQ設計架構圖
關于MQ系統的三大對象
以下(xia)三大對象(xiang)其實都有(you)各(ge)自的實現(xian),各(ge)自的平臺,各(ge)自也都需要(yao)一個(ge)宿主!
Producer
生(sheng)產者,用來(lai)將消(xiao)息(xi)(xi)從源(yuan)平臺發送到(dao)目標隊列(lie)中,目標隊列(lie)用到(dao)存(cun)儲(chu)消(xiao)息(xi)(xi),這里一般(ban)指Broker,它(ta)(ta)可以(yi)是(shi)一種集群環境,它(ta)(ta)會封(feng)裝(zhuang)對存(cun)儲(chu)消(xiao)息(xi)(xi)介(jie)質(zhi)的(de)入隊與(yu)出隊的(de)基本(ben)操作,而對于真實的(de)存(cun)儲(chu)介(jie)質(zhi),生(sheng)產者是(shi)不需要知(zhi)道的(de)!
Broker
消(xiao)息(xi)(xi)處理者,用來處理消(xiao)息(xi)(xi),加工消(xiao)息(xi)(xi),存儲(chu)消(xiao)息(xi)(xi)等,它會公開基本的推消(xiao)息(xi)(xi)接(jie)口(kou)和拉消(xiao)息(xi)(xi)接(jie)口(kou)!
Consumer
消(xiao)費(fei)者,用來處理(li)Broker里(li)的消(xiao)息,它一般通(tong)過(guo)長連接,定(ding)時(shi)向Broker里(li)拉消(xiao)息的方法實現,基于實時(shi)性考慮,又出現了pub/sub這種發(fa)布與訂(ding)(ding)閱模(mo)式,當(dang)消(xiao)費(fei)方訂(ding)(ding)閱了某種消(xiao)息主題(topic)之后,有這種消(xiao)息產生時(shi),broker會把消(xiao)息自動推到消(xiao)息方!
關于消息的上下文
消(xiao)(xiao)息上下(xia)文(wen),我們可以把它(ta)看成是承載消(xiao)(xiao)息的(de)對象,它(ta)會有topic主題(ti),queueId消(xiao)(xiao)息隊列索引,queueOffset內(nei)容索引,body消(xiao)(xiao)息體組成,它(ta)相關于是producer,broker和consumer之間定(ding)義的(de)一種(zhong)數據協(xie)(xie)議(yi),他們之間通訊使用這種(zhong)公開的(de)協(xie)(xie)議(yi),在LinqQueue里面消(xiao)(xiao)息協(xie)(xie)議(yi)我們稱為LindMQ,下(xia)面看一下(xia)協(xie)(xie)議(yi)的(de)內(nei)容
/// <summary> /// 消息(xi)協議 /// </summary> [Serializable] public class LindMQ { /// <summary> /// 消息(xi)所屬(shu)Topic,每(mei)種Topic有(you)一種類型的Body /// </summary> public string Topic { get; set; } /// <summary> /// 消息內容,Redis里存儲為(wei)Json /// </summary> public string Body { get; set; } /// <summary> /// 消息所(suo)屬(shu)的(de)隊(dui)列(lie)ID /// </summary> public int QueueId { get; internal set; } /// <summary> /// 消息在所屬隊(dui)列(lie)的(de)序(xu)號 /// </summary> public long QueueOffset { get; internal set; } /// <summary> /// 消息的(de)存儲時間 /// </summary> internal DateTime CreateTime { get; set; } /// <summary> /// 將消息對象序列化成字符 /// </summary> /// <returns></returns> public override string ToString() { return Utils.SerializeMemoryHelper.SerializeToJson<LindMQ>(this); } }
通過上面代碼我們可以看到,Topic,QueueId,QueueOffset,Body等字段,這也是一個消息協議也需要的主要信息了,Topic是消息主題,我們可以這樣認為,一種主題就是一類消息,QueueId它位于(yu)Topic消息主題下面,一個topic可以包括多個queue,而QueueOffset是每個queue里的消息索(suo)引,類似(si)你的(de)消(xiao)息(xi)在(zai)消(xiao)息(xi)隊列里排在(zai)第幾位(wei);而body就是我(wo)們(men)的(de)消(xiao)息(xi)體了,它(ta)使(shi)用二時制流表示,這樣有(you)利于網絡(luo)傳輸!
好(hao)了,今天主要是對LinqQueue做一個簡單的介(jie)紹,下次我再繼續介(jie)紹LindQueue!