進(jìn)階的程序員:什么是微服務(wù)?
微服務(wù)microservice
微服務(wù)是指提供單個(gè)業(yè)務(wù)功能的服務(wù),從技術(shù)角度看就是一種小而獨(dú)立的處理過程,類似流程概念,能夠自行單獨(dú)啟動(dòng)或銷毀,擁有自己獨(dú)立的數(shù)據(jù)庫。
一個(gè)復(fù)雜軟件架構(gòu)是由很多這樣小而獨(dú)立運(yùn)行(有自己的端口)微服務(wù)組成,這些獨(dú)立處理組件之間通訊是通過與語言無關(guān)的API進(jìn)行,簡單協(xié)議有同步性質(zhì)的RMI/RPC和 RESTful Web Services,異步的消息推送和Reactive方式。
這些模塊化的方式能夠使得公司將項(xiàng)目分解分散到多個(gè)開發(fā)團(tuán)隊(duì),跨不同業(yè)務(wù)部門,提供非常充分的靈活性,幫助提高項(xiàng)目的生命周期,加快項(xiàng)目開發(fā)完成效率。
每個(gè)微服務(wù)組件都有自己分配的存儲(chǔ) 內(nèi)存和CPU資源,這就使得硬件利用更加易于優(yōu)化和跟蹤,特別是在基于云的Pass環(huán)境,開發(fā)團(tuán)隊(duì)可以使用他們喜歡的技術(shù),任何語言都可以,只要確保微服務(wù)之間是可交互的,能夠組合起后面的應(yīng)用。
當(dāng)管理復(fù)雜性會(huì)因?yàn)椴扇∥⒎?wù)架構(gòu)而降低,通常更新其中一個(gè)微服務(wù)組件不會(huì)引起連鎖反應(yīng),因?yàn)槲⒎?wù)之間是松耦合的。
目前使用微服務(wù)的企業(yè)有:Netflix Twitter Amazon Web Services (AWS), Google, eBay等。
因?yàn)橛泻芏鄳?yīng)用和服務(wù)部署在基于云主機(jī)的環(huán)境中,微服務(wù)架構(gòu)將會(huì)嚴(yán)重依賴容器技術(shù),容器隔離了微服務(wù)處理過程,將一個(gè)應(yīng)用切分為一個(gè)個(gè)小的實(shí)例,這些容器中的小實(shí)例有自己的端口和虛擬化環(huán)境。
廣泛使用的容器技術(shù)是Docker, 一種基于Linux的開源實(shí)現(xiàn),由很多軟件公司支持如 Canonical, Red Hat,和Parallels. PaaS服務(wù)支持包括Google App Engine, Red Hat Open Shift,和VMware的 Cloud Foundry,。
微服務(wù)架構(gòu)不只是傳統(tǒng)服務(wù)變微變小。微服務(wù)兩個(gè)顯著特點(diǎn)是:
- 微服務(wù)本身是無狀態(tài)的;
- 微服務(wù)之間很少可變共享。
可以設(shè)想一下,如果微服務(wù)之間可以共享,那么帶來兩個(gè)問題:微服務(wù)團(tuán)隊(duì)之間需要合作,因?yàn)楣蚕淼氖且粋€(gè)統(tǒng)一數(shù)據(jù)庫,如果這種共享沒有帶來溝通成本,沒有破壞一個(gè)團(tuán)隊(duì)就能搞定的宗旨,那么這種共享數(shù)據(jù)庫也是可以考慮,但是這種情況很少,大部分團(tuán)隊(duì)因?yàn)楣蚕韱栴}破壞了獨(dú)立性;再者,微服務(wù)如果使用Docker分別打包在一個(gè)容器中,這些容器可能是跨不同基礎(chǔ)設(shè)施部署,部署方式很靈活,是一種cloud native應(yīng)用,而共享數(shù)據(jù)庫屬于底層基礎(chǔ)設(shè)施,顯然提高了部署難點(diǎn)。
另外,傳統(tǒng)服務(wù)之間通訊無論是RPC/RMI或是Http/RESTful都是同步的,而微服務(wù)之間通信應(yīng)該是異步的或reactive的,也就是非同步的。根據(jù)FLP不可能原理,網(wǎng)絡(luò)默認(rèn)是不可靠的,RPC在一旦發(fā)生網(wǎng)絡(luò)堵塞會(huì)連環(huán)爆炸,事后監(jiān)控并不能根本解決這個(gè)問題,需要從CAP定理角度進(jìn)行平衡設(shè)計(jì),引入事件驅(qū)動(dòng)或Pub/Sub消息方式能在提高網(wǎng)絡(luò)容錯(cuò)性的同時(shí),保證數(shù)據(jù)最終一致性,柔性事務(wù)是微服務(wù)環(huán)境的主要選擇。
傳統(tǒng)服務(wù)變成鐵板一塊經(jīng)常是因?yàn)槭聞?wù)處理要求,某個(gè)服務(wù)方法的代碼很多,需要塞在同一個(gè)事務(wù)邊界內(nèi),雖然這帶來了高一致性的,但是擴(kuò)展性比較差,因?yàn)橥粋€(gè)事務(wù)邊界內(nèi)的動(dòng)作無法分離到幾個(gè)微服務(wù)中,因此,使用微服務(wù)必須積極擁抱最終一致性,對分布式系統(tǒng)以及CAP定理有一定理解。當(dāng)然,這些都是必須有多個(gè)微服務(wù)調(diào)用的情況下才需要考慮,由于微服務(wù)粒度小且專一,可以通過組合替代共享繼承的思路,容忍代碼有一定的重復(fù)性。
一個(gè)微服務(wù)架構(gòu)需要具備以下條件:
- 基礎(chǔ)監(jiān)視 測量和健康檢查
- 分布式日志 跟蹤
- 針對每個(gè)服務(wù),不只是隔離代碼,還需要在構(gòu)建+測試+打包+提交整個(gè)環(huán)節(jié)隔離。
- 能清晰定義每個(gè)服務(wù)的上下游、編譯時(shí)間和運(yùn)行依賴。
- 掌握如何構(gòu)建、暴露和維護(hù)好的API和合約。
- 需要尊重b/w和f/w兼容性,即使你可能不同時(shí)是你生產(chǎn)的服務(wù)的消費(fèi)者。
- 好的單元測試和更具有可讀性
- 注意微服務(wù)與模塊和庫包區(qū)別,以及分布式整體型monolith, 協(xié)同版本發(fā)布,數(shù)據(jù)庫驅(qū)動(dòng)繼承的區(qū)別。
- 知道基礎(chǔ)設(shè)施的自動(dòng)化
- 需要基于CI/CD持續(xù)集成/持續(xù)遞交的基礎(chǔ)設(shè)施
服務(wù)劃分:
- 根據(jù)業(yè)務(wù)能力界定服務(wù)的范圍
- 根據(jù)領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)中子域的概念界定服務(wù)的范圍
通訊模式:
- 使用基于RPC的同步通訊方式
- 使用異步消息進(jìn)行服務(wù)間通訊
外部API:
- API 網(wǎng)關(guān)(API gateway) - 為每一類客戶端提供一個(gè)訪問服務(wù)的獨(dú)特接口
- 服務(wù)前端的后端(Backend for front-end) - 為每一類客戶端都提供一個(gè)獨(dú)立的 API 網(wǎng)關(guān)
數(shù)據(jù)管理:
- 每個(gè)服務(wù)都擁有它私有的數(shù)據(jù)庫特接口
- 服務(wù)之間共享同一個(gè)數(shù)據(jù)庫
- 使用事件來維護(hù)服務(wù)間的數(shù)據(jù)一致性 事件溯源/CQRS
運(yùn)維監(jiān)控:
- 服務(wù)的發(fā)現(xiàn):通過第三方模塊來進(jìn)行服務(wù)實(shí)例信息到服務(wù)注冊表的注冊過程
- 分布式追蹤(Distributed tracing)new - 在服務(wù)代碼中針對每一個(gè)外部訪問,都分配一個(gè)服務(wù)標(biāo)識(shí)符,并在跨服務(wù)訪問時(shí)傳遞這個(gè)標(biāo)識(shí)符以供追蹤分布式引發(fā)
- 斷路器(Circuit Breaker) - 當(dāng)遠(yuǎn)端服務(wù)返回的故障率超過一定的閥值時(shí),客戶端代理(比如 API 網(wǎng)關(guān))對遠(yuǎn)程服務(wù)的調(diào)用將立刻返回失敗的信息