進(jìn)階的程序員:什么是微服務(wù)?
微服務(wù)microservice
微服務(wù)是指提供單個(gè)業(yè)務(wù)功能的服務(wù),從技術(shù)角度看就是一種小而獨(dú)立的處理過(guò)程,類似流程概念,能夠自行單獨(dú)啟動(dòng)或銷毀,擁有自己獨(dú)立的數(shù)據(jù)庫(kù)。
一個(gè)復(fù)雜軟件架構(gòu)是由很多這樣小而獨(dú)立運(yùn)行(有自己的端口)微服務(wù)組成,這些獨(dú)立處理組件之間通訊是通過(guò)與語(yǔ)言無(wú)關(guān)的API進(jìn)行,簡(jiǎn)單協(xié)議有同步性質(zhì)的RMI/RPC和 RESTful Web Services,異步的消息推送和Reactive方式。
這些模塊化的方式能夠使得公司將項(xiàng)目分解分散到多個(gè)開(kāi)發(fā)團(tuán)隊(duì),跨不同業(yè)務(wù)部門,提供非常充分的靈活性,幫助提高項(xiàng)目的生命周期,加快項(xiàng)目開(kāi)發(fā)完成效率。
每個(gè)微服務(wù)組件都有自己分配的存儲(chǔ) 內(nèi)存和CPU資源,這就使得硬件利用更加易于優(yōu)化和跟蹤,特別是在基于云的Pass環(huán)境,開(kāi)發(fā)團(tuán)隊(duì)可以使用他們喜歡的技術(shù),任何語(yǔ)言都可以,只要確保微服務(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ù)處理過(guò)程,將一個(gè)應(yīng)用切分為一個(gè)個(gè)小的實(shí)例,這些容器中的小實(shí)例有自己的端口和虛擬化環(huán)境。
廣泛使用的容器技術(shù)是Docker, 一種基于Linux的開(kāi)源實(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ù)本身是無(wú)狀態(tài)的;
- 微服務(wù)之間很少可變共享。
可以設(shè)想一下,如果微服務(wù)之間可以共享,那么帶來(lái)兩個(gè)問(wèn)題:微服務(wù)團(tuán)隊(duì)之間需要合作,因?yàn)楣蚕淼氖且粋€(gè)統(tǒng)一數(shù)據(jù)庫(kù),如果這種共享沒(méi)有帶來(lái)溝通成本,沒(méi)有破壞一個(gè)團(tuán)隊(duì)就能搞定的宗旨,那么這種共享數(shù)據(jù)庫(kù)也是可以考慮,但是這種情況很少,大部分團(tuán)隊(duì)因?yàn)楣蚕韱?wèn)題破壞了獨(dú)立性;再者,微服務(wù)如果使用Docker分別打包在一個(gè)容器中,這些容器可能是跨不同基礎(chǔ)設(shè)施部署,部署方式很靈活,是一種cloud native應(yīng)用,而共享數(shù)據(jù)庫(kù)屬于底層基礎(chǔ)設(shè)施,顯然提高了部署難點(diǎn)。
另外,傳統(tǒng)服務(wù)之間通訊無(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è)問(wèn)題,需要從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),雖然這帶來(lái)了高一致性的,但是擴(kuò)展性比較差,因?yàn)橥粋€(gè)事務(wù)邊界內(nèi)的動(dòng)作無(wú)法分離到幾個(gè)微服務(wù)中,因此,使用微服務(wù)必須積極擁抱最終一致性,對(duì)分布式系統(tǒng)以及CAP定理有一定理解。當(dāng)然,這些都是必須有多個(gè)微服務(wù)調(diào)用的情況下才需要考慮,由于微服務(wù)粒度小且專一,可以通過(guò)組合替代共享繼承的思路,容忍代碼有一定的重復(fù)性。
一個(gè)微服務(wù)架構(gòu)需要具備以下條件:
- 基礎(chǔ)監(jiān)視 測(cè)量和健康檢查
- 分布式日志 跟蹤
- 針對(duì)每個(gè)服務(wù),不只是隔離代碼,還需要在構(gòu)建+測(cè)試+打包+提交整個(gè)環(huán)節(jié)隔離。
- 能清晰定義每個(gè)服務(wù)的上下游、編譯時(shí)間和運(yùn)行依賴。
- 掌握如何構(gòu)建、暴露和維護(hù)好的API和合約。
- 需要尊重b/w和f/w兼容性,即使你可能不同時(shí)是你生產(chǎn)的服務(wù)的消費(fèi)者。
- 好的單元測(cè)試和更具有可讀性
- 注意微服務(wù)與模塊和庫(kù)包區(qū)別,以及分布式整體型monolith, 協(xié)同版本發(fā)布,數(shù)據(jù)庫(kù)驅(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èn)服務(wù)的獨(dú)特接口
- 服務(wù)前端的后端(Backend for front-end) - 為每一類客戶端都提供一個(gè)獨(dú)立的 API 網(wǎng)關(guān)
數(shù)據(jù)管理:
- 每個(gè)服務(wù)都擁有它私有的數(shù)據(jù)庫(kù)特接口
- 服務(wù)之間共享同一個(gè)數(shù)據(jù)庫(kù)
- 使用事件來(lái)維護(hù)服務(wù)間的數(shù)據(jù)一致性 事件溯源/CQRS
運(yùn)維監(jiān)控:
- 服務(wù)的發(fā)現(xiàn):通過(guò)第三方模塊來(lái)進(jìn)行服務(wù)實(shí)例信息到服務(wù)注冊(cè)表的注冊(cè)過(guò)程
- 分布式追蹤(Distributed tracing)new - 在服務(wù)代碼中針對(duì)每一個(gè)外部訪問(wèn),都分配一個(gè)服務(wù)標(biāo)識(shí)符,并在跨服務(wù)訪問(wèn)時(shí)傳遞這個(gè)標(biāo)識(shí)符以供追蹤分布式引發(fā)
- 斷路器(Circuit Breaker) - 當(dāng)遠(yuǎn)端服務(wù)返回的故障率超過(guò)一定的閥值時(shí),客戶端代理(比如 API 網(wǎng)關(guān))對(duì)遠(yuǎn)程服務(wù)的調(diào)用將立刻返回失敗的信息