架構(gòu)設(shè)計(jì)30-架構(gòu)模式07-命令查詢(xún)指責(zé)分離模式

架構(gòu)設(shè)計(jì)系列文章,請(qǐng)參見(jiàn)連接剩檀。

介紹

命令查詢(xún)責(zé)任分離源于Bertrand Mayer設(shè)計(jì)的命令查詢(xún)分離(CQS)原理。CQS聲明一個(gè)類(lèi)只能有兩種方法:改變狀態(tài)并返回void的方法和返回狀態(tài)但不改變它的方法坏逢。后來(lái)經(jīng)過(guò)Greg Young的發(fā)展與推廣最終形成了現(xiàn)在的CQRS。

講解

命令查詢(xún)的責(zé)任分離(Command Query Responsibility Segregation痒谴,簡(jiǎn)稱(chēng)CQRS)模式包含著兩部分:能夠使改變模型的狀態(tài)的命令和模型狀態(tài)的查詢(xún)。CQRS是DDD應(yīng)用領(lǐng)域的一個(gè)模式铡羡,主要解決DDD在數(shù)據(jù)庫(kù)報(bào)表輸出上處理方式积蔚。

在DDD架構(gòu)中,通常會(huì)將查詢(xún)和命令操作分開(kāi)蓖墅,具體落地時(shí)库倘,是否將查詢(xún)和命令分開(kāi)成為兩個(gè)項(xiàng)目可以視情況而定,大多數(shù)情況下放在一個(gè)項(xiàng)目可以提高業(yè)務(wù)內(nèi)聚性论矾。也可以在邏輯層面上劃分為兩個(gè)不同的操作模型(Command和Query)但是在物理層面上還是使用同一個(gè)數(shù)據(jù)庫(kù)進(jìn)行。

對(duì)于CQRS來(lái)說(shuō)最主要的是改變狀態(tài)和獲取狀態(tài)的兩類(lèi)操作杆勇,只要將這兩類(lèi)動(dòng)作分離的都可以稱(chēng)作是CQRS贪壳。這樣拆離之后對(duì)于查詢(xún)DTO和命令DTO就也可以分離出來(lái)。大多數(shù)時(shí)候蚜退,改變狀態(tài)所需的數(shù)據(jù)在形式或數(shù)量上都不同于用戶(hù)需要查詢(xún)所需的數(shù)據(jù)闰靴。使用相同的模型來(lái)一起處理查詢(xún)和命令會(huì)會(huì)導(dǎo)致模型膨脹,只依靠一種類(lèi)型來(lái)操作所需的所有東西钻注,模型復(fù)雜性也會(huì)增加蚂且,聚合大小通常會(huì)更大。

模式描述

對(duì)于命令查詢(xún)職責(zé)分離模式可以有兩種變種模式:CQRS幅恋,CQRS/ES杏死。CQRS是對(duì)命令和查詢(xún)使用不同的服務(wù)器。而CQRS/ES是使用溯源事件的方式將用戶(hù)命令發(fā)送到讀數(shù)據(jù)庫(kù)中捆交。Event Sourcing是由Martin Fowler提出淑翼,是將業(yè)務(wù)領(lǐng)域精髓(尤其是最復(fù)雜的)與技術(shù)平臺(tái)的復(fù)雜性實(shí)現(xiàn)脫鉤的天作之合。為什么要用Event Sourcing?Domain Events – 救世主

CQRS

在這兩種模式的選擇中也分為有兩個(gè)陣營(yíng):一個(gè)說(shuō)你應(yīng)該總是使用CQRS / ES品追,另一個(gè)說(shuō)你應(yīng)該只使用你的解決方案的一部分玄括,并且只有當(dāng)你需要具有高性能/可用性/可擴(kuò)展性系統(tǒng)的高度并發(fā)系統(tǒng)時(shí)。您應(yīng)該始終根據(jù)您的要求評(píng)估您的選擇肉瓦。

CQRS使我們能夠使用不同的模型來(lái)改變狀態(tài)和不同的模型來(lái)支持查詢(xún)遭京。通常寫(xiě)操作的頻率低于讀操作。 具有單獨(dú)的模型和分離的數(shù)據(jù)庫(kù)引擎允許我們獨(dú)立地?cái)U(kuò)展查詢(xún)端并更好地處理并發(fā)訪(fǎng)問(wèn)泞莉,因?yàn)樽x取端不再堵塞寫(xiě)入或命令端(在相反的情況下)哪雕。

對(duì)于讀寫(xiě)數(shù)據(jù)庫(kù)數(shù)據(jù)結(jié)構(gòu)不一致或純粹不一致的數(shù)據(jù)庫(kù)的情況下,可以通過(guò)Event Sourcing的方式進(jìn)行支撐戒财。并且Event Sourcing的方式還可以進(jìn)行消息記錄热监。

特點(diǎn)

  • 開(kāi)發(fā)

  • 過(guò)程管理(康威定律)
    CQRS/ES增加了平臺(tái)的復(fù)雜度。需要在實(shí)施過(guò)程中以過(guò)程的方法解決復(fù)雜度增加造成的問(wèn)題饮寞。

  • 可測(cè)試性
    CQRS/ES的測(cè)試點(diǎn)較多孝扛。并且因?yàn)閺?fù)雜的增加可能會(huì)造成測(cè)試過(guò)程中問(wèn)題反復(fù)列吼。

  • 可擴(kuò)展性
    CQRS/ES最主要的目標(biāo)就是為了高性能/可用性/可擴(kuò)展性系統(tǒng)而設(shè)計(jì)的。所以對(duì)于可擴(kuò)展性的支持較好苦始。

  • 運(yùn)維

  • 可伸縮
    CQRS/ES最主要的目標(biāo)就是為了高性能/可用性/可擴(kuò)展性系統(tǒng)而設(shè)計(jì)的寞钥。所以對(duì)于可伸縮性的支持較好。

  • 部署難易
    CQRS/ES系統(tǒng)中涉及到多服務(wù)部署的問(wèn)題陌选,需要在上線(xiàn)時(shí)進(jìn)行配置理郑。

  • 維護(hù)難易
    穩(wěn)定性尚可,但是可跟蹤性比較弱咨油。所以維護(hù)難度比較高您炉。

  • 性能

CQRS/ES最主要的目標(biāo)就是為了高性能/可用性/可擴(kuò)展性系統(tǒng)而設(shè)計(jì)的。所以對(duì)于性能的支持較好役电。

總結(jié):

在互聯(lián)網(wǎng)高并發(fā)的情況下經(jīng)常使用CQRS架構(gòu)作為整體架構(gòu)赚爵,然后再在CQRS內(nèi)部使用其他的架構(gòu)模式配合形成一套完整的架構(gòu)。幫我們解決了很多關(guān)于性能法瑟、穩(wěn)定性冀膝、數(shù)據(jù)拆分的問(wèn)題。對(duì)于CQRS的特點(diǎn)可以總結(jié)為將用戶(hù)操作與頁(yè)面展示分離霎挟,可以使用靜態(tài)化窝剖、緩存的方式解決讀速度的問(wèn)題。所以在CQRS中并沒(méi)有限制在系統(tǒng)中使用同構(gòu)數(shù)據(jù)庫(kù)/數(shù)據(jù)源作為數(shù)據(jù)存儲(chǔ)與查詢(xún)做管理酥夭。在結(jié)合Event Sourcing的方式進(jìn)行數(shù)據(jù)的更新操作赐纱。可以滿(mǎn)足系統(tǒng)大量查詢(xún)的情況采郎。

參考

CQRS
領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)模式千所、原理與實(shí)踐
CQRS架構(gòu)
解決CQRS中的復(fù)雜問(wèn)題
最全面的CQRS和事件溯源介紹 - Software House ASC

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市蒜埋,隨后出現(xiàn)的幾起案子淫痰,更是在濱河造成了極大的恐慌,老刑警劉巖整份,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件待错,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡烈评,警方通過(guò)查閱死者的電腦和手機(jī)火俄,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)讲冠,“玉大人瓜客,你說(shuō)我怎么就攤上這事。” “怎么了谱仪?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵玻熙,是天一觀(guān)的道長(zhǎng)。 經(jīng)常有香客問(wèn)我疯攒,道長(zhǎng)嗦随,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任敬尺,我火速辦了婚禮枚尼,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘砂吞。我一直安慰自己署恍,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布呜舒。 她就那樣靜靜地躺著锭汛,像睡著了一般。 火紅的嫁衣襯著肌膚如雪袭蝗。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,125評(píng)論 1 297
  • 那天般婆,我揣著相機(jī)與錄音到腥,去河邊找鬼。 笑死蔚袍,一個(gè)胖子當(dāng)著我的面吹牛乡范,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播啤咽,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼晋辆,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了宇整?” 一聲冷哼從身側(cè)響起瓶佳,我...
    開(kāi)封第一講書(shū)人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎鳞青,沒(méi)想到半個(gè)月后霸饲,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡臂拓,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年厚脉,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片胶惰。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡傻工,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情中捆,我是刑警寧澤鸯匹,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站轨香,受9級(jí)特大地震影響忽你,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜臂容,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一科雳、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧脓杉,春花似錦糟秘、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至蕉堰,卻和暖如春凌净,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背屋讶。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來(lái)泰國(guó)打工冰寻, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人皿渗。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓斩芭,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親乐疆。 傳聞我的和親對(duì)象是個(gè)殘疾皇子划乖,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353

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