系統(tǒng)架構(gòu)的演變
伴隨著互聯(lián)網(wǎng)的快速發(fā)展,Web應(yīng)用系統(tǒng)從面向企業(yè)內(nèi)部發(fā)展到面向市場(chǎng)用戶(hù),業(yè)務(wù)的日趨復(fù)雜以及用戶(hù)量的上升产徊,那些曾經(jīng)工作良好的單體應(yīng)用開(kāi)始遇到開(kāi)發(fā)、測(cè)試蜀细、部署舟铜、發(fā)布各個(gè)方面的瓶頸,諸如擴(kuò)展新增功能艱難
奠衔、系統(tǒng)龐大難以維護(hù)
谆刨、編譯太耗時(shí),發(fā)布流程太慢
等問(wèn)題困擾著開(kāi)發(fā)團(tuán)隊(duì)涣觉。
SOA的問(wèn)世促使系統(tǒng)架構(gòu)發(fā)生了跨越式的演變痴荐,它提出了面向服務(wù)的架構(gòu)思想,將系統(tǒng)拆分成多個(gè)服務(wù)組件官册,并通過(guò)ESB(企業(yè)服務(wù)總線(xiàn))對(duì)服務(wù)組件進(jìn)行統(tǒng)一管理生兆,但重量級(jí)的ESB使得自身又成為了一個(gè)瓶頸。隨之而來(lái)的是近來(lái)業(yè)界流行的微服務(wù)架構(gòu),它將SOA的思想進(jìn)一步升級(jí)鸦难,將系統(tǒng)組件化根吁、服務(wù)化以及去中心化,強(qiáng)調(diào) 輕量級(jí)
合蔽、松耦合
击敌、服務(wù)自治
、獨(dú)立部署
拴事。
微服務(wù)架構(gòu)解決了單體應(yīng)用的痛點(diǎn)沃斤,打破了SOA的瓶頸,同時(shí)也帶來(lái)了很多的復(fù)雜性刃宵。部署運(yùn)維方面衡瓶,服務(wù)的部署、管理牲证、監(jiān)控哮针。開(kāi)發(fā)設(shè)計(jì)方面,服務(wù)的拆分坦袍、設(shè)計(jì)十厢、編碼、測(cè)試都將會(huì)變得復(fù)雜捂齐。幸運(yùn)的是蛮放,容器化技術(shù)(比如無(wú)比流行的Docker)已經(jīng)很大程度上幫助我們克服了環(huán)境的差異性,而一些容器編排工具諸如Kubernetes, Rancher, Docker-compose 提供了容器部署管理的解決方案辛燥。作為行業(yè)的領(lǐng)航者筛武,ThoughtWorks也在極力倡導(dǎo) 開(kāi)發(fā)、設(shè)計(jì)挎塌、部署徘六、運(yùn)維一體化 的DEVOPS文化理念,并通過(guò)豐富的咨詢(xún)和交付成果來(lái)幫助企業(yè)研發(fā)團(tuán)隊(duì)更好地實(shí)施微服務(wù)架構(gòu)的開(kāi)發(fā)榴都。
那么在編碼測(cè)試方面待锈,又有什么新招來(lái)保證微服務(wù)架構(gòu)下系統(tǒng)的質(zhì)量?
本文將從開(kāi)發(fā)測(cè)試的視角來(lái)探討如何在微服務(wù)架構(gòu)下通過(guò)不一樣的測(cè)試策略來(lái)盡可能的保證系統(tǒng)的質(zhì)量嘴高。
單體應(yīng)用測(cè)試實(shí)踐
當(dāng)我們的意識(shí)中只存在一樣?xùn)|西的時(shí)候竿音,我們便可以不假思索的拿來(lái)就用。
在單體時(shí)代拴驮,對(duì)于開(kāi)發(fā)-測(cè)試-部署春瞬,業(yè)界已經(jīng)具備了一套很成熟的解決方案√灼。基于這種方案宽气,當(dāng)一個(gè)敏捷開(kāi)發(fā)的小Team開(kāi)始構(gòu)建一個(gè)應(yīng)用之前,CI搭建的過(guò)程也會(huì)變得非常簡(jiǎn)單:CI只需要從一個(gè)代碼庫(kù)中去pull代碼,然后編譯-測(cè)試-部署萄涯,它的流程可以簡(jiǎn)化成:
在這種單線(xiàn)流水線(xiàn)模式下绪氛,如果團(tuán)隊(duì)的自動(dòng)化實(shí)踐做得很好,開(kāi)發(fā)人員只需要關(guān)注自己編寫(xiě)代碼時(shí)所編寫(xiě)的測(cè)試的質(zhì)量和數(shù)量涝影。整個(gè)應(yīng)用的測(cè)試策略簡(jiǎn)單直接:
保證足夠的單元測(cè)試的覆蓋率枣察,保持一定數(shù)量的Servcie測(cè)試,添加一些重要業(yè)務(wù)流程的E2E測(cè)試燃逻。
微服務(wù)測(cè)試的演變
微服務(wù)架構(gòu)是一種演進(jìn)式架構(gòu)序目,開(kāi)發(fā)團(tuán)隊(duì)跟領(lǐng)域?qū)<以谝黄疬M(jìn)行業(yè)務(wù)分析(Event Storming),從而劃分出獨(dú)立的服務(wù)唆樊,系統(tǒng)一開(kāi)始確定為獨(dú)立服務(wù)的數(shù)量可能是幾個(gè)宛琅,伴隨著業(yè)務(wù)的復(fù)雜深入,會(huì)不斷地衍生出新的服務(wù)逗旁。下圖是一個(gè)包含了四個(gè)服務(wù)的微服務(wù)架構(gòu)的系統(tǒng):
微服務(wù)體系中的諸多服務(wù)不可避免跨服務(wù)調(diào)用,它們通常使用輕量級(jí)的HTTP RESTful API舆瘪。那么如何保證跨服務(wù)調(diào)用的可靠性以及整個(gè)系統(tǒng)集成的質(zhì)量片效?尤其是當(dāng)不同服務(wù)由不同小團(tuán)隊(duì)負(fù)責(zé)開(kāi)發(fā)和測(cè)試。
服務(wù)自身的Unit測(cè)試
系統(tǒng)被拆分成獨(dú)立的服務(wù)英古,每個(gè)服務(wù)都是一個(gè)完整的小系統(tǒng)淀衣,首要工作仍然是保證服務(wù)自身的業(yè)務(wù)功能的正確性。比如一個(gè)Java Web應(yīng)用(Springboot)召调,API功能以及各個(gè)Service的業(yè)務(wù)邏輯的正確性膨桥,可以通過(guò)單元測(cè)試來(lái)保證。服務(wù)細(xì)分之后從某種意義上讓單元測(cè)試更加易于編寫(xiě)唠叛,可以借助測(cè)試替身來(lái)屏蔽掉對(duì)其他服務(wù)依賴(lài)只嚣。
系統(tǒng)級(jí)的集成(UI)測(cè)試
Unit測(cè)試使得開(kāi)發(fā)人員可以快活地活在自己的世界中,每個(gè)開(kāi)發(fā)團(tuán)隊(duì)按照?qǐng)D紙?jiān)斐鱿到y(tǒng)的一個(gè)部件艺沼,只有當(dāng)這些小部件集成在一起之后能夠按照用戶(hù)的期望為用戶(hù)提供服務(wù)才體現(xiàn)出了系統(tǒng)業(yè)務(wù)價(jià)值册舞。所以我們要通過(guò)系統(tǒng)集成測(cè)試(UI測(cè)試)來(lái)保證集成的質(zhì)量。
從 測(cè)試金字塔 中可以看出障般,在一個(gè)系統(tǒng)中调鲸,UI測(cè)試是數(shù)量最少的。雖然它的業(yè)務(wù)價(jià)值最高挽荡,但它高昂的成本使得它只會(huì)覆蓋業(yè)務(wù)流程復(fù)雜的業(yè)務(wù)場(chǎng)景茁帽。甚至,當(dāng)一個(gè)微服務(wù)架構(gòu)系統(tǒng)中服務(wù)個(gè)數(shù)量達(dá)到一定之后胚想,很多開(kāi)發(fā)團(tuán)隊(duì)對(duì)UI測(cè)試開(kāi)始望而卻步蹋嵌,因?yàn)樵谝粋€(gè)存在多個(gè)服務(wù)的系統(tǒng)中(即便單體應(yīng)用系統(tǒng))做集成測(cè)試,會(huì)面臨諸多痛點(diǎn):
1. 需要維護(hù)完整的運(yùn)行環(huán)境,成本很高角雷。
2. 環(huán)境不穩(wěn)定(UI不穩(wěn)定)導(dǎo)致測(cè)試隨機(jī)掛祸穷,功能增強(qiáng)很容易破壞大量測(cè)試。
3. 問(wèn)題難定位勺三,修復(fù)時(shí)間太長(zhǎng)雷滚,影響Pipeline的推進(jìn)。
4. 運(yùn)行速度慢吗坚,反饋周期長(zhǎng)祈远。
5. 存在重復(fù)測(cè)試已測(cè)試的功能。
這些痛點(diǎn)在很大程度上會(huì)削減一個(gè)開(kāi)發(fā)團(tuán)隊(duì)的生產(chǎn)力商源,某些企業(yè)會(huì)雇一個(gè)QA進(jìn)行重復(fù)的人工測(cè)試從而解放開(kāi)發(fā)人員的生產(chǎn)力车份。這種措施有悖于追求卓越的理念,并沒(méi)有從本質(zhì)上解決系統(tǒng)的集成的質(zhì)量問(wèn)題牡彻。既然UI測(cè)試已經(jīng)不適用引進(jìn)了微服務(wù)架構(gòu)的開(kāi)發(fā)團(tuán)隊(duì)扫沼,要如何保證服務(wù)集成的質(zhì)量,我們還需要在自動(dòng)化測(cè)試道路上另辟蹊徑庄吼。
Pair集成測(cè)試
系統(tǒng)級(jí)別的集成測(cè)試阻礙重重缎除,我們不妨退一步思考,將集成的范圍縮小 保證服務(wù)倆倆的集成的可靠性总寻。有了這個(gè)想法器罐,我們開(kāi)始對(duì)服務(wù)倆倆配對(duì)做集成測(cè)試。測(cè)試架構(gòu)演變成:
我們需要真實(shí)運(yùn)行待測(cè)試的服務(wù)渐行,并且對(duì)其他服務(wù)使用替身轰坊。不難看出這種方式存在以下問(wèn)題:
1. 需要運(yùn)行待集成的真實(shí)服務(wù),存在環(huán)境不穩(wěn)定導(dǎo)致維護(hù)成本增加祟印。
2. 需要Mock掉其他服務(wù)肴沫,增加了額外的工作量。
3. 存在大量重復(fù)測(cè)試已經(jīng)測(cè)試的功能旁理。
雖然Pair集成測(cè)試沒(méi)有從根本上解決UI測(cè)試的痛點(diǎn)樊零,但它提出了 積小成多 的理念,該理念告訴我們:只要能夠保證服務(wù)倆倆之間的集成是可靠的孽文,我們就可以相信系統(tǒng)集成也是可靠的驻襟。
引入Contract概念的集成測(cè)試
就在兩年前,我在珠海出差的某項(xiàng)目上跟小伙伴一起嘗試了一種集成測(cè)試方案芋哭。當(dāng)時(shí)項(xiàng)目采用的是前后端分離開(kāi)發(fā)沉衣,后端作為服務(wù)提供者提供RESTful API,前端作為消費(fèi)者消費(fèi)API减牺。
為了保證前后端開(kāi)發(fā)人員并行開(kāi)展工作豌习,我們引入了Contarct概念存谎。前后端開(kāi)發(fā)人員基于業(yè)務(wù)共同定義API協(xié)議(Contract),該協(xié)議以JSON文件存在于代碼庫(kù)的測(cè)試資源目錄中肥隆,前端在開(kāi)發(fā)過(guò)程中以JSON文件作為測(cè)試的斷言依據(jù)既荚。而后端開(kāi)發(fā)人員則參照該協(xié)議內(nèi)容來(lái)實(shí)現(xiàn)API。
基于這種方案栋艳,前后端開(kāi)發(fā)人員如果都遵守了協(xié)議恰聘,聯(lián)調(diào)的過(guò)程就會(huì)非常順利。而它的優(yōu)勢(shì)也很明顯的體現(xiàn)出來(lái):
1. 不需要運(yùn)行其他服務(wù)吸占,環(huán)境簡(jiǎn)單晴叨,運(yùn)行快。
2. 測(cè)試可控范圍縮小到單個(gè)服務(wù)內(nèi)部矾屯。
3. 按照Contract兼蕊,各自編寫(xiě)代碼并測(cè)試。
前后端本質(zhì)上等價(jià)于服務(wù)提供方和服務(wù)消費(fèi)方件蚕,所以該理念運(yùn)用在微服務(wù)之間的集成測(cè)試中孙技,系統(tǒng)的測(cè)試架構(gòu)會(huì)得到進(jìn)一步演進(jìn):
我么在享受著它帶來(lái)的好處的同時(shí),問(wèn)題也偷偷地潛入系統(tǒng)中骤坐。不久后绪杏,CI就報(bào)警了:UI測(cè)試測(cè)試掛了
進(jìn)行一番debug之后我們定位到了問(wèn)題,解開(kāi)了 按照Contract單獨(dú)運(yùn)行測(cè)試一切OK纽绍,為什么上集成環(huán)境就莫名其妙掛掉!
的疑惑:
// 兩天前
request {
method 'POST'
url '/users'
body([
name: $(regex('[a-z]{6, 20}')),
email: 'sjyuan@thoughtworks.com',
homePage: 'http://sjyuan.cc'
])
headers {
contentType('application/json')
}
}
// 兩天后
request {
method 'POST'
url '/users'
body([
name: $(regex('[a-z]{6, 20}')),
email: 'sjyuan@thoughtworks.com',
homePage: 'http://sjyuan.cc',
gender: 'M'
])
headers {
contentType('application/json')
}
}
通過(guò)Git歷史記錄發(fā)現(xiàn)服務(wù)消費(fèi)方(前端)將API協(xié)議更新了势似,而服務(wù)提供方(后端)沒(méi)有同步修改實(shí)現(xiàn)拌夏。
回顧一下引入Contract概念的集成測(cè)試
,之所以會(huì)出現(xiàn)協(xié)議的修改直到集成環(huán)境中才暴露出來(lái)履因,是因?yàn)槿狈ψ詣?dòng)化監(jiān)控機(jī)制來(lái)提前發(fā)現(xiàn)問(wèn)題并預(yù)警障簿。讓我們做進(jìn)一步深入思考:把同一份API契約作為服務(wù)提供方和服務(wù)消費(fèi)方的測(cè)試斷言依據(jù),一旦契約被一方改動(dòng)栅迄,則另一方的測(cè)試便會(huì)失敗站故。
歸根結(jié)底,我們?nèi)狈σ环N有效的強(qiáng)制約束來(lái)約束雙方毅舆,馬上要揭曉的 消費(fèi)者驅(qū)動(dòng)契約測(cè)試
可以能夠提供這種有效約束的解決方案西篓。
CDCT(消費(fèi)者驅(qū)動(dòng)契約測(cè)試)
消費(fèi)者驅(qū)動(dòng)契約測(cè)試的流程是,消費(fèi)者定義他們期望的API或消息是什么樣子憋活,這些期望即為契約岂津,從這些契約可以生成存根,此后消費(fèi)者團(tuán)隊(duì)可以在構(gòu)建過(guò)程中重復(fù)使用它們悦即。消費(fèi)者和生產(chǎn)者都需要驗(yàn)證契約吮成。
CDCT強(qiáng)調(diào)契約由消費(fèi)者來(lái)驅(qū)動(dòng)橱乱,并由雙方共同遵守,核心是共同遵守粱甫。
那么如何保證共同遵守呢泳叠?
敏捷宣言中提到 可工作的軟件 優(yōu)于 面面俱到的文檔
。引入Contract概念的測(cè)試會(huì)定義一個(gè)Contract文檔(JSON協(xié)議文件)茶宵。對(duì)于消費(fèi)方危纫,該文檔被用作測(cè)試斷言依據(jù),文檔被轉(zhuǎn)換成一個(gè)可工作的軟件
(可執(zhí)行的測(cè)試套件:修改文檔會(huì)導(dǎo)致測(cè)試失斀谠ぁ)叶摄。而對(duì)于服務(wù)提供方,因?yàn)闇y(cè)試的斷言與Contract文檔沒(méi)有強(qiáng)制關(guān)聯(lián)安拟,它最多只能是一個(gè)面面俱到的文檔
蛤吓。
所以,只有當(dāng)雙方都將文檔轉(zhuǎn)換成可工作的軟件時(shí)糠赦,文檔的修改便會(huì)導(dǎo)致任意一方測(cè)試失敗会傲,文檔才真正成為雙方共同遵守的契約(可工作的軟件總是可靠的,文檔卻有可能已經(jīng)過(guò)期)拙泽。
消費(fèi)者驅(qū)動(dòng)契約測(cè)試中存在一個(gè)契約淌山,雙方基于契約生成可工作的測(cè)試套件:
CDCT具備了引入Contract概念集成測(cè)試
的諸多優(yōu)點(diǎn),并且通過(guò)可工作的測(cè)試套件保證了契約的一致性和實(shí)時(shí)性顾瞻。
技術(shù)實(shí)踐
運(yùn)籌帷幄之中泼疑,決勝千里之外。
三國(guó)明星諸葛亮負(fù)責(zé)運(yùn)籌帷幄荷荤,關(guān)退渗、張、趙等武將負(fù)責(zé)沖鋒陷陣蕴纳,從而決勝千里之外的硝煙戰(zhàn)場(chǎng)会油。團(tuán)隊(duì)確定了測(cè)試策略之后,應(yīng)當(dāng)交由優(yōu)秀工具來(lái)實(shí)施執(zhí)行古毛。
關(guān)于單元測(cè)試翻翩,業(yè)界已經(jīng)有非常優(yōu)秀的測(cè)試工具和框架,比如我們正在做的Springboot應(yīng)用稻薇,JUnit
, Mockito
, JMock
, Hamcrest
等都是測(cè)試工具箱里的明星嫂冻。對(duì)于CDCT,目前比較流行的有JVM框架 Spring cloud Contract颖低,以及支持多語(yǔ)言的 Pact絮吵。
如果團(tuán)隊(duì)正在開(kāi)發(fā)一個(gè)Springboot應(yīng)用,Spring cloud Contract 是一個(gè)不錯(cuò)的選擇忱屑。它使用Groovy DSL定義測(cè)試契約并生成測(cè)試套件蹬敲,測(cè)試套件去驗(yàn)證服務(wù)提供方是否滿(mǎn)足契約暇昂,測(cè)試通過(guò)之后會(huì)生成一個(gè)jar文件,該jar文件隨后會(huì)作為一個(gè)可運(yùn)行的Stub server伴嗡,消費(fèi)方基于Stub server編寫(xiě)測(cè)試急波,從而驗(yàn)證功能是否滿(mǎn)足契約:
在CDCT中,不管是測(cè)試生產(chǎn)者還是測(cè)試消費(fèi)者瘪校,都需要引入一種快速失敗方法澄暮。即如果任何一方違反了契約,最好在構(gòu)建的第一分鐘就失敗阱扬,而不是等到2小時(shí)之后的集成測(cè)試中失敗泣懊。所以,我們需要將CDCT作為構(gòu)建Pipeline中的一個(gè)Stage集成到CI中麻惶。
何去何從
代價(jià)高昂的UI測(cè)試使得開(kāi)發(fā)團(tuán)隊(duì)逐漸對(duì)它失去了信心馍刮,尤其引入了微服務(wù)架構(gòu),它所帶來(lái)的復(fù)雜性使得業(yè)界摒棄UI測(cè)試的呼聲高漲窃蹋。早在2009年卡啰,著名的敏捷和TDD專(zhuān)家J.B. Rainsberger在InfoQ上提出 Integration Tests Are a Scam。
集成測(cè)試是一個(gè)騙局警没,你可能需要編寫(xiě)2-5%集成測(cè)試來(lái)做一個(gè)E2E的測(cè)試匈辱,但它們可能到處在重復(fù)單元測(cè),另外集成測(cè)試存在彼此重復(fù)杀迹。更糟糕的是亡脸,當(dāng)集成測(cè)試失敗時(shí),你不知道哪里出了問(wèn)題树酪,不能及時(shí)準(zhǔn)確定位問(wèn)題梗掰。
J.B. Rainsberger后來(lái)還在博客上發(fā)表了 《Integration Tests Are a Scam》,文章借用強(qiáng)有力的數(shù)據(jù)分析來(lái)證實(shí)自己的觀點(diǎn)嗅回。他提出的最佳實(shí)踐是:用契約測(cè)試或協(xié)議測(cè)試來(lái)做集成測(cè)試!
Martin Fowller 在2012年的 測(cè)試金字塔理論 中也指出:
應(yīng)該引入面向應(yīng)用程序服務(wù)層的中間層測(cè)試摧茴,這些測(cè)試既保持了端到端測(cè)試的諸多優(yōu)勢(shì)绵载,又避免了許多與UI框架相關(guān)的復(fù)雜性。在Web應(yīng)用程序中苛白,中間層測(cè)試相當(dāng)于API層測(cè)試娃豹,而位于金字塔頂層的UI測(cè)試則相當(dāng)于Selenium測(cè)試。
ThoughtWorks技術(shù)雷達(dá) 于2016年已經(jīng)正式采納消費(fèi)者驅(qū)動(dòng)契約測(cè)試购裙。
We’ve decided to bring consumer-driven contract testing back from the archive for this edition even though we had allowed it to fade in the past.
微服務(wù)架構(gòu)的盛行促使越來(lái)越多的開(kāi)發(fā)團(tuán)隊(duì)開(kāi)始引入CDCT懂版,逐漸淡化UI測(cè)試。團(tuán)隊(duì)的測(cè)試策略正在發(fā)生不同的演變:
引入了CDCT并擺出了正確的姿勢(shì)躏率,便可大大弱化UI測(cè)試躯畴,甚至可以使用少量的人工測(cè)試來(lái)代替自動(dòng)化UI測(cè)試民鼓。CDCT幫助我們緩解了UI測(cè)試的痛點(diǎn),但也要當(dāng)心走極端蓬抄,譬如有些團(tuán)隊(duì)的測(cè)試策略發(fā)生了下面的極端情況:
軟件工程曾經(jīng)從未產(chǎn)出銀彈丰嘉,相信未來(lái)也不會(huì),一種新的方案的誕生只是解決了已有方案的痛點(diǎn)嚷缭,好比微服務(wù)架構(gòu)解決了單體的那些痛點(diǎn)之后饮亏,卻又帶來(lái)了足夠的復(fù)雜性,從而對(duì)團(tuán)隊(duì)自身的能力提出了挑戰(zhàn)阅爽。在選擇測(cè)試策略的時(shí)候可以參考以下幾條原則:
1. 單元測(cè)試成本低路幸,運(yùn)行效率高,性?xún)r(jià)比非常高付翁,始終擺在第一位简肴。
2. 高層測(cè)試只是測(cè)試防護(hù)體系的第二防線(xiàn)。
3. 軟件開(kāi)發(fā)是一項(xiàng)成本與收益的博弈活動(dòng)胆敞,性?xún)r(jià)比高的方案應(yīng)該更加受到青睞着帽。
4. 沒(méi)有絕對(duì)的對(duì)與錯(cuò),根據(jù)自身項(xiàng)目工程和技術(shù)能力選擇適合團(tuán)隊(duì)的策略移层。
其中第二條原則強(qiáng)調(diào):如果一個(gè)高層測(cè)試失敗了仍翰,不僅僅表明功能代碼中存在bug,還意味著單元測(cè)試的欠缺观话。因此予借,無(wú)論何時(shí)修復(fù)失敗的端到端測(cè)試,都應(yīng)該同時(shí)添加相應(yīng)的單元測(cè)試频蛔。
寫(xiě)在最后
微服務(wù)架構(gòu)的復(fù)雜度不僅體現(xiàn)在技術(shù)上灵迫,與之相輔相成的是系統(tǒng)的業(yè)務(wù)架構(gòu),而技術(shù)架構(gòu)總是服務(wù)于業(yè)務(wù)架構(gòu)晦溪。優(yōu)秀的測(cè)試策略和工程技術(shù)實(shí)踐讓我們更好地構(gòu)建復(fù)雜的架構(gòu)體系并克服它所帶來(lái)的挑戰(zhàn)瀑粥,而最終決定一個(gè)系統(tǒng)成功與否在于人。所以三圆,團(tuán)隊(duì)中每一個(gè)人應(yīng)該保持Open的心態(tài)狞换,持續(xù)學(xué)習(xí),提升自己的高度(技能和業(yè)務(wù))舟肉,掌握實(shí)施微服務(wù)的相關(guān)技能修噪,比如利用DDD去做服務(wù)的劃分,從而能夠更好的駕馭微服務(wù)架構(gòu)路媚。