淺談「領(lǐng)域事件」實(shí)踐

領(lǐng)域事件是DDD歌溉,Event Sourcing等架構(gòu)中的一個重要概念。
基于工作環(huán)境中的一些實(shí)踐經(jīng)驗(yàn)瓶颠,我總結(jié)了一些粗淺的體會拟赊。
文中不會有非常高深復(fù)雜的定義,只使用一些基本的概念粹淋。

領(lǐng)域事件定義

國外書籍中很少使用下定義的方式解釋一個名詞的含義吸祟。一般都會使用作詮釋的方式:“領(lǐng)域事件可以怎樣怎樣”、“領(lǐng)域事件會帶來什么什么”桃移。

讓我來下定義的話:領(lǐng)域事件是微服務(wù)系統(tǒng)中各服務(wù)通信的一種方式屋匕。和RPC類似,領(lǐng)域事件用于在服務(wù)之間交換信息借杰,但領(lǐng)域事件并不追求實(shí)時一致性过吻,僅要求數(shù)據(jù)的最終一致性。

各服務(wù)在一些關(guān)鍵有意義的業(yè)務(wù)節(jié)點(diǎn)完成后會發(fā)送領(lǐng)域事件蔗衡,代表一些關(guān)鍵的動作「已完成」纤虽。因此領(lǐng)域事件的命名多采用過去分詞,例如「訂單已發(fā)送Order sent」「訂單已取消Order canceled」绞惦。

領(lǐng)域事件有多種實(shí)現(xiàn)方式逼纸。我工作中使用到的方式是:將一些關(guān)鍵的、其他服務(wù)可能用到的信息济蝉,打包成一個結(jié)構(gòu)體杰刽,以消息的形式菠发,通過消息隊列中間件,異步傳輸給系統(tǒng)中訂閱該消息的服務(wù)专缠。

領(lǐng)域事件帶來的收益

介紹領(lǐng)域事件的書籍從不吝惜對領(lǐng)域事件優(yōu)點(diǎn)的贊美雷酪。在此我針對各優(yōu)點(diǎn)談?wù)勛约旱母惺堋?/p>

增強(qiáng)服務(wù)自治性

這大概是領(lǐng)域事件最常被提及的優(yōu)點(diǎn)了。何謂“自治性”涝婉?我的理解是:一個服務(wù)只需要關(guān)注自己哥力,不與其他服務(wù)耦合的程度。單體服務(wù)不依賴其他任何服務(wù)墩弯,自治性最高吩跋;如果一個服務(wù)調(diào)用了大量其他服務(wù)的RPC,那么它的穩(wěn)定性和業(yè)務(wù)邏輯必定受其他服務(wù)的影響渔工,自治性稍差锌钮。

為什么能提升自治性愧旦?個人認(rèn)為有以下原因:

首先領(lǐng)域事件一般使用消息隊列實(shí)現(xiàn)墓猎,消息隊列是異步的爆雹,不會阻塞調(diào)用休溶。如果因一時網(wǎng)絡(luò)原因消息無法傳達(dá)宁仔,那么也會由消息組件重試逾条。領(lǐng)域事件可以看做異步的君账、非阻塞的酝惧、由第三方保證最終送達(dá)的RPC区端,可靠性比普通的RPC更高值漫。

另一點(diǎn)就是領(lǐng)域事件不必指定消息的接收方是誰。假設(shè)我們有這樣的業(yè)務(wù)場景织盼,A服務(wù)完成了某一動作后杨何,需要通知B。如果我們使用RPC通信沥邻,后面業(yè)務(wù)擴(kuò)展時增加了C危虱,D服務(wù)需要通知,則實(shí)現(xiàn)時我們需要修改A的代碼谋国,A的業(yè)務(wù)邏輯可能還要受到C槽地,D處理結(jié)果的影響。但是如果我們使用領(lǐng)域事件進(jìn)行通信芦瘾,則在新增C捌蚊,D服務(wù)之后,讓它們訂閱A發(fā)出的事件即可近弟,A服務(wù)完全不需要修改缅糟,不受其他服務(wù)的影響,提升了自治性祷愉。

回放系統(tǒng)動作

如果我們把系統(tǒng)看做一個狀態(tài)機(jī)窗宦,則領(lǐng)域事件可以看做推動狀態(tài)機(jī)轉(zhuǎn)移狀態(tài)的輸入赦颇。領(lǐng)域事件是具有業(yè)務(wù)含義的,回放某一時間段的領(lǐng)域事件可以復(fù)現(xiàn)用戶操作赴涵。通過數(shù)據(jù)庫binlog回放也可以達(dá)到類似的效果媒怯,但binlog是沒有業(yè)務(wù)語義的,回放結(jié)果沒有準(zhǔn)確的解讀方式髓窜。

回放領(lǐng)域事件當(dāng)然需要某種消息存儲/檢索機(jī)制扇苞,這里不做展開。

實(shí)踐領(lǐng)域事件時的一些思考

  • 領(lǐng)域事件實(shí)時性
    領(lǐng)域事件可以保證最終一致性寄纵,但不能保證數(shù)據(jù)實(shí)時性鳖敷。產(chǎn)生的時延是否是業(yè)務(wù)可以接受的?《實(shí)現(xiàn)領(lǐng)域驅(qū)動設(shè)計精粹》中進(jìn)行了一個精妙的類比:在軟件出現(xiàn)前程拭,傳統(tǒng)業(yè)務(wù)的執(zhí)行流程是怎樣的定踱?流程步驟之間是否會有一定的時間差?如果領(lǐng)域事件導(dǎo)致的時延不超過無軟件時業(yè)務(wù)流程的時延恃鞋,那么這時延就是可以接受的崖媚。當(dāng)然,實(shí)際生產(chǎn)環(huán)境中恤浪,說服用戶接受這樣的時延通常不是件容易的事情至扰。

  • 領(lǐng)域事件定義
    領(lǐng)域事件有業(yè)務(wù)語義,這個業(yè)務(wù)語義所代表的動作资锰,必須要有明確的定義。例如:在一個招聘系統(tǒng)中阶祭,目前只有“現(xiàn)場面試簽到”這一個場景绷杜。那么這個動作完成以后,應(yīng)該發(fā)出「面試已簽到」領(lǐng)域事件濒募,還是發(fā)出「現(xiàn)場面試已簽到」的領(lǐng)域事件呢鞭盟?如果是前者,那么后續(xù)新增的其他類型面試簽到瑰剃,也要發(fā)出這個領(lǐng)域事件齿诉。領(lǐng)域事件的業(yè)務(wù)語義必須得到準(zhǔn)確的解釋,從命名開始晌姚。領(lǐng)域事件表示的動作粒度也要在定義前就想好粤剧。

  • 領(lǐng)域事件管理
    目前我們有yAPI這樣優(yōu)秀的接口管理工具,但還沒有合適的領(lǐng)域事件管理工具挥唠。領(lǐng)域事件和接口都是用于通信的手段抵恋,所以他們的含義,包括功能宝磨、每個字段含義等弧关,必須得到準(zhǔn)確的解釋盅安。否則當(dāng)領(lǐng)域事件增加到一定規(guī)模,有人員更迭時世囊,了解各個領(lǐng)域事件將成為惱火的事情别瞭。

  • 向領(lǐng)域事件改造
    EDA是一種時髦的架構(gòu),但并非所有服務(wù)一開始就會選用這種架構(gòu)株憾。一個單純由RPC通信的系統(tǒng)蝙寨,想要轉(zhuǎn)型到通過領(lǐng)域事件通信會遇到很多問題。我們系統(tǒng)遇到的一個現(xiàn)實(shí)問題是:太多的接口可能會發(fā)送同一種領(lǐng)域事件号胚,如果在所有可能的代碼后加上領(lǐng)域事件籽慢,很可能造成遺漏。我們系統(tǒng)對此的解決方案是:將領(lǐng)域事件發(fā)送收斂到數(shù)據(jù)庫上猫胁。業(yè)務(wù)操作箱亿,最終的效果是修改數(shù)據(jù)庫,那么我們就監(jiān)聽相應(yīng)數(shù)據(jù)庫的binglog弃秆,發(fā)出相應(yīng)的領(lǐng)域事件届惋。
    這種解決方案可能會有以下問題:
    首先一個領(lǐng)域事件可能對應(yīng)不只一張表的修改。為了不遺漏領(lǐng)域事件菠赚,我們不得不監(jiān)聽多張表脑豹。每個表修改時,我們都會發(fā)出領(lǐng)域事件衡查,這就導(dǎo)致業(yè)務(wù)上同一個領(lǐng)域事件可能會重復(fù)發(fā)送瘩欺。冪等操作只能交給接收方來做了。
    監(jiān)聽binlog發(fā)送領(lǐng)域事件帶來的另一個改造問題是消息中各字段的準(zhǔn)確性問題拌牲。正常發(fā)送領(lǐng)域事件時俱饿,在業(yè)務(wù)處理的過程中就能獲取領(lǐng)域事件的各個字段。但一張表上可能不會有完整的領(lǐng)域事件信息塌忽,需要反查其他表進(jìn)行字段填充拍埠。某一業(yè)務(wù)操作會修改t1,t2兩張表土居,A枣购,B兩個業(yè)務(wù)操作前后發(fā)生。A操作導(dǎo)致的t1 binlog消息到達(dá)了擦耀,查詢t2表上的字段棉圈,此時t2卻已經(jīng)被B操作修改了,則反查出來的結(jié)果是B操作后的數(shù)據(jù)結(jié)果眷蜓。那么拼裝消息時迄损,部分字段是A導(dǎo)致的,部分字段是B導(dǎo)致的账磺,就會組裝出一個沒有真實(shí)發(fā)生的領(lǐng)域事件芹敌,可能對接收方有影響痊远,具體影響還需要接收方想辦法化解。

  • 領(lǐng)域事件處理
    處理消息逃不開的三個問題:冪等氏捞,重試碧聪,丟失。真實(shí)寫代碼時有太多細(xì)節(jié)需要注意液茎,只能case by case的看了逞姿。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市捆等,隨后出現(xiàn)的幾起案子滞造,更是在濱河造成了極大的恐慌,老刑警劉巖栋烤,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件谒养,死亡現(xiàn)場離奇詭異,居然都是意外死亡明郭,警方通過查閱死者的電腦和手機(jī)买窟,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來薯定,“玉大人始绍,你說我怎么就攤上這事』爸叮” “怎么了亏推?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長年堆。 經(jīng)常有香客問我径簿,道長,這世上最難降的妖魔是什么嘀韧? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮缠捌,結(jié)果婚禮上锄贷,老公的妹妹穿的比我還像新娘。我一直安慰自己曼月,他們只是感情好谊却,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著哑芹,像睡著了一般炎辨。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上聪姿,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天碴萧,我揣著相機(jī)與錄音乙嘀,去河邊找鬼。 笑死破喻,一個胖子當(dāng)著我的面吹牛虎谢,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播曹质,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼婴噩,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了羽德?” 一聲冷哼從身側(cè)響起几莽,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎宅静,沒想到半個月后章蚣,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡坏为,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年究驴,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片匀伏。...
    茶點(diǎn)故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡洒忧,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出够颠,到底是詐尸還是另有隱情熙侍,我是刑警寧澤,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布履磨,位于F島的核電站蛉抓,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏剃诅。R本人自食惡果不足惜巷送,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望矛辕。 院中可真熱鬧笑跛,春花似錦、人聲如沸聊品。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽翻屈。三九已至陈哑,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背惊窖。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工刽宪, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人爬坑。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓纠屋,卻偏偏與公主長得像,于是被迫代替她去往敵國和親盾计。 傳聞我的和親對象是個殘疾皇子售担,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評論 2 353

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