久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

CQRS解構(gòu):用讀寫分離設(shè)計API

 漢無為 2019-01-01

本文討論的是如何使用CQRS實現(xiàn)API設(shè)計,。

概述

下面是名為Command / Query Responsibility Segregation(CQRS)的設(shè)計模式:

返回數(shù)據(jù) 做出改變查詢 ?? ?命令 ? ??


查詢和命令是兩種分離的API,。

為何使用這種模式,?我喜歡它有幾個原因。作為API的消費者,,我永遠(yuǎn)不必?fù)?dān)心使用API出現(xiàn)異常了,;相反,我能確切地知道哪些API調(diào)用會專門應(yīng)付對系統(tǒng)的更改請求,,沒有含糊之處,。這使得API 易于推理。

我曾經(jīng)嘗試創(chuàng)建一個統(tǒng)一的界面來完成兩者,,但是隨著時間推移,,出現(xiàn)“服務(wù)于兩個主人“”的典型問題,單一界面變得更加混亂,。

時間長了會發(fā)生:“我們不使用這個字段,,為什么我們要更新它?,?!?回應(yīng):“我不知道,但繼續(xù)這樣做或會出問題,?!?

因此,CQRS的核心是一個關(guān)注點分離的特定應(yīng)用,,即良好的組織實踐?,F(xiàn)在我們已經(jīng)對模式進(jìn)行了介紹,我將介紹一些實現(xiàn)細(xì)節(jié)和經(jīng)驗教訓(xùn),。

消息

我認(rèn)為每個查詢或命令都是一條消息,。這意味著任何客戶端系統(tǒng)都可以將這些表達(dá)為沒有方法的普通數(shù)據(jù)(類或結(jié)構(gòu)),。然后以線形格式(如JSON或CapnProto或w / e)輕松傳輸它們。

每條消息都有一個名稱 - 通常只是類/結(jié)構(gòu)名稱 - 它在API中唯一標(biāo)識它,。如SearchCustomers(查詢)或DeactivateCourse(命令),。名稱用于標(biāo)識請求的操作,然后將其與消息解析器和處理函數(shù)進(jìn)行匹配,。安全授權(quán)由此很簡單,,只要保留一個用戶名單,允許這些用戶可發(fā)送哪些消息名稱,;然后在處理任何用戶的消息之前檢查該列表,。

運營

命令和查詢應(yīng)該如何工作似乎很明顯。但是我發(fā)現(xiàn)了一些細(xì)微差別,。

查詢:

查詢是很簡單的:

1. API偵聽 /query/[Query Name]

2. 驗證用戶是否具有[Query Name]權(quán)限

3. 反序列化查詢消息

4. 將查詢消息傳遞給其處理函數(shù),,該函數(shù)將:

5. 驗證查詢消息

6. 從數(shù)據(jù)庫加載和轉(zhuǎn)換數(shù)據(jù)

7. 序列化并返回數(shù)據(jù)

命令:

命令的目的是在系統(tǒng)上執(zhí)行一些業(yè)務(wù)操作。在實踐中,,我們注意到命令是否需要更改一個或多個實體,。出于架構(gòu)原因,如何處理多個實體更改非常重要,。

在這種情況下,,實體意味著某個邏輯單元。在高度規(guī)范化的表中,,實體可能包含父對象和一對多關(guān)系的任何子對象,。在DDD術(shù)語中,你可以將其稱為聚合,。在事件溯源中,,這是一個事件流。

可擴(kuò)展性

你可以在單個事務(wù)中執(zhí)行多實體更改,,以實現(xiàn)全有或全無的事務(wù)語義,。這種方法很適合,但它限制了可伸縮性,。要參與事務(wù),,所有受影響的實體必須位于同一數(shù)據(jù)庫節(jié)點上。如果它們位于不同的節(jié)點上,,則發(fā)生分布式事務(wù)(如果數(shù)據(jù)庫支持),。隨著負(fù)載的增加,,分布式事務(wù)將逐漸變慢,。跨實體事務(wù)是企業(yè)內(nèi)部業(yè)務(wù)應(yīng)用程序的有效方法,,但對于公開的互聯(lián)網(wǎng)服務(wù),,也許不是,。

像互聯(lián)網(wǎng)這種更加大規(guī)模級別應(yīng)用,我們的方法是僅使用單實體命令進(jìn)行更改,。當(dāng)用例需要更改多個實體時,,請使用元命令(自身不做任何改變),而不是編排并運行單實體命令,。我將單實體命令稱為“基本命令”,,將多實體命令稱為“工作流程”。當(dāng)工作流調(diào)用基本命令時,,這些命令可能會失敗,,工作流程會以業(yè)務(wù)用例的方式處理故障。這可能意味著需要忽略失敗并作為業(yè)務(wù)錯誤/警告返回給客戶,,或采取補(bǔ)償回退措施,。

客戶端工作流

你可以在客戶端實現(xiàn)工作流 - 讓UI編排所有必要的基本命令。但是,,我不在客戶端實現(xiàn)工作流,,而在API端實現(xiàn)工作流,主要理由是清晰(特別是安全性),。

我用一個真實例子來說明,。我們有培訓(xùn)師的角色,這個角色不能創(chuàng)建課程,,但是,,他們可以記錄他們提供給員工的培訓(xùn)。記錄培訓(xùn)時可能需要創(chuàng)建一個有限選項的新課程,。將記錄培訓(xùn)作為API工作流執(zhí)行,,可以將其表示為單個細(xì)化權(quán)限:“培訓(xùn)師可以記錄培訓(xùn),但不能創(chuàng)建課程,?!?在權(quán)限UI上選中一個選項,而不選中另一個選項,。

如果采取客戶端工作流,,執(zhí)行上述相同的操作,我們看看會怎樣,?我們需要添加一個基本命令:創(chuàng)建培訓(xùn)師課程,,然后管理員用戶必須被告知:“要給某人錄制培訓(xùn)的權(quán)限,你必須檢查Create Trainer Course并且Permission X和Permission Y,?!?那么這就給最終用戶造成的負(fù)擔(dān),需要他做這些流程。在這里,,我們還可以創(chuàng)建一個偽命令,,僅用于權(quán)限目的,映射到所需的基本命令,。這就將負(fù)擔(dān)又轉(zhuǎn)移給開發(fā)人員,。我不喜歡這些結(jié)果中的任何一個,所以我更喜歡API端工作流,。

指導(dǎo)原則

在實施CQRS API時,,人們會提出一些非常常見的問題。

1. 返回錯誤與返回數(shù)據(jù)不同,。

一個流行的誤解是命令應(yīng)該什么都不返回,。實際是命令應(yīng)該返回一些東西。它們返回有關(guān)操作本身的元信息(無論是成功還是失敗以及為什么,。這與返回業(yè)務(wù)數(shù)據(jù)非常不同,,后者是查詢的工作。

2. 命令可以在不進(jìn)行更改的情況下成功,。

命令可以進(jìn)行0次或更多次更改,。換句話說,“進(jìn)行更改”是命令的目的,,而不是所需的結(jié)果,。因此,對于成功運行的命令完全有效,,但不會導(dǎo)致任何更改,。

在運行命令之前和之后比較實體,如果它們完全相同,,那么就是進(jìn)行0更改并成功返回,。

3. 命令處理代碼可以調(diào)用查詢。

這似乎違反了CQRS原則,。命令的內(nèi)部除了“進(jìn)行更改”之外,,它沒有任何意思。

因此,,可以在命令中運行查詢,,才能獲取命令所需的一些信息,但是要小心一點,。

4. 自動遞增ID不應(yīng)是主鍵ID,。

常常需要返回自動生成的ID,因為自動增量ID非常方便,,但是也有問題:重復(fù),。

場景:用戶填寫表單用來創(chuàng)建新實體并點擊提交,。請求超時。

自動增量冒險:如果自動增量字段是您唯一的ID,,則你的應(yīng)用無法知道請求是否成功,。對這種情況的補(bǔ)救措施通常取決于用戶的意識和參與,。

如果用戶再次點擊提交(非??赡埽窍惹暗恼埱笕绻_實創(chuàng)建了實體,,盡管超時,,那么現(xiàn)在有兩個具有不同ID的相同實體。要正確清理,,用戶現(xiàn)在應(yīng)該搜索重復(fù)項并刪除冗余實體??(極不可能),。

或者,在超時之后,,用戶可以搜索他們可能創(chuàng)建的實體,。如果他們找不到,請再回來填寫表單,。根據(jù)我的經(jīng)驗,,這種情況不太可能。如果培訓(xùn)用戶習(xí)慣于這樣思考,,則可能會發(fā)生這種情況,。

還可以添加重復(fù)檢查的外部系統(tǒng),例如保持對已查看操作及其結(jié)果的記憶,。但有更好的方法......

預(yù)先生成的ID(冒險):

在用戶甚至開始鍵入任何內(nèi)容之前,,在加載表單時就生成(或從服務(wù)器請求)ID。

在用戶被告知請求超時后,,她再次點擊提交,。界面就會使用相同的預(yù)生成ID發(fā)送與之前相同的完全相同的請求。如果數(shù)據(jù)庫沒有重復(fù)會成功,,否則API響應(yīng):“此實體已存在,。” 如果UI可以識別出這個特定錯誤,,它可以假裝它正常成功,。這種冒險帶來了更好的用戶體驗,沒有重復(fù)的機(jī)會,。

我們的策略:我們傾向于使用UUID進(jìn)行所有標(biāo)識,。它們很容易在許多平臺上生成,。他們無視趨勢分析,。我們的大多數(shù)創(chuàng)建表單都必須運行查詢(例如,,獲取下拉列表數(shù)據(jù)),因此我們會在查詢結(jié)果中包含一個新的UUID,。

結(jié)論

命令是變動的守門人,。查詢則是知識庫,這是CQRS,。我發(fā)現(xiàn)這種模式使我走向正確的方向,。它也是一種多功能的模式。它不關(guān)心你的部署的是單體還是微服務(wù),。甚至可以將命令和查詢拆分為各自獨立的服務(wù),,實現(xiàn)讀寫負(fù)載分離。

但請記住,,這只是一個大系統(tǒng)中的一個部分,,而不是適合每個系統(tǒng)的通用工具。CQRS模式在后端系統(tǒng)的邊界內(nèi)能很好地工作,,與客戶端應(yīng)用程序連接,。與任何模式一樣,只有在適當(dāng)?shù)那闆r下應(yīng)用它時才有用,。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點,。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多