自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

微服務(wù)壞味道之循環(huán)依賴

開發(fā) 架構(gòu)
重構(gòu)系統(tǒng)和重構(gòu)代碼一樣,首先要先識別系統(tǒng)的壞味道,今天我們就來聊聊如何消滅其中的一個壞味道——循環(huán)依賴。

歷史上有很多科學(xué)家為之背書的熵增定律,揭示了很多自然界現(xiàn)象的本質(zhì):任何孤立系統(tǒng),在沒有外力作用的情況下,其總混亂度(熵)會不斷增大。

軟件系統(tǒng)當(dāng)然也不例外,隨著軟件系統(tǒng)的功能不斷增加,系統(tǒng)的混亂度也在不斷增大。為了降低軟件系統(tǒng)混亂的速度,必須要對其施以外力(重構(gòu))。

重構(gòu)系統(tǒng)和重構(gòu)代碼一樣,首先要先識別系統(tǒng)的壞味道,Davide Taibi和Valentina Lenarduzzi在文章《On the Definition of Microservice Bad Smells》中定義了微服務(wù)的壞味道,今天我們就來聊聊如何消滅其中的一個壞味道——循環(huán)依賴。

循環(huán)依賴的危害

微服務(wù)之間的循環(huán)依賴類似于類之間的循環(huán)依賴,當(dāng)依賴關(guān)系形成了環(huán),會有很多危害:

首先是微服務(wù)之間的耦合性非常強(qiáng),服務(wù)很難做到獨立部署,這嚴(yán)重違反了微服務(wù)的初衷;這種情況往往是服務(wù)之間的調(diào)用沒有約束導(dǎo)致的,為了方便取到或更新數(shù)據(jù),服務(wù)之間可以隨意的調(diào)用,以”微服務(wù)“為設(shè)計目標(biāo)的系統(tǒng)會逐漸演變成一個分布式大單體,下圖展示了三個服務(wù)之間的循環(huán)依賴關(guān)系:

另外循環(huán)依賴很可能導(dǎo)致一些循環(huán)調(diào)用或并發(fā)問題,造成一些復(fù)雜難以定位的問題,以上圖中訂單和客戶的循環(huán)依賴為例:

訂單服務(wù)依賴客戶服務(wù)來獲取客戶信息,為了滿足可以根據(jù)客戶姓名查詢訂單的需求,除了記錄客戶的ID,同時將客戶的姓名冗余到訂單的數(shù)據(jù)中。當(dāng)客戶信息更新時,為保證訂單上數(shù)據(jù)的準(zhǔn)確,客戶服務(wù)會調(diào)用訂單服務(wù)更新訂單上的客戶信息。

循環(huán)依賴讓事情變得復(fù)雜,不同的實現(xiàn)會有不同的問題表現(xiàn),我們來看這樣的場景:當(dāng)訂單狀態(tài)變化時,客戶的狀態(tài)也要跟著變化,訂單服務(wù)會更新客戶的狀態(tài),而客戶信息的變化反過來需要更新訂單上冗余的客戶信息;假設(shè)在訂單上加了樂觀鎖,同一時刻的兩次訂單更新因為樂觀鎖會有一個失敗,排查問題過程中通過現(xiàn)象會優(yōu)先考慮并發(fā)的問題,然而真相卻恰恰相反,參見下圖時序:

循環(huán)依賴產(chǎn)生的原因

數(shù)據(jù)過度冗余

數(shù)據(jù)冗余是導(dǎo)致服務(wù)之間循環(huán)依賴的主要原因,為了保證多個服務(wù)之間數(shù)據(jù)的一致性,某個服務(wù)對數(shù)據(jù)的修改要同步到其他服務(wù),保證其他服務(wù)冗余字段的信息準(zhǔn)確。

上面訂單上冗余客戶姓名的場景就是個很好的例子,冗余數(shù)據(jù)在一定程度上增強(qiáng)了業(yè)務(wù)實現(xiàn)的簡便性,但為了保證數(shù)據(jù)一致性,也增加了服務(wù)間不必要的調(diào)用。

缺失業(yè)務(wù)概念

和數(shù)據(jù)過度冗余相對的是在軟件設(shè)計時缺少必要的業(yè)務(wù)概念,也同樣會導(dǎo)致循環(huán)依賴的情況發(fā)生;典型的場景是上游系統(tǒng)的數(shù)據(jù)狀態(tài)需要下游系統(tǒng)的數(shù)據(jù)進(jìn)行計算得到,當(dāng)需要對上游系統(tǒng)的數(shù)據(jù)狀態(tài)時,上游服務(wù)會調(diào)用下游服務(wù)的接口來進(jìn)行計算。

這種場景也很常見,繼續(xù)用訂單和客戶的例子幫助理解:

如果一個客戶的所有訂單要么取消,要么已經(jīng)完成開票結(jié)算流程,那么這個客戶就是一個成功客戶,否則是一個服務(wù)中客戶。

在軟件設(shè)計時如果沒有給客戶定義一個狀態(tài)來表達(dá)這個業(yè)務(wù)概念,那么每次需要拿到客戶狀態(tài)時只能通過訂單服務(wù)來進(jìn)行查詢計算。

濫用同步調(diào)用

上面兩種場景一旦產(chǎn)生循環(huán)依賴,往往也伴隨著同步調(diào)用的濫用,然而也有一些場景既沒有數(shù)據(jù)過度冗余,也沒有缺少業(yè)務(wù)概念,但仍然可能會濫用同步調(diào)用。

上文圖中用戶離職更新客戶所有者信息的場景就是一個很好的例子,雖然使用同步調(diào)用的方式從實現(xiàn)結(jié)果上來看是非常直接有效的方法,但長遠(yuǎn)來看,這種無腦的濫用同步調(diào)用讓系統(tǒng)的復(fù)雜度變的非常高,當(dāng)我們希望替換或重構(gòu)某個服務(wù),我們很難依據(jù)業(yè)務(wù)分析清楚到底有哪些服務(wù)會受到影響。

消滅循環(huán)依賴的方法

通過上面對循環(huán)依賴原因的分析(這里我們不考慮微服務(wù)劃分不合理的場景),可以看出循環(huán)依賴通常是為了滿足某種業(yè)務(wù)需求,在服務(wù)之間增加了不合理的調(diào)用。

要解決循環(huán)依賴,必須要在微服務(wù)之間建立一些原則來約束微服務(wù)之間的通信,定期通過這些原則來審視我們的系統(tǒng),找到問題并進(jìn)行重構(gòu),這些原則應(yīng)該包括:

  • 定義服務(wù)上下游關(guān)系,下游服務(wù)可以直接依賴上游服務(wù),反之則不可
  • 上游服務(wù)的變更對下游服務(wù)產(chǎn)生影響需要通過領(lǐng)域事件(異步)的方式來實現(xiàn)
  • 服務(wù)之間要通過數(shù)據(jù)Id(或類Id,能夠唯一代表數(shù)據(jù)且不變的屬性)來進(jìn)行關(guān)聯(lián),盡量不做過多的數(shù)據(jù)冗余
  • 一旦需要上游服務(wù)調(diào)用下游服務(wù)才能完成業(yè)務(wù)時,要考慮是否上游服務(wù)缺少業(yè)務(wù)概念
  • 為滿足前端邏輯而導(dǎo)致的服務(wù)間交互邏輯要放到BFF(Backend for frontend)中,而不是增加服務(wù)間的調(diào)用

小結(jié)

微服務(wù)架構(gòu)提倡把服務(wù)拆的小而獨立,一個軟件系統(tǒng)往往會有很多服務(wù),大部分業(yè)務(wù)需求是需要多個服務(wù)一起配合才能完成;受限于交付壓力,在對架構(gòu)的理解不是很透徹的情況下,開發(fā)人員往往傾向于采用更容易的(熵增)方式實現(xiàn)功能,在這種情況下,循環(huán)依賴是一個非常容易發(fā)生的壞味道,對系統(tǒng)的健康具有巨大危害。

我們可以通過一些技術(shù)手段來發(fā)現(xiàn)系統(tǒng)中的循環(huán)依賴問題,比如通過鏈路追蹤系統(tǒng)(如Zipkin)將服務(wù)間依賴關(guān)系可視化出來;也可以在發(fā)現(xiàn)問題時將有問題的流程時序圖畫出來,可視化的方式可以很容易幫我們找到系統(tǒng)中循環(huán)依賴的問題,然后我們就可以對癥下藥,消滅壞味道。

責(zé)任編輯:趙寧寧 來源: Thoughtworks洞見
相關(guān)推薦

2020-06-12 08:21:58

JavaScript代碼開發(fā)

2019-10-11 09:07:46

Java代碼對象

2024-07-12 08:52:50

2023-01-11 08:41:47

微服務(wù)循環(huán)依賴

2021-05-26 11:50:37

代碼優(yōu)化Java

2012-07-13 09:35:58

PHP

2012-07-13 09:38:15

項目代碼

2015-07-29 13:22:40

.NET代碼

2012-07-19 10:42:17

項目

2018-08-24 21:25:02

編程語言代碼重構(gòu)GitHub

2024-07-02 10:58:53

2019-09-09 06:30:06

Springboot程序員開發(fā)

2018-08-01 14:20:11

微服務(wù)架構(gòu)人工智能

2021-07-13 10:00:00

微服務(wù)SleuthElasticSear

2019-07-11 15:25:02

架構(gòu)運(yùn)維技術(shù)

2017-07-04 17:35:46

微服務(wù)架構(gòu)Spring Clou

2021-03-09 09:33:42

網(wǎng)關(guān)授權(quán)微服務(wù)

2024-08-05 10:03:53

2022-06-17 12:05:25

微服務(wù)注冊

2023-05-04 08:06:27

Spring循環(huán)依賴
點贊
收藏

51CTO技術(shù)棧公眾號