微服務(wù)是一種流行的體系結(jié)構(gòu)類型,用于構(gòu)建可復(fù)原、高度可縮放、可獨立部署且能快速演變的應(yīng)用程序。但是,成功的微服務(wù)體系結(jié)構(gòu)需要利用不同的方法來設(shè)計和生成應(yīng)用程序。
微服務(wù)體系結(jié)構(gòu)由一系列小型的自治服務(wù)組成。每個服務(wù)都是自包含服務(wù),并且應(yīng)實現(xiàn)單個業(yè)務(wù)功能。
什么是微服務(wù)?
微服務(wù)具有規(guī)模小、獨立和松散耦合的特點。一個小規(guī)模的開發(fā)人員團隊就能編寫和維護一個服務(wù)。
每個服務(wù)都是一個單獨的基本代碼,可由小型開發(fā)團隊管理。
服務(wù)可獨立部署。團隊可以更新現(xiàn)有服務(wù),而無需重新生成和重新部署整個應(yīng)用程序。
服務(wù)負(fù)責(zé)暫留自己的數(shù)據(jù)或外部狀態(tài)。這一點與傳統(tǒng)模型不同,后者由單獨的數(shù)據(jù)層處理數(shù)據(jù)暫留。
服務(wù)通過定義完善的API相互通信。每個服務(wù)的內(nèi)部實現(xiàn)細(xì)節(jié)均對其他服務(wù)隱藏。
服務(wù)無需共享相同的技術(shù)堆棧、庫或框架。
除了服務(wù)本身,典型微服務(wù)體系結(jié)構(gòu)中還會出現(xiàn)其他組件:
管理/業(yè)務(wù)流程.該組件負(fù)責(zé)將服務(wù)放置在節(jié)點上、確定故障,以及跨節(jié)點重新均衡服務(wù)等等。該組件通常是一種現(xiàn)成的技術(shù)(例如Kubernetes),而不是自定義構(gòu)建的內(nèi)容。
API網(wǎng)關(guān)。API網(wǎng)關(guān)是客戶端的入口點。客戶端會調(diào)用API網(wǎng)關(guān),網(wǎng)關(guān)再將調(diào)用轉(zhuǎn)發(fā)到后端上的相應(yīng)服務(wù),而不是由客戶端直接調(diào)用服務(wù)。
使用API網(wǎng)關(guān)的優(yōu)點如下:
它分離了客戶端與服務(wù)。無需更新所有客戶端,便可對服務(wù)進行版本控制或重構(gòu)。
服務(wù)可以使用對Web不友好的消息傳遞協(xié)議,比如AMQP。
API網(wǎng)關(guān)可執(zhí)行身份驗證、日志記錄、SSL終止和負(fù)載均衡等其他跨領(lǐng)域功能。
優(yōu)點
敏捷性。由于微服務(wù)是獨立部署的,因此我們可以更輕松地管理bug修復(fù)和功能發(fā)布。無需重新部署整個應(yīng)用程序即可更新服務(wù),出現(xiàn)問題時可回滾更新。在很多傳統(tǒng)應(yīng)用程序中,如果在應(yīng)用程序的一個部件中發(fā)現(xiàn)bug,它會阻止整個發(fā)布流程。新功能可能會被擱置,要等到bug修補程序后才能進行集成、測試和發(fā)布。
小型專屬團隊。微服務(wù)應(yīng)該足夠小,單個功能團隊就能構(gòu)建、測試和部署。即使團隊規(guī)模不大,也能大幅提升敏捷性。而由于溝通效率更慢、管理開銷更高且敏捷性更低,大型團隊的工作效率往往更低。
小型代碼庫。在整體式應(yīng)用程序,代碼依賴項往往會隨著時間的推移而變得混雜。因此,要在多個位置更改代碼才能添加新功能。如果不共享代碼或數(shù)據(jù)存儲,則微服務(wù)體系結(jié)構(gòu)可將依賴項減到最少,使新功能的添加變得更容易。
混合技術(shù)。團隊可以選擇最適合其服務(wù)的技術(shù),并適當(dāng)?shù)厥褂没旌霞夹g(shù)棧。
錯誤隔離。單個微服務(wù)在不可用的情況下不會中斷整個應(yīng)用程序,但前提是所有上游微服務(wù)能夠正確處理故障(例如,通過實施熔斷機制)。
可伸縮性。服務(wù)可獨立擴展,這樣你就能橫向擴展需要更多資源的子系統(tǒng),而不橫向擴展整個應(yīng)用程序。借助Kubernetes或Service Fabric等業(yè)務(wù)流程協(xié)調(diào)程序,你可將更高密度的服務(wù)打包到一臺主機中,從而提高資源的利用效率。
數(shù)據(jù)隔離。執(zhí)行架構(gòu)更新要容易得多,因為只會影響單個微服務(wù)。在整體應(yīng)用程序中,更新架構(gòu)可能極具挑戰(zhàn)性,因為應(yīng)用程序的不同部分可能都要獲取相同的數(shù)據(jù),對架構(gòu)進行任何更改都會帶來風(fēng)險。
挑戰(zhàn)
微服務(wù)的優(yōu)勢并非沒有代價。下面是在開始使用微服務(wù)體系結(jié)構(gòu)之前需要考慮的一些挑戰(zhàn)。
復(fù)雜性。與同等的單一式應(yīng)用程序相比,微服務(wù)應(yīng)用程序具有更多移動部件。每個服務(wù)更簡單,但整個系統(tǒng)作為整體來說更復(fù)雜。
開發(fā)和測試。編寫依賴于其他獨立服務(wù)的小型服務(wù)時需要的方法與編寫傳統(tǒng)的整體式或分層式應(yīng)用程序時的方法不同?,F(xiàn)有工具并非總是能夠處理服務(wù)依賴關(guān)系??绶?wù)邊界進行重構(gòu)可能很困難。測試服務(wù)依賴關(guān)系也有一定難度,尤其是在應(yīng)用程序快速發(fā)展之時。
缺乏監(jiān)管。用于生成微服務(wù)的分散式方法具有一定優(yōu)勢,但也可能導(dǎo)致許多問題。用戶在生成過程中可能采用了許多不同的語言和框架,從而使應(yīng)用程序變得難以維護。這種情況下可以實施一些項目范圍內(nèi)的標(biāo)準(zhǔn),不過分限制團隊的靈活性。這尤其適用于日志記錄等跨領(lǐng)域功能。
網(wǎng)絡(luò)擁塞和延遲。使用大量小型的精細(xì)服務(wù)可能會增加服務(wù)間的通信量。此外,如果服務(wù)依賴關(guān)系鏈變得太長(服務(wù)A調(diào)用B,B調(diào)用C...),額外延遲可能會成為一個問題。用戶需要精心設(shè)計API。應(yīng)避免過于繁瑣的API,考慮使用序列化格式,并找到可以使用異步通信模式的地方。
數(shù)據(jù)完整性。每個微服務(wù)負(fù)責(zé)自己的數(shù)據(jù)暫留。因此,數(shù)據(jù)一致性可能是個挑戰(zhàn)。如果可能,請采用最終一致性。
管理。成功使用微服務(wù)需要有成熟的DevOps區(qū)域性??绶?wù)的關(guān)聯(lián)日志記錄可能很難。通常情況下,日志記錄必須為單個用戶操作關(guān)聯(lián)多個服務(wù)調(diào)用。
版本控制。對某個服務(wù)的更新不應(yīng)中斷依賴于它的其他服務(wù)。多個服務(wù)可在任意給定時間更新,因此,若不精心設(shè)計,可能會遇到向后或向前兼容性問題。
技能集。微服務(wù)是一種高度分布式系統(tǒng)。請仔細(xì)評估團隊是否具有成功使用微服務(wù)所需的技能和經(jīng)驗。
微服務(wù)體系結(jié)構(gòu)的構(gòu)建流程
此處所列文章介紹了用于設(shè)計、構(gòu)建和操作微服務(wù)體系結(jié)構(gòu)的結(jié)構(gòu)化方法。
域分析。為了避免設(shè)計微服務(wù)時會出現(xiàn)的某些常見錯誤,請使用域分析來定義微服務(wù)邊界。執(zhí)行以下步驟:
使用域分析為微服務(wù)建模。
使用戰(zhàn)術(shù)性DDD來設(shè)計微服務(wù)。
確定微服務(wù)邊界。
設(shè)計服務(wù)。微服務(wù)需要利用不同的方法來設(shè)計和生成應(yīng)用程序。有關(guān)詳細(xì)信息,請參閱設(shè)計微服務(wù)體系結(jié)構(gòu)。
在生產(chǎn)環(huán)境中操作。由于微服務(wù)體系結(jié)構(gòu)是分布式的,因此你必須對部署和監(jiān)視提供可靠的操作。
適用于微服務(wù)體系結(jié)構(gòu)的CI/CD
在Kubernetes上為微服務(wù)構(gòu)建CI/CD管道
監(jiān)視在Azure Kubernetes服務(wù)(AKS)上運行的微服務(wù)
Azure的微服務(wù)參考體系結(jié)構(gòu)
Azure Kubernetes服務(wù)(AKS)上的微服務(wù)體系結(jié)構(gòu)
Azure Service Fabric上的微服務(wù)體系結(jié)構(gòu)