微服務(wù)實戰(zhàn)(二):落地微服務(wù)架構(gòu)到直銷系統(tǒng)(構(gòu)建消息總線框架接口)

微服務(wù)實戰(zhàn)(二):落地微服務(wù)架構(gòu)到直銷系統(tǒng)(構(gòu)建消息總線框架接口)

從上一篇文章大家可以看出,實現(xiàn)一個自己的消息總線框架是非常重要的內(nèi)容住拭,消息總線可以將界限上下文之間進行解耦坦冠,也可以為大并發(fā)訪問提供必要的支持。

消息總線的作用:

1.界限上下文解耦:在DDD第一波文章中,當更新了訂單信息后耍休,我們通過調(diào)用經(jīng)銷商界限上下文的領(lǐng)域模型和倉儲辱匿,進行了經(jīng)銷商信息的更新键痛,這造成了耦合。通過一個消息總線匾七,可以在訂單界限上下文的WebApi服務(wù)(來源微服務(wù)-生產(chǎn)者)更新了訂單信息后絮短,發(fā)布一個事件消息到消息總線的某個隊列中,經(jīng)銷商界限上下文的WebApi服務(wù)(消費者)訂閱這個事件消息昨忆,然后交給自己的Handler進行消息處理丁频,更新自己的經(jīng)銷商信息。這樣就實現(xiàn)了訂單界限上下文與經(jīng)銷商界限上下文解耦邑贴。

2.大并發(fā)支持:可以通過消息總線進一步提升下單的性能席里。我們可以將用戶下單的操作直接交給一個下單命令WebApi接收,下單命令WebApi接收到命令后拢驾,直接丟給一個消息總線的隊列奖磁,然后立即給前端返回下單結(jié)果掠哥。這樣用戶就不用等待后續(xù)的復雜訂單業(yè)務(wù)邏輯奖唯,加快速度。后續(xù)訂單的一系列處理交給消息的Handler進行后續(xù)的處理與消息的進一步投遞趁舀。


消息總線設(shè)計重點:

1.定義消息(事件)的接口:所有需要投遞與處理的消息嵌洼,都從這個消息接口繼承案疲,因為需要約束消息中必須包含的內(nèi)容,比如消息的ID麻养、消息產(chǎn)生的時間等褐啡。

publicinterface IEvent

? ? {

? ? ? ? Guid Id { get;set; }

? ? ? ? DateTime CreateDate { get;set; }

? ? }

2.定義消息(事件)處理器接口:當消息投遞到消息總線隊列中后,一定有消費者WebApi接收并處理這個消息鳖昌,具體的處理方法邏輯在訂閱方處理器中實現(xiàn)备畦,這里先需要定義處理器的接口低飒,便于在消息總線框架中使用。

publicinterface IEventHandler

? ? {

? ? ? ? Task HandleAsync(TEvent @event)where TEvent : IEvent;

? ? }

從上面代碼可以看出懂盐,消息(事件)處理器處理的類型就是從IEvent接口繼承的消息類褥赊。

3.定義消息(事件)與消息(事件)處理器關(guān)聯(lián)接口:一種類型的消息被投遞后,一定要在訂閱方找到這種消息的處理器進行處理莉恼,所以一定要定義二者的關(guān)聯(lián)接口拌喉,這樣才能將消息與消息處理器對應(yīng)起來,才能實現(xiàn)消息被訂閱后的處理俐银。

publicinterface IEventHandlerExecutionContext

? ? {

? ? ? ? voidRegisterEventHandler()where TEvent : IEvent

? ? ? ? ? ? where TEventHandler : IEventHandler;

? ? ? ? boolIsRegisterEventHandler()where TEvent : IEvent

? ? ? ? ? ? where TEventHandler : IEventHandler;

? ? ? ? Task HandleAsync(TEvent @event)where TEvent : IEvent;

? ? }

RegisterEventHandler方法就是建立消息與消息處理器的關(guān)聯(lián)尿背,這個方法其實是在訂閱方使用,訂閱方告訴消息總線捶惜,什么樣的消息應(yīng)該交給我的哪個處理器進行處理田藐。

IsRegisterEventHandler方法是判斷消息與處理器之間是否已經(jīng)存在關(guān)聯(lián)。

HandleAsync方法是通過查找到消息對應(yīng)的處理器后吱七,然后調(diào)用處理器自己的Handle方法進行消息的處理.

4.定義消息發(fā)布汽久、訂閱與消息總線接口:消息總線至少要支持兩個功能,一個是生產(chǎn)者能夠發(fā)布消息到我的消息總線陪捷,另一個是訂閱方需要能夠從我這個消息總線訂閱消息回窘。

publicinterface IEventPublisher

? ? {

? ? ? ? voidPublish(TEvent @event)where TEvent : IEvent;

? ? }

從上面代碼可以看出诺擅,生產(chǎn)者發(fā)布的消息仍然要從IEvent繼承的類型市袖。

publicinterface IEventSubscriber

? ? {

? ? ? ? voidSubscribe()where TEvent : IEvent

? ? ? ? ? ? where TEventHandler : IEventHandler;

? ? }

上面代碼是訂閱方用于從消息總線訂閱消息,從代碼中可以看出烁涌,它的最終的實現(xiàn)其實就是建立消息與處理器之間的關(guān)聯(lián)苍碟。

publicinterface IEventBus:IEventPublisher,IEventSubscriber

? ? {

? ? }

消息(事件)總線從兩個接口繼承下來,同時支持消息的發(fā)布與消息的訂閱撮执。

5.實現(xiàn)事件基類:上面已經(jīng)訂閱了消息(事件)的接口微峰,這里來實現(xiàn)事件的基類,其實就是實現(xiàn)消息ID與產(chǎn)生的時間:

publicclass BaseEvent : IEvent

? ? {

? ? ? ? publicGuid Id {get;set; }

? ? ? ? publicDateTime CreateDate {get;set; }

? ? ? ? public BaseEvent()

? ? ? ? {

? ? ? ? ? ? this.Id = Guid.NewGuid();

? ? ? ? ? ? this.CreateDate = DateTime.Now;

? ? ? ? }

? ? }

6.實現(xiàn)消息總線基類:消息總線底層的依賴可以是各種消息代理產(chǎn)品抒钱,比如RabbitMq蜓肆、Kafaka或第三方云平臺提供的消息代理產(chǎn)品,通常我們要封裝這些消息代理產(chǎn)品谋币。在封裝之前仗扬,我們需要定義頂層的消息總線基類實現(xiàn),主要的目的是未來依賴于它的具體實現(xiàn)可替換蕾额,另外也將消息與消息處理器的關(guān)聯(lián)接口傳遞進來早芭,便于訂閱方使用。

publicabstractclass BaseEventBus : IEventBus

? ? {

? ? ? ? protectedreadonly IEventHandlerExecutionContext eventHandlerExecutionContext;

? ? ? ? protected BaseEventBus(IEventHandlerExecutionContext eventHandlerExecutionContext)

? ? ? ? {

? ? ? ? ? ? this.eventHandlerExecutionContext = eventHandlerExecutionContext;

? ? ? ? }

? ? ? ? publicabstractvoidPublish(TEvent @event)

? ? ? ? ? ? where TEvent : IEvent;

? ? ? ? publicabstractvoidSubscribe()

? ? ? ? ? ? where TEvent : IEvent

? ? ? ? ? ? where TEventHandler : IEventHandler;

? ? }

7.實現(xiàn)消息與處理器關(guān)聯(lián):消息必須與處理器關(guān)聯(lián)诅蝶,訂閱方收到特定類型的消息后退个,才知道交給哪個處理器處理募壕。

publicclass EventHandlerExecutionContext : IEventHandlerExecutionContext

? ? {

? ? ? ? privatereadonly IServiceCollection registry;

? ? ? ? privatereadonly IServiceProvider serviceprovider;

? ? ? ? privateDictionary> registrations =newDictionary>();

? ? ? ? publicEventHandlerExecutionContext(IServiceCollection registry,Func

? ? ? ? ? ? IServiceProvider> serviceProviderFactory =null)

? ? ? ? {

? ? ? ? ? ? this.registry = registry;

? ? ? ? ? ? this.serviceprovider =this.registry.BuildServiceProvider();

? ? ? ? }

? ? ? //查找消息關(guān)聯(lián)的處理器,然后調(diào)用處理器的處理方法publicasyncTask HandleAsync(TEvent @event)where TEvent : IEvent

? ? ? ? {

? ? ? ? ? ? vareventtype = @event.GetType();

? ? ? ? ? ? if(registrations.TryGetValue(eventtype,outList handlertypes) && handlertypes.Count >0)

? ? ? ? ? ? {

? ? ? ? ? ? ? ? using(varchildscope =this.serviceprovider.CreateScope())

? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? foreach(varhandlertypein handlertypes)

? ? ? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? ? ? varhandler = Activator.CreateInstance(handlertype)as IEventHandler;

? ? ? ? ? ? ? ? ? ? ? ? await handler.HandleAsync(@event);

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }

? ? ? ? }

? ? ? //判斷消息與處理器之間是否有關(guān)聯(lián)publicboolIsRegisterEventHandler()

? ? ? ? ? ? where TEvent : IEvent

? ? ? ? ? ? where TEventHandler : IEventHandler

? ? ? ? {

? ? ? ? ? ? if(registrations.TryGetValue(typeof(TEvent),outList handlertypelist))

? ? ? ? ? ? {

? ? ? ? ? ? ? ? returnhandlertypelist !=null&& handlertypelist.Contains(typeof(IEventHandler));

? ? ? ? ? ? }

? ? ? ? ? ? returnfalse;

? ? ? ? }


? ? ? //將消息與處理器關(guān)聯(lián)起來语盈,可以在內(nèi)存中建立關(guān)聯(lián)舱馅,也可以建立在數(shù)據(jù)庫單獨表中publicvoidRegisterEventHandler()

? ? ? ? ? ? where TEvent : IEvent

? ? ? ? ? ? where TEventHandler : IEventHandler

? ? ? ? {

? ? ? ? ? ? Utils.DictionaryRegister(typeof(TEvent),typeof(TEventHandler), registrations);

? ? ? ? }

? ? }

上面我們基本上就將消息總線的架子搭建起來了,也實現(xiàn)了基本的功能刀荒,下一章我們基于它來實現(xiàn)RabbitMq的消息總線习柠。

QQ討論群:309287205?

微服務(wù)實戰(zhàn)視頻請關(guān)注微信公眾號:MSSHCJ

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市照棋,隨后出現(xiàn)的幾起案子资溃,更是在濱河造成了極大的恐慌,老刑警劉巖烈炭,帶你破解...
    沈念sama閱讀 219,188評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件溶锭,死亡現(xiàn)場離奇詭異,居然都是意外死亡符隙,警方通過查閱死者的電腦和手機趴捅,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來霹疫,“玉大人拱绑,你說我怎么就攤上這事±鲂” “怎么了猎拨?”我有些...
    開封第一講書人閱讀 165,562評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長屠阻。 經(jīng)常有香客問我红省,道長,這世上最難降的妖魔是什么国觉? 我笑而不...
    開封第一講書人閱讀 58,893評論 1 295
  • 正文 為了忘掉前任吧恃,我火速辦了婚禮,結(jié)果婚禮上麻诀,老公的妹妹穿的比我還像新娘痕寓。我一直安慰自己,他們只是感情好蝇闭,可當我...
    茶點故事閱讀 67,917評論 6 392
  • 文/花漫 我一把揭開白布呻率。 她就那樣靜靜地躺著,像睡著了一般丁眼。 火紅的嫁衣襯著肌膚如雪筷凤。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,708評論 1 305
  • 那天,我揣著相機與錄音藐守,去河邊找鬼挪丢。 笑死,一個胖子當著我的面吹牛卢厂,可吹牛的內(nèi)容都是我干的乾蓬。 我是一名探鬼主播,決...
    沈念sama閱讀 40,430評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼慎恒,長吁一口氣:“原來是場噩夢啊……” “哼任内!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起融柬,我...
    開封第一講書人閱讀 39,342評論 0 276
  • 序言:老撾萬榮一對情侶失蹤死嗦,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后粒氧,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體越除,經(jīng)...
    沈念sama閱讀 45,801評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,976評論 3 337
  • 正文 我和宋清朗相戀三年外盯,在試婚紗的時候發(fā)現(xiàn)自己被綠了摘盆。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,115評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡饱苟,死狀恐怖孩擂,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情箱熬,我是刑警寧澤类垦,帶...
    沈念sama閱讀 35,804評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站坦弟,受9級特大地震影響护锤,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜酿傍,卻給世界環(huán)境...
    茶點故事閱讀 41,458評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望驱入。 院中可真熱鬧赤炒,春花似錦、人聲如沸亏较。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽雪情。三九已至遵岩,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背尘执。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評論 1 272
  • 我被黑心中介騙來泰國打工舍哄, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人誊锭。 一個月前我還...
    沈念sama閱讀 48,365評論 3 373
  • 正文 我出身青樓表悬,卻偏偏與公主長得像,于是被迫代替她去往敵國和親丧靡。 傳聞我的和親對象是個殘疾皇子蟆沫,可洞房花燭夜當晚...
    茶點故事閱讀 45,055評論 2 355

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)温治,斷路器饭庞,智...
    卡卡羅2017閱讀 134,665評論 18 139
  • 關(guān)于Mongodb的全面總結(jié) MongoDB的內(nèi)部構(gòu)造《MongoDB The Definitive Guide》...
    中v中閱讀 31,938評論 2 89
  • 一、apache環(huán)境安裝 正常安裝軟件步驟熬荆,到下圖時需要注意但绕。訪問http://localhost/顯示 It w...
    殘燈古夢閱讀 113評論 0 1
  • 半夜醒來捏顺,似乎再難入睡。雙11纬黎,8本書158.6元幅骄。漸已適應(yīng)居家的生活,或者前綴“被”本今。 “曾夢想仗劍走天涯拆座,看一...
    希冀SKY閱讀 141評論 0 0
  • 攝于2018.4.25 地點南寧萬芊民宿 微博@烘焙攝影肥仔雲(yún) 前期準備 當時打算在南寧玩兩天,去試試海底撈和烏布...
    肥仔雲(yún)閱讀 556評論 0 3