溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

微服務(wù)架構(gòu)與領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)應(yīng)用實(shí)踐

發(fā)布時(shí)間:2020-07-20 06:25:42 來源:網(wǎng)絡(luò) 閱讀:454 作者:JAVA努力中 欄目:編程語言

本篇文章一共分為三個(gè)部分,分別是微服務(wù)架構(gòu)的演進(jìn)過程、具體實(shí)踐微服務(wù)的應(yīng)用技術(shù)和領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)的意識(shí)轉(zhuǎn)變。微服務(wù)架構(gòu)已經(jīng)***到互聯(lián)網(wǎng)應(yīng)用的方方面面,而領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)也逐漸被業(yè)界所接收。

微服務(wù)架構(gòu)幾乎都是從 ALL IN ONE 的單體架構(gòu)演進(jìn)而來,中間又經(jīng)歷了分布式架構(gòu)、面向服務(wù)架構(gòu)的演進(jìn)過程。

單體架構(gòu)往往以煙筒式方式發(fā)展,往往存在兩個(gè)主要問題:中心化和耦合度高。所謂中心化,就是數(shù)據(jù)集中存儲(chǔ)在單個(gè)數(shù)據(jù)庫中,業(yè)務(wù)系統(tǒng)集中部署在單臺(tái)服務(wù)器上,通過集群部署方式提供服務(wù)能力,然而中心化的問題,也就是單點(diǎn)問題。而耦合度高,主要是指其中一個(gè)功能模塊升級(jí),其它的模塊都得一起升級(jí)。這里要說明下,模塊依賴度高不是單體架構(gòu)的錯(cuò),是因?yàn)楸緛砑軜?gòu)可能就沒有設(shè)計(jì)好,但是,在實(shí)際場(chǎng)景中,隨著快速迭×××發(fā),研發(fā)換了一波又一波,產(chǎn)品走了一茬又一茬,難免系統(tǒng)架構(gòu)腐化嚴(yán)重。

看到了單體架構(gòu)的諸多問題,系統(tǒng)開始通過按功能或模塊進(jìn)行拆分,拆分成多個(gè)獨(dú)立的子系統(tǒng),系統(tǒng)間通過 RPC、MQ 方式調(diào)用,由此逐漸演變?yōu)榉植际降姆?wù)架構(gòu)。分布式服務(wù)架構(gòu)主要通過服務(wù)化和層次化進(jìn)行解耦拆分,《架構(gòu)整潔之道》書中提到一點(diǎn),系統(tǒng)可以降解為策略和層次,而架構(gòu)設(shè)計(jì)就是把相同的策略分到同一個(gè)組件中,反之,分屬于不同的組件。所以,架構(gòu)設(shè)計(jì)可以通過分層設(shè)計(jì),由高層次服務(wù)調(diào)用低層次服務(wù),低層次服務(wù)通過接口向上提供服務(wù),以實(shí)現(xiàn)系統(tǒng)之間的解耦。也正是在這一階段,單體架構(gòu)一下子被拆分成幾個(gè)或幾十個(gè)系統(tǒng)。

但是隨著架構(gòu)的發(fā)展,問題又接踵而來,在沒有做好邊界的劃分之前,系統(tǒng)拆分的服務(wù)往往是松散的。正如《架構(gòu)整潔之道》所講:軟件架構(gòu)設(shè)計(jì)本身就是一門劃分邊界的藝術(shù)。所以,很多系統(tǒng)在這一階段,又往往進(jìn)行了服務(wù)內(nèi)聚和去層次化的演變過程。所謂服務(wù)內(nèi)聚,就是以領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)為原則,重新界定領(lǐng)域邊界,對(duì)模塊進(jìn)行服務(wù)整合,對(duì)系統(tǒng)進(jìn)行合并。而去層次化,則是去除服務(wù)層次高低之分,按服務(wù)調(diào)用最優(yōu)鏈路提供服務(wù)請(qǐng)求,降低深度,以此保證系統(tǒng)的穩(wěn)定性能。

系統(tǒng)如何從 0 到 1,從 1 到 2,從 2 到 100,在具體實(shí)踐微服務(wù)的過程并不容易。首先,考慮的第一個(gè)問題是:微服務(wù)是什么?其實(shí),微服務(wù)是一個(gè)動(dòng)作:拆。說到拆,就涉及到兩個(gè)問題,第一,怎么拆?第二,拆到什么程度。

第一個(gè)問題,關(guān)于怎么拆,需要關(guān)注兩個(gè)層面,一是發(fā)版速度,如商品、交易、促銷等不同領(lǐng)域的迭代速度和開發(fā)速度是不一致的,所以,應(yīng)該拆分到不同的領(lǐng)域,否則,就可能耦合在一起,A 上線 B 必須跟著一起上,這可能就應(yīng)該合并到一起。另一個(gè)是能源協(xié)同,每個(gè)系統(tǒng)后面對(duì)應(yīng)不同的研發(fā)團(tuán)隊(duì),一個(gè)項(xiàng)目往往需要幾個(gè)團(tuán)隊(duì)分工協(xié)作,那么系統(tǒng)拆分必然導(dǎo)致團(tuán)隊(duì)協(xié)作的成本,所以拆分系統(tǒng)同樣也是拆分團(tuán)隊(duì),要考慮協(xié)作溝通所帶來的成本。

第二個(gè)問題,拆到什么程度。其實(shí),已經(jīng)有很多人對(duì)微服務(wù)進(jìn)行了定義,其中我認(rèn)為最重要的兩點(diǎn):一是微服務(wù)或一組微服務(wù),應(yīng)該是一套獨(dú)立部署運(yùn)行的服務(wù),二是微服務(wù)所依賴的數(shù)據(jù)資源應(yīng)該是彼此間相互獨(dú)立隔離部署的。

其實(shí),拆只是實(shí)踐微服務(wù)的開始,要搭建整體的微服務(wù)框架還要進(jìn)行四部曲:拆、服務(wù)化、高可用、隔離。

1,服務(wù)拆分

微服務(wù)講究拆分,那么多微才是微,以及,怎么才是比較合理的拆分。在架構(gòu)設(shè)計(jì)領(lǐng)域,有一個(gè)大家都在講的著名定律:康為定律,可以理解為:一個(gè)系統(tǒng)架構(gòu)的組織關(guān)系是和團(tuán)隊(duì)的組織關(guān)系相匹配的。如交易系統(tǒng)會(huì)對(duì)應(yīng)一個(gè)交易系統(tǒng)的研發(fā)團(tuán)隊(duì),商品系統(tǒng)會(huì)對(duì)應(yīng)一個(gè)商品系統(tǒng)的研發(fā)團(tuán)隊(duì),這種職責(zé)明確的組織結(jié)構(gòu)會(huì)使得系統(tǒng)開發(fā)更高效。

(圖片來自網(wǎng)絡(luò))

《未來架構(gòu)》一書中講過一個(gè) AKF 立方體模型,從三個(gè)緯度講述功能拆分、水平擴(kuò)展、數(shù)據(jù)分區(qū)所產(chǎn)生的復(fù)雜度,如果只有一個(gè)系統(tǒng),單臺(tái)部署,單點(diǎn)存儲(chǔ),那么它就應(yīng)該只是一個(gè)點(diǎn),因?yàn)殡S著量級(jí)的增大,系統(tǒng)在每個(gè)緯度不斷延長(zhǎng),逐漸成為一個(gè)龐大的立方體。

(圖片來自網(wǎng)絡(luò))

拆分可以分為系統(tǒng)拆分、功能拆分和讀寫拆分。如一個(gè)單體系統(tǒng)中,按照用戶的交互場(chǎng)景看,門戶首頁可以拆分為前臺(tái)系統(tǒng),類目、商品、搜索等功能可以拆分到商品中心,訂單、結(jié)算、發(fā)票等功能則可以拆分到交易中心,這就是簡(jiǎn)單的系統(tǒng)拆分和功能拆分。而有些功能較為特殊,如商詳頁,在讀取時(shí)需要聚合讀取,所以又可以進(jìn)行讀寫拆分。

2,服務(wù)化

微服務(wù)首先需要有微服務(wù)基礎(chǔ)設(shè)施,沒有微服務(wù)基礎(chǔ)設(shè)施,實(shí)踐微服務(wù)就是一場(chǎng)災(zāi)難。以 SOA 落地方式為例,SOA 落地方式主要有:分布式服務(wù)化和集中式管理(ESB),分布式服務(wù)化的技術(shù)手段有 dubbo 或 spring cloud 等等,必須有整套的如服務(wù)發(fā)現(xiàn)、服務(wù)訂閱、服務(wù)監(jiān)控、服務(wù)追蹤、服務(wù)日志等微服務(wù)基礎(chǔ)設(shè)置,才能進(jìn)行微服務(wù)架構(gòu)。不能簡(jiǎn)單只有 p2p 的服務(wù)調(diào)用就開始服務(wù)化,那是不現(xiàn)實(shí)的。

3,服務(wù)治理

當(dāng)服務(wù)拆分的設(shè)計(jì)方案確認(rèn)完畢,而服務(wù)化的基礎(chǔ)設(shè)施也部署到位,那么系統(tǒng)往往一下子就會(huì)突然發(fā)布出成百上千個(gè)服務(wù)接口,就像一個(gè)網(wǎng)絡(luò)一樣,每個(gè)服務(wù)或微服務(wù)就像網(wǎng)中的一個(gè)節(jié)點(diǎn),彼此之間關(guān)聯(lián)和聯(lián)系。但是,服務(wù)網(wǎng)絡(luò)應(yīng)該被設(shè)計(jì)成為一個(gè)有向無環(huán)圖,否則,就是一團(tuán)麻。如開始的時(shí)候,只是 A 調(diào)用 B,但隨著業(yè)務(wù)發(fā)展,需要修改,但是因?yàn)閷?duì) A 不了解,就加個(gè)環(huán)節(jié) B 調(diào)用 A,如此形成了環(huán)形調(diào)用,不僅邏輯復(fù)雜了,還降低了穩(wěn)定和性能。

這里的服務(wù)治理不是講中間件團(tuán)隊(duì)的服務(wù)治理,如超時(shí)優(yōu)化、啟動(dòng)優(yōu)化等等,而是作為應(yīng)用平臺(tái)對(duì)服務(wù)的治理。服務(wù)治理又分為三個(gè)階段:服務(wù)梳理、服務(wù)界定和服務(wù)編排。所謂服務(wù)梳理就是梳理系統(tǒng)對(duì)外開放的服務(wù)化接口,包括服務(wù)的 provider 和 consumer,以及服務(wù)分組、動(dòng)態(tài)路由等依賴的梳理,然后對(duì)拆散的服務(wù)進(jìn)行歸類、界定,確定服務(wù)領(lǐng)域從屬性,依據(jù)領(lǐng)域模型重新界定服務(wù)邊界,最后通過服務(wù)遷移、切換,對(duì)同一領(lǐng)域的服務(wù)接口進(jìn)行服務(wù)整合,提供統(tǒng)一的服務(wù)出口,實(shí)現(xiàn)服務(wù)編排。

為什么要進(jìn)行服務(wù)治理?那先來看看不進(jìn)行服務(wù)治理的壞處。

微服務(wù)化拆分必然會(huì)在初期產(chǎn)生代碼到處拷貝,沒有一套代碼,必然會(huì)造成復(fù)雜的擴(kuò)散,如同樣語意的 A、B 兩個(gè)接口,如果 A 接口存在性能問題需要加緩存,那么 B 接口也會(huì)存在同樣的問題,并需要同樣的改造,這樣復(fù)雜度就會(huì)到處蔓延,同時(shí)也無法實(shí)現(xiàn)統(tǒng)一的服務(wù)層架構(gòu),還有,如果同樣語意或相似語意的接口太多,那么接口就是混亂的,無法實(shí)現(xiàn)有限接口的治理,如果系統(tǒng)出了問題,可能很難定位問題。業(yè)務(wù)邏輯是依賴于數(shù)據(jù)的,如果接口是混亂的,那么慢 SQL 等質(zhì)量差的 SQL 就無法進(jìn)行有效收口改造,同樣就更加難以實(shí)現(xiàn)數(shù)據(jù)庫拆分和解耦。綜上,服務(wù)治理的過程就是從無序到有序的過程。

總結(jié)一下看從拆分到服務(wù)化的過程,就是將原來一個(gè)整體的服務(wù)打碎,碎成一塊一塊的零碎服務(wù),然后再對(duì)服務(wù)重新歸類、整合,形成一個(gè)一個(gè)新領(lǐng)域的、獨(dú)立的服務(wù)。如單體架構(gòu)就像一個(gè)宏偉的城堡,如果相對(duì)其中一個(gè)點(diǎn)進(jìn)行調(diào)整和改造,那么可能面臨著牽一發(fā)而動(dòng)全身的風(fēng)險(xiǎn)。

微服務(wù)化就是以一系列小的服務(wù)去支撐一個(gè)應(yīng)用的方法論。簡(jiǎn)明扼要的說,就是:分而治之。

4,服務(wù)高可用

服務(wù)拆分并服務(wù)化之后,是不是就完事了,不!真正的微服務(wù)實(shí)踐才剛剛開始,簡(jiǎn)單提供了一個(gè)接口,是沒有意義的,它必須具備高可用、高性能、高并發(fā)的三高特性,尤以高可用最為重要。保障服務(wù)高可用的方法有很多,如數(shù)據(jù)異構(gòu)、多級(jí)緩存、超時(shí)與重試、熔斷、異步并發(fā)、降級(jí)、限流、消息隊(duì)列、壓測(cè)與預(yù)案等 。

重點(diǎn)說下數(shù)據(jù)異構(gòu),所謂數(shù)據(jù) 異構(gòu),就是將通過順序消費(fèi)或并發(fā)消費(fèi)的方式,訂閱 MySQL 數(shù)據(jù)庫的 binlog,然后通過消息,如 Kafka 等 MQ 方式,異地存儲(chǔ)到緩存或其它數(shù)據(jù)源中,如 Redis、Elasticsearch 等。數(shù)據(jù)異構(gòu)現(xiàn)在被普通使用,實(shí)現(xiàn)數(shù)據(jù)聚合,形成數(shù)據(jù)閉環(huán)。

在進(jìn)行數(shù)據(jù)異構(gòu)的過程中,需要關(guān)注幾個(gè)關(guān)鍵點(diǎn),一是 CAP 原則,即強(qiáng)一致性往往被舍棄,而采用最終一致性的設(shè)計(jì)。二是緩存,緩存在微服務(wù)架構(gòu)中,不能被當(dāng)成銀彈來使用,使用緩存必須正視的問題有:熱點(diǎn)緩存 & 大 Value 緩存、緩存穿透等問題。三是消息,消息現(xiàn)在還存在的問題有:延遲問題、消息的不穩(wěn)定性(如丟消息)、消息的不確定性(如 timeout)、消息補(bǔ)償、柔性事務(wù)等問題。而這些是微服務(wù)高可用架構(gòu)實(shí)踐中,不能不面對(duì)的問題。

5,服務(wù)隔離

隔離也是服務(wù)拆分的一種,為什么單獨(dú)講?因?yàn)榉?wù)拆分、服務(wù)化、服務(wù)治理和服務(wù)高可用都是在事前或事中可以做的,然而,有些系統(tǒng)已經(jīng)成了某個(gè)樣子,那么我們接收時(shí),首先能做到的就是迅速對(duì)系統(tǒng)進(jìn)行隔離,保證業(yè)務(wù)之間不互相影響,具體實(shí)踐包括:進(jìn)程線程隔離、集群/機(jī)房隔離、讀寫隔離、動(dòng)靜隔離、爬蟲/熱點(diǎn)隔離等。

從單體架構(gòu)開始,到分布式架構(gòu)設(shè)計(jì)、微服務(wù)架構(gòu),再到現(xiàn)在領(lǐng)域驅(qū)動(dòng)設(shè)計(jì),作為實(shí)踐微服務(wù)的架構(gòu)師,思想上又有什么變化?

我覺得,程序員都是很悶騷的,但每個(gè)程序員心里都住一個(gè)大俠,金庸《笑傲江湖》里有氣宗和劍宗之分,什么是劍宗,我理解就像是劍招、招數(shù),如 spring、spring boot、spring cloud,還有 tomcat、netty、serviceless 等,這些技術(shù)、中間件、框架等就像腳手架一樣可以幫助我們提高效率,但是,我們是否需要出現(xiàn)一個(gè)新技術(shù)就學(xué)習(xí)一個(gè)技術(shù)呢?而這就讓我想到了氣宗,它就像是通過對(duì)內(nèi)在規(guī)律的掌握,打通任督二脈,實(shí)現(xiàn)融會(huì)貫通,正如《九陽神功》所說:他強(qiáng)任他強(qiáng),清風(fēng)拂山崗,我自一口真氣足。如 Kakfa、Flink、Hbase 等分區(qū)可用性保障的設(shè)計(jì)思想都是基于 BigTable 的分區(qū)復(fù)制策略。

正是重心由外到內(nèi)的轉(zhuǎn)變,讓我認(rèn)知到,現(xiàn)在系統(tǒng)架構(gòu)的發(fā)展,很多系統(tǒng)架構(gòu)的復(fù)雜度,已經(jīng)不是簡(jiǎn)簡(jiǎn)單單通過引入一些新技術(shù)或框架,就能降低系統(tǒng)復(fù)雜的。它需要大大的提前對(duì)風(fēng)險(xiǎn)、問題、隱患的預(yù)知,做到未雨綢繆?!稄牧汩_始學(xué)架構(gòu)》書中提到:架構(gòu)設(shè)計(jì)的發(fā)展歷程就是在于降低軟件系統(tǒng)復(fù)雜的歷程。

《架構(gòu)整潔之道》書中提到:一個(gè)軟件系統(tǒng)存在的意義,是系統(tǒng)用來賺錢或省錢的那部分代碼,那才是整個(gè)系統(tǒng)的皇冠明珠。所以,當(dāng)拿到一個(gè)需求的時(shí)候,首先考慮的是要解決什么問題,它的問題域是什么,而不是先考慮用哪種技術(shù)去實(shí)現(xiàn)或解決這個(gè)問題,這是本末倒置的處理方法。

從領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)的角度來看,需求首先是問題域,屬于業(yè)務(wù)邊界的事情,梳理了解要實(shí)現(xiàn)什么功能和需求,然后在外延到工作邊界,確認(rèn)團(tuán)隊(duì)合作的方式,因?yàn)楹芏嘈枨蠖伎赡苄枰鐖F(tuán)隊(duì)合作的,最后才會(huì)到應(yīng)用邊界,即技術(shù)實(shí)現(xiàn)的解決問題領(lǐng)域。

上圖是一個(gè)典型的洋蔥頭模型,它的思想就是闡述了從內(nèi)到外的思考過程。然后,現(xiàn)實(shí)工作中,經(jīng)常有人從外往內(nèi)去考慮問題,從我過往的經(jīng)歷舉例,一次是數(shù)據(jù)異構(gòu)的方案,之前是采用 Storm,后來 flink 開始流行,我就將業(yè)務(wù)切換到了 flink,但是對(duì)于 flink 的調(diào)優(yōu)不到位,從而影響了系統(tǒng)穩(wěn)定性,還有一次是之前搜索用 solr,后來 es 開始流行,就像切到 es,但是 es 和 solr 兩套搜索引擎的搜索排序結(jié)果是不一樣的,最后,我們只能強(qiáng)奸了業(yè)務(wù)。其實(shí),這都是不太對(duì)的。《架構(gòu)整潔之道》也提到:良好的架構(gòu)設(shè)計(jì)應(yīng)該盡可能地允許用戶推遲和延后決定采用什么框架、數(shù)據(jù)庫、Web 服務(wù)以及其他與環(huán)境相關(guān)的工具。

理解領(lǐng)域驅(qū)動(dòng)設(shè)計(jì),需求或問題它開始于一個(gè)領(lǐng)域意愿,由領(lǐng)域?qū)<液徒桓秷F(tuán)隊(duì)一起,輸出統(tǒng)一語言和領(lǐng)域知識(shí),統(tǒng)一語言可以是敏捷看板,因?yàn)橐粋€(gè)團(tuán)隊(duì)是由產(chǎn)品、運(yùn)營(yíng)、研發(fā)、測(cè)試組成的,彼此之間是基于統(tǒng)一語言進(jìn)行溝通的,然后定義領(lǐng)域邊界,區(qū)分核心領(lǐng)域、普通領(lǐng)域、支持領(lǐng)域,其中核心領(lǐng)域就是由核心團(tuán)隊(duì)開發(fā)的,支持領(lǐng)域可以是外包等實(shí)現(xiàn)的,在通過映射上下文,確認(rèn)限界上下文,最終確認(rèn)系統(tǒng)應(yīng)用邊界。https://mp.weixin.qq.com/

(圖片來自網(wǎng)絡(luò))

采用領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)的六邊形架構(gòu)繪制了一張交易系統(tǒng)的領(lǐng)域邊界圖,不同顏色表明不同領(lǐng)域,U/D 代表上游和下游。這個(gè)圖還不算完整,因?yàn)轭I(lǐng)域業(yè)務(wù)邏輯是要為端服務(wù)的,而通過對(duì)領(lǐng)域的梳理,可以通用的支持很多端。即表達(dá)為領(lǐng)域有界,端×××。最 終,每個(gè)限界上下文即是微服務(wù)。

其實(shí),每個(gè)系統(tǒng)的微服務(wù)架構(gòu)演進(jìn)道路各不相同,所以,實(shí)踐微服務(wù)不能一板一眼原封照抄,而是要根據(jù)自己的業(yè)務(wù)特征,合理的裁剪,找到合適落地方案。總結(jié)一句話,那就是:因需而變。雖然微服務(wù)的路徑是不一樣的,但方向是相同的。再次回顧微服務(wù)的架構(gòu)演進(jìn)歷程,你會(huì)發(fā)現(xiàn),從單體架構(gòu)開始,進(jìn)行拆分,形成微服務(wù)之后,又因?yàn)楦鞣N這樣的原因,很多微服務(wù)架構(gòu)又在進(jìn)行合并,現(xiàn)在領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)來了,又開始重新拆分。真可謂:話說天下大勢(shì),分久必合,合久必分。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI