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

業(yè)務(wù)系統(tǒng)改造嘗試引入DDD,事情變得更禿然起來……

系統(tǒng) 新聞
本文主要介紹了商品中心中臺服務(wù)創(chuàng)建過程中的DDD實(shí)踐思路、業(yè)務(wù)改造案例、服務(wù)架構(gòu)設(shè)計、消息機(jī)制等內(nèi)容。

?商品中心隨著自身業(yè)務(wù)的發(fā)展,系統(tǒng)復(fù)雜度逐漸變高。在業(yè)務(wù)治理過程中,我們嘗試引入了DDD來輔助進(jìn)行現(xiàn)有業(yè)務(wù)的模型重建,并在此基礎(chǔ)上完成了中臺服務(wù)能力的沉淀和對外提供。通過將核心業(yè)務(wù)邏輯下沉內(nèi)聚,降低調(diào)用方的業(yè)務(wù)復(fù)雜度,防范邏輯腐化。

一、前言

商品中心業(yè)務(wù)主要包括商品、類目等核心數(shù)據(jù)維護(hù),負(fù)責(zé)和支撐嚴(yán)選內(nèi)部商品相關(guān)的業(yè)務(wù)協(xié)同。

在業(yè)務(wù)的快速發(fā)展過程中,系統(tǒng)的復(fù)雜度也不斷提升。原來的架構(gòu)已經(jīng)無法適應(yīng)內(nèi)外部的需求,因此從17年開始,商品中心逐步經(jīng)歷了管理后臺拆分、商品中心服務(wù)化、商品數(shù)據(jù)遷移等工作,并且在不斷優(yōu)化,以適應(yīng)嚴(yán)選日益增長的業(yè)務(wù)量。

19年開始,嚴(yán)選開始進(jìn)行中臺化架構(gòu)升級。我們嘗試引入了DDD來輔助進(jìn)行現(xiàn)有業(yè)務(wù)的模型重建,并在此基礎(chǔ)上完成了中臺服務(wù)能力的沉淀和對外提供。通過將核心業(yè)務(wù)邏輯下沉內(nèi)聚,降低調(diào)用方的業(yè)務(wù)復(fù)雜度,防范邏輯腐化。

當(dāng)前,商品中心已經(jīng)構(gòu)建了一工作臺一中臺兩個查詢服務(wù)的系統(tǒng)架構(gòu)。

圖片

本文將介紹中臺服務(wù)建設(shè)的相關(guān)過程、踩坑記錄,同時給需要進(jìn)行類似嘗試的開發(fā)童鞋一定的參考和借鑒。

二、系統(tǒng)的痛點(diǎn)有哪些?

眾所周知,軟件系統(tǒng)總是在不知不覺之間變得龐大,如果沒有及時干預(yù),系統(tǒng)的脈絡(luò)就會和毛線球一樣難以解開。

商品中心目前主要有以下幾點(diǎn)突出問題:

1、業(yè)務(wù)邏輯重復(fù)

當(dāng)采用自然式的流程開發(fā),在初期業(yè)務(wù)不復(fù)雜時,系統(tǒng)業(yè)務(wù)脈絡(luò)還比較簡單。一旦經(jīng)歷了多個版本以上的迭代,腳本式開發(fā)的代碼不斷增刪內(nèi)容,甚至出現(xiàn)同一段代碼拷貝后微調(diào)了部分邏輯,造成邏輯的冗余,從而增加理解和迭代的成本。

舉例商品的創(chuàng)建鏈路:

  • 開發(fā)完成后自動創(chuàng)建商品
  • 工單審核后自動創(chuàng)建純組合裝商品
  • 直接創(chuàng)建特殊免立項(xiàng)商品
  • 采購遷移后臺創(chuàng)建商品

因?yàn)榍捌跊]有從模型的能力視角進(jìn)行設(shè)計,且由于商品創(chuàng)建的部分差異和中途經(jīng)歷了不同的同事開發(fā)等原因,結(jié)果是項(xiàng)目中存在多分類似又有一定差異的代碼,導(dǎo)致維護(hù)變得越來越困難,出了一些漏改導(dǎo)致的BUG。

2、模塊耦合太重

商品工作臺作為業(yè)務(wù)進(jìn)行商品管理的入口服務(wù),承擔(dān)了大量業(yè)務(wù)協(xié)同和商品數(shù)據(jù)配置的內(nèi)容。由于沒有隔離,導(dǎo)致業(yè)務(wù)協(xié)同和商品管理的邏輯耦合太深,不利于各模塊的復(fù)用和優(yōu)化。

三、DDD簡介

領(lǐng)域驅(qū)動設(shè)計(domain-driven design),是指通過設(shè)計領(lǐng)域模型,來驅(qū)動軟件設(shè)計,最終指導(dǎo)代碼落地的過程。一個業(yè)務(wù)領(lǐng)域劃分為若干個限界上下文(Bounded Context),領(lǐng)域模型處于各自的限界上下文之內(nèi)。

DDD的具有以下特點(diǎn):

  • 更明確的邊界

DDD的設(shè)計原則,是使系統(tǒng)的邊界更加清晰,讓我們本能的進(jìn)行軟件系統(tǒng)的分而治之。這是其最具價值的地方,當(dāng)我們把問題分的越小,它的解決也越簡單。

  • 更通用的語言

當(dāng)邊界確定后,邊界內(nèi)的術(shù)語(名詞對象、動作等),在產(chǎn)品、開發(fā)、測試的共同努力下,將形成具有共識的通用語言。特別是可以在后續(xù)的迭代保證這些術(shù)語是通用的。這里特別提到了通用語言的確定不再只由開發(fā)人員來決定了,是業(yè)務(wù)相關(guān)人員的共識,也更能加深大家對領(lǐng)域模型的了解。

  • 更內(nèi)聚的邏輯

一個明確的問題域中,子問題都會落到邊界內(nèi)負(fù)責(zé)處理,邏輯更加內(nèi)聚,對外界隔離。

作為業(yè)務(wù)研發(fā)人員,本質(zhì)是通過技術(shù)更好實(shí)現(xiàn)業(yè)務(wù)價值。面對當(dāng)前系統(tǒng)中的問題,我們希望DDD能在系統(tǒng)改造的過程中發(fā)揮它的作用。

四、系統(tǒng)改造之路

商品中臺服務(wù)搭建,核心思路是:抽取核心業(yè)務(wù)邏輯->抽象流程->標(biāo)準(zhǔn)化能力。

雖然是對現(xiàn)有業(yè)務(wù)的改造,但是在系統(tǒng)建模的流程上我們盡量趨向于從頭開始設(shè)計。這樣做的好處是:可以盡可能避免受到現(xiàn)有表結(jié)構(gòu)設(shè)計的干擾。

沿用DDD的經(jīng)典步驟如下:

1、戰(zhàn)略設(shè)計

在這過程中,主要是明確系統(tǒng)的通用語言。

例如我們在商品中心服務(wù)的設(shè)計過程中,我們明確了系統(tǒng)模型和行為,劃分子域,并編制了限界上下文和上下文映射圖,形成了包括產(chǎn)品和開發(fā)在內(nèi)所普遍認(rèn)可的通用語言。

子域又分為幾類:核心域、支撐子域、通用子域;其中核心域是整個業(yè)務(wù)域的主要成員。支撐域不是核心,負(fù)責(zé)一些具體的業(yè)務(wù)。如果支撐域可以適用整個系統(tǒng),那么就變成通用域。

商品中心主要通過兩個步驟完成戰(zhàn)略設(shè)計:

  • 領(lǐng)域愿景說明(Domain Vision Statement)

由產(chǎn)品技術(shù)等人員闡述商品域的核心能力:商品板塊負(fù)責(zé)商品管理:包括商品和SKU等核心數(shù)據(jù)維護(hù)、商品相關(guān)配置,負(fù)責(zé)和支撐嚴(yán)選內(nèi)部商品相關(guān)的業(yè)務(wù)協(xié)同:包括新品開發(fā)全流程(新品立項(xiàng)、尋源、報改價、采購側(cè)工單、包裝設(shè)計、上線信息評審等)、售價變更、重新售賣等。

  • 突出核心(Highlighted Core)

通過對業(yè)務(wù)的梳理,抽出核心模型:SPU、SKU、物理類目、配送區(qū)域、營銷配置、售后地址、服務(wù)政策等,并將這些模型按聚合關(guān)系劃分為四個子域。

圖片

2、戰(zhàn)術(shù)設(shè)計

戰(zhàn)術(shù)設(shè)計是將戰(zhàn)略設(shè)計進(jìn)行具體化,這個過程中將明確各子域的聚合、實(shí)體、值對象、領(lǐng)域?qū)嵺`、領(lǐng)域服務(wù)等,不做詳細(xì)展開,詳細(xì)可參考《實(shí)現(xiàn)領(lǐng)域驅(qū)動設(shè)計》(沃恩?弗農(nóng) (Vaughn Vernon)) 。

在上述階段,可以通過OOAD(面向?qū)ο蠓治龇椒ǎ⑺纳?、事件風(fēng)暴等方式。

在我們的項(xiàng)目中,我們通過事件風(fēng)暴識別領(lǐng)域事件、命令,并完成了邊界、聚合的劃分。

事件風(fēng)暴:簡單概括就是通過X主體,執(zhí)行了A命令,產(chǎn)生了B事件的這樣一個流程,來梳理核心的業(yè)務(wù)流程和規(guī)則,輸出業(yè)務(wù)對象,并推導(dǎo)出相關(guān)的領(lǐng)域模型。常用模型如下:

  • Entity(實(shí)體)

每個實(shí)體是唯一的,允許狀態(tài)發(fā)生變化,但是一定有唯一標(biāo)識。

  • ValueObject(值對象)

值對象用于描述實(shí)體,值對象和實(shí)體的區(qū)別是不需要感知唯一標(biāo)識。

  • Aggregate(聚合)

聚合是一種特殊的實(shí)體,是由一組與強(qiáng)相關(guān)的實(shí)體和值對象組合而成的。

  • Bounded Context(限界上下文)

用來封裝通用語言和領(lǐng)域?qū)ο?,通常一個子域?qū)?yīng)一個限界上下文。

領(lǐng)域?qū)ο蟊硎崂砣缦拢?/p>

圖片

3、編碼流程

本節(jié)主要介紹商品中心在實(shí)施過程中對一些場景的改造方法。

1)重復(fù)流程的抽象方法

在代碼改造中,可以發(fā)現(xiàn)有些分散在不同位置卻干著相同流程的代碼。對于這部分代碼,我們需要抽象出業(yè)務(wù)流程,并對其進(jìn)行邏輯的統(tǒng)一收攏。

嚴(yán)選的作為品牌電商,自營立項(xiàng)流程是我們區(qū)別行業(yè)所特有的業(yè)務(wù),舉例現(xiàn)狀分析中提到的商品創(chuàng)建流程,通過三步驟(梳理流程列表-->標(biāo)記共同流程-->輸出通用流程),分析業(yè)務(wù)邏輯,找到核心鏈路如下:

圖片

2)核心邏輯的抽象方法

在改造中也會遇到流程較長的鏈路,我們需要獲取到核心節(jié)點(diǎn),排除非核心節(jié)點(diǎn),從而輸出該業(yè)務(wù)的鏈路。通過三個步驟進(jìn)行:

① 梳理業(yè)務(wù)節(jié)點(diǎn)

圖片

② 抓取關(guān)鍵節(jié)點(diǎn)

在對鏈路分析后,按領(lǐng)域模型相關(guān)性,標(biāo)記核心節(jié)點(diǎn)(綠色部分),形成簡化版的節(jié)點(diǎn)圖:

圖片

③ 收斂邏輯

在這個過程中,需要對節(jié)點(diǎn)進(jìn)行重構(gòu),主要進(jìn)行節(jié)點(diǎn)合并和節(jié)點(diǎn)異步化兩塊內(nèi)容:

  • 節(jié)點(diǎn)合并:校驗(yàn)節(jié)點(diǎn),我們可以歸位一個統(tǒng)一節(jié)點(diǎn),實(shí)際業(yè)務(wù)操作的節(jié)點(diǎn)也按聚合合并。
  • 非阻塞流程異步化:通過分析,其實(shí)有些操作是可以異步化的。例如:操作人、操作日志、上架任務(wù)的取消、緩存刷新等可以在消息通知訂閱后處理,從而繼續(xù)簡化核心鏈路。

實(shí)際上核心邏輯被我們分解成了四個階段:

圖片

通過這些過程,我們對核心流程進(jìn)行了邏輯重構(gòu),從結(jié)果上看,核心邏輯下沉到中臺服務(wù)內(nèi),減少接入方的邏輯處理和代碼量,使維護(hù)性得到了較大的提升。在商品創(chuàng)建這個案例中,光代碼量上就縮減了2/3左右,長遠(yuǎn)看,會降低未來迭代時邏輯梳理的時間和人力成本。

五、相關(guān)設(shè)計

1、服務(wù)架構(gòu)

在嚴(yán)選中臺建設(shè)初期,我們?yōu)楹罄m(xù)的應(yīng)用架構(gòu)標(biāo)準(zhǔn)進(jìn)行了激烈的討論,對比經(jīng)典四層架構(gòu)、COLA(整潔結(jié)構(gòu))之間的優(yōu)缺點(diǎn)。

雖然經(jīng)典架構(gòu)更直觀,但鑒于COLA對領(lǐng)域模型為中心的設(shè)計,保證領(lǐng)域?qū)拥莫?dú)立性,最終促成我們采用COLA架構(gòu)作為統(tǒng)一的模版,和六邊形架構(gòu)類似,它的核心理念是:應(yīng)用是通過端口與外部進(jìn)行交互的,內(nèi)部業(yè)務(wù)邏輯(應(yīng)用層和領(lǐng)域模型)與外部資源(外部服務(wù),數(shù)據(jù)庫資源、消息中間件等)相互隔離,僅通過適配器進(jìn)行交互。

圖片

有別于傳統(tǒng)的用戶界面、接口層、邏輯層、持久化層的從外到內(nèi)的分層模型,這是種全新的思想,我們認(rèn)為用戶界面、數(shù)據(jù)庫、消息等都屬于平等的外部方,他們都需要通過端口和應(yīng)用交互,COLA的思想中,更加突出了架構(gòu)核心是領(lǐng)域模型。 

商品中臺服務(wù)在此基礎(chǔ)上的系統(tǒng)分層如下:

圖片

2、事件機(jī)制

場景:修改SKU售價,被我們打包成一個具體的能力如下:

圖片

上述場景中,應(yīng)用層調(diào)用“更新售價”的領(lǐng)域行為后,還要處理其他行為,等所有行為處理完成后事件才對外發(fā)送。

因此我們的消息機(jī)制需要滿足以下要求:

  • 事件提交:允許事件提交到當(dāng)前場景。

  • 事件異步和控制:指的是可以控制事件實(shí)際對外通知的時機(jī)。

  • 事件異常重試:異常后支持重試實(shí)現(xiàn)業(yè)務(wù)補(bǔ)償。

消息初始化流程如下:

圖片

系統(tǒng)初始化邏輯:

  • 容器啟動
  • 完成Listeners實(shí)例創(chuàng)建
  • 初始化EventBus事件總線
  • 從BeanFactory掃描所有Listeners
  • 注冊Listeners到EventBus事件總線

實(shí)際消息處理流程:

圖片

在應(yīng)用層處理完所有業(yè)務(wù)并完成事務(wù)提交后,系統(tǒng)將暫存在EventContext中的消息post到異步處理的eventBus中,由eventBus協(xié)調(diào)消息的投遞和處理。

如果是內(nèi)部消息,直接由訂閱者處理,如果是外部消息,由訂閱者通過MQ轉(zhuǎn)發(fā)至外部。

當(dāng)然,我們需要支持事件定制的消息異常處理機(jī)制,對于有需要重試的消息,允許在啟動時注冊重試處理器。

六、討論

在實(shí)踐中,也發(fā)現(xiàn)一些問題和解決思路供大家參考。

1、實(shí)體范圍大小問題

在設(shè)計中,我們存在把同一類屬性歸為一個實(shí)體,但是實(shí)際使用中,會發(fā)現(xiàn)對該實(shí)體的使用仍然是按模塊的。例如履約實(shí)體:

圖片

設(shè)計之初,我們將商品的預(yù)約配送、發(fā)票開關(guān)、稅率等都?xì)w為履約實(shí)體,但在實(shí)際應(yīng)用中,實(shí)際還是按子業(yè)務(wù)配置,那么在對實(shí)體更新的處理邏輯中,需要過多關(guān)注屬性覆蓋等問題,這就是沒有拆分完全,履約實(shí)體內(nèi)其實(shí)可以再拆分為三個實(shí)體。因此設(shè)計時不光要考慮屬性的相似性,更要結(jié)合業(yè)務(wù)場景進(jìn)行設(shè)計。

2、模型的開發(fā)模式選擇

首先明確分類,因?yàn)檫@里會出現(xiàn)不同時期對貧血模型的定義歧義,導(dǎo)致大家理解的不同。

  • 失血模型:實(shí)體只有setter/getter。

  • 貧血模型:domain ojbect包含了不依賴于持久化的業(yè)務(wù)邏輯。

  • 充血模型:絕大多業(yè)務(wù)邏輯都應(yīng)該被放在domain object里面(包括持久化邏輯),而Service層應(yīng)該是很薄的一層。

  • 脹血模型:取消Service層,只剩下domain object和DAO兩層,在domain object的domain logic上面封裝事務(wù)。

在這種定義下,充血和貧血其實(shí)各有好處,本質(zhì)上我認(rèn)為依然負(fù)責(zé)領(lǐng)域模型包含業(yè)務(wù)的思想。我們采用貧血模式,在保留模型業(yè)務(wù)邏輯的同時,不希望引入持久化邏輯,兼顧開發(fā)接受度和模型的整潔度。

3、服務(wù)粒度

微服務(wù)粒度建議按子域范圍拆分。如果拆分太細(xì),需要考慮分布式事務(wù)問題,增加了復(fù)雜度(特別是對于一些核心域有數(shù)據(jù)一致性要求的場景)。

七、結(jié)尾

本文主要介紹了商品中心中臺服務(wù)創(chuàng)建過程中的DDD實(shí)踐思路、業(yè)務(wù)改造案例、服務(wù)架構(gòu)設(shè)計、消息機(jī)制等內(nèi)容。希望其中的一些類似案例和實(shí)施手段可以為后續(xù)其他產(chǎn)品線實(shí)踐提供一個探索思路。

當(dāng)然,后端服務(wù)的架構(gòu)演進(jìn)遠(yuǎn)非如此簡單。在完成現(xiàn)有業(yè)務(wù)的改造后,依然會面臨業(yè)務(wù)變更和新增業(yè)務(wù)的挑戰(zhàn),系統(tǒng)的模型也不是一成不變的,我們也依然需要對系統(tǒng)進(jìn)行不斷的自我更新以適應(yīng)業(yè)務(wù)的發(fā)展。?

責(zé)任編輯:張燕妮 來源: 嚴(yán)選技術(shù)產(chǎn)品團(tuán)隊(duì)
相關(guān)推薦

2022-06-17 09:47:04

Linux命令

2021-02-18 09:38:50

敏捷性組織IT團(tuán)隊(duì)

2025-01-26 10:10:30

2021-03-15 10:29:50

人工智能

2021-04-25 15:17:29

代碼軟件程序員

2019-06-26 15:41:26

AI云原生云遷移

2018-07-30 11:53:04

Kubernetes無服務(wù)器容器

2024-01-23 13:13:09

2021-11-29 08:07:07

微服務(wù)驅(qū)動設(shè)計

2019-07-10 10:20:36

前端用戶體驗(yàn)javascript

2021-05-18 16:27:50

編程代碼金融

2021-03-08 10:21:22

開源技術(shù) 框架

2013-06-24 09:41:07

AdLeaks數(shù)據(jù)泄露斯諾登

2009-07-22 14:56:50

ERPVPNVPN加速

2024-12-23 05:00:00

AI人工智能

2009-06-18 15:51:52

SSL VPN負(fù)載均衡Array

2019-12-19 18:40:16

5G智慧城市智能教育

2017-05-23 08:50:16

巴菲特挑戰(zhàn)

2011-11-09 11:13:55

Firefox 8

2020-06-16 13:22:22

AI創(chuàng)新深度學(xué)習(xí)
點(diǎn)贊
收藏

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