一、微服務(wù)簡(jiǎn)介
1. 微服務(wù)的誕生
微服務(wù)是基于分而治之的思想演化出來(lái)的。過(guò)去傳統(tǒng)的一個(gè)大型而又全面的系統(tǒng),隨著互聯(lián)網(wǎng)的發(fā)展已經(jīng)很難滿足市場(chǎng)對(duì)技術(shù)的需求,于是我們從單獨(dú)架構(gòu)發(fā)展到分布式架構(gòu),又從分布式架構(gòu)發(fā)展到 SOA 架構(gòu),服務(wù)不斷的被拆分和分解,粒度也越來(lái)越小,直到微服務(wù)架構(gòu)的誕生。
微服務(wù)架構(gòu)是一種架構(gòu)模式,它提倡將單一應(yīng)用程序劃分成一組小的服務(wù),服務(wù)之間互相協(xié)調(diào)、互相配合,為用戶提供最終價(jià)值。
每個(gè)服務(wù)運(yùn)行在其獨(dú)立的進(jìn)程中,服務(wù)和服務(wù)間采用輕量級(jí)的通信機(jī)制互相溝通(通常是基于 HTTP 的 RESTful API)。每個(gè)服務(wù)都圍繞著具體業(yè)務(wù)進(jìn)行構(gòu)建,并且能夠被獨(dú)立地部署到生產(chǎn)環(huán)境、類生產(chǎn)環(huán)境等。另外,應(yīng)盡量避免統(tǒng)一的、集中式的服務(wù)管理機(jī)制,對(duì)具體的一個(gè)服務(wù)而言,應(yīng)根據(jù)業(yè)務(wù)上下文,選擇合適的語(yǔ)言、工具對(duì)其進(jìn)行構(gòu)建。
2. 微服務(wù)架構(gòu)與SOA架構(gòu)的區(qū)別
微服務(wù)是真正的分布式的、去中心化的。把所有的“思考”邏輯包括路由、消息解析等放在服務(wù)內(nèi)部,去掉一個(gè)大一統(tǒng)的 ESB,服務(wù)間輕通信,是比 SOA 更徹底的拆分。
微服務(wù)架構(gòu)強(qiáng)調(diào)的重點(diǎn)是業(yè)務(wù)系統(tǒng)需要徹底的組件化和服務(wù)化,原有的單個(gè)業(yè)務(wù)系統(tǒng)會(huì)拆分為多個(gè)可以獨(dú)立開發(fā),設(shè)計(jì),運(yùn)行和運(yùn)維的小應(yīng)用,這些小應(yīng)用之間通過(guò)服務(wù)完成交互和集成。
3. 微服務(wù)架構(gòu)引發(fā)的問(wèn)題
隨著整個(gè)業(yè)務(wù)數(shù)據(jù)被分散在各個(gè)子服務(wù)之后,也帶來(lái)了兩個(gè)最明顯的問(wèn)題。
- 業(yè)務(wù)管理系統(tǒng)對(duì)數(shù)據(jù)完整性查詢,比如分頁(yè)查詢、多條件查詢等,數(shù)據(jù)被割裂后如何來(lái)整合?
- 數(shù)據(jù)分析挖掘,這些需求可能需要分析全量的數(shù)據(jù),并且在分析時(shí)不能影響到當(dāng)前業(yè)務(wù)
從技術(shù)方案來(lái)講,我們一般有兩種選擇來(lái)處理這些問(wèn)題,第一種是在線處理數(shù)據(jù),第二種是離線處理數(shù)據(jù)。
- 在線處理數(shù)據(jù)的方案:通過(guò)微服務(wù)提供的接口來(lái)獲取數(shù)據(jù),然后進(jìn)行數(shù)據(jù)整合,不過(guò)這種方式有著明顯的弊端,就是調(diào)用者需要編寫大量的代碼進(jìn)行數(shù)據(jù)處理。其次在對(duì)各個(gè)微服務(wù)進(jìn)行調(diào)取數(shù)據(jù)時(shí)會(huì)影響微服務(wù)的正常業(yè)務(wù)處理性能
- 離線處理數(shù)據(jù)方案:將業(yè)務(wù)數(shù)據(jù)準(zhǔn)實(shí)時(shí)的同步到另外一個(gè)數(shù)據(jù)庫(kù)中,在同步的過(guò)程中進(jìn)行數(shù)據(jù)整合處理,以滿足業(yè)務(wù)方對(duì)數(shù)據(jù)的需求,數(shù)據(jù)同步過(guò)來(lái)后,再提供另外一個(gè)服務(wù)接口專業(yè)負(fù)責(zé)對(duì)外輸出數(shù)據(jù)信息,這種方案有兩個(gè)特點(diǎn):①數(shù)據(jù)同步方案是關(guān)鍵,技術(shù)選型有很多,如何選擇切合公司業(yè)務(wù)的技術(shù)方案;②離線數(shù)據(jù)處理對(duì)微服務(wù)正常業(yè)務(wù)處理沒(méi)有影響。
推薦使用第二種,利用 Spring Boot 和 MongoDB 可以輕松的解決這個(gè)問(wèn)題,通過(guò)技術(shù)手段將分裂到 N 個(gè)微服務(wù)的數(shù)據(jù)同步到 MongoDB 集群中,在同步的過(guò)程中進(jìn)行數(shù)據(jù)清洗,來(lái)滿足公司的各項(xiàng)業(yè)務(wù)需求
在微服務(wù)架構(gòu)中,有 大難題,那就是服務(wù)故障的傳播性、服務(wù)的劃分和分布式事務(wù)。
二、CAP 理論
Consistency :指數(shù)據(jù)的強(qiáng)一致性。如果寫入某個(gè)數(shù)據(jù)成功,之后讀取,讀到的都是新 寫入的數(shù)據(jù):如果寫入失敗,之后讀取的都不是寫入失敗的數(shù)據(jù)。
Availability :指服務(wù)的可用性
Partition-tolerance :指分區(qū)容錯(cuò)
在分布式系統(tǒng)中 P是基本要求,而單體服務(wù)是 CA 系統(tǒng), 微服務(wù)系統(tǒng)通常是 AP 系統(tǒng),即同時(shí)滿足了可用性和分區(qū)容錯(cuò)。
這就有了 個(gè)難題:在分布式系統(tǒng)中如何保證數(shù)據(jù)的一致性?這就是大家經(jīng)常討論的分布式事務(wù)
三、分布式事務(wù)
在微服務(wù)架構(gòu)中,分布式事務(wù) 般的解決辦法就是兩階段提交或者 三階段提交,不管使用哪都存在事務(wù)失敗,導(dǎo)致數(shù)據(jù)不 致的情況,關(guān)鍵時(shí)刻還得人工去恢復(fù)數(shù)據(jù)。
- 第一階段:發(fā)起一個(gè)分布式事務(wù),交給事務(wù)協(xié)調(diào)器TC處理,TC向多有的參與事務(wù)的節(jié)點(diǎn)發(fā)送處理事務(wù)操作的準(zhǔn)備操作。所有的參與節(jié)點(diǎn)執(zhí)行準(zhǔn)備操作,將Undo和Redo 信息寫進(jìn)日志,并向事務(wù)管理器返回準(zhǔn)備操作是否成功
- 第二階段:事務(wù)管理器收集所有節(jié)點(diǎn)的準(zhǔn)備操作是否成功,如果都成功,則通知所有的節(jié)點(diǎn)執(zhí)行提交操作;如果有 個(gè)失敗,則執(zhí)行回滾操作
兩階段提交,將事務(wù)分成兩部分能夠大大提高分布式事務(wù)成功的概率。如果在第 階段都成功了,而執(zhí)行第 階段的某 個(gè)節(jié)點(diǎn)失敗,仍然導(dǎo)致數(shù)據(jù)的不準(zhǔn)確,這時(shí)一般需要人工去處 理,這就是當(dāng)初在第一步記錄日志的原因。另外,如果分布式事務(wù)涉及的節(jié)點(diǎn)很多,某 個(gè)節(jié) 點(diǎn)的網(wǎng)絡(luò)出現(xiàn)異常會(huì)導(dǎo)致整個(gè)事務(wù)處于阻塞狀態(tài),大大降低數(shù)據(jù)庫(kù)的性能。所以一般情況下, 盡量少用分布式事務(wù)。
四、服務(wù)劃分
橫向拆分:按照不同的業(yè)務(wù)域進(jìn)行拆分,例如訂單、營(yíng)銷、風(fēng)控、積分資源等。形成獨(dú)立的業(yè)務(wù)領(lǐng)域微服務(wù)集群。
縱向拆分:把一個(gè)業(yè)務(wù)功能里的不同模塊或者組件進(jìn)行拆分。例如把公共組件拆分成獨(dú)立的原子服務(wù),下沉到底層,形成相對(duì)獨(dú)立的原子服務(wù)層。這樣一縱一橫,就可以實(shí)現(xiàn)業(yè)務(wù)的服務(wù)化拆分。
要做好微服務(wù)的分層:梳理和抽取核心應(yīng)用、公共應(yīng)用,作為獨(dú)立的服務(wù)下沉到核心和公共能力層,逐漸形成穩(wěn)定的服務(wù)中心,使前端應(yīng)用能更快速的響應(yīng)多變的市場(chǎng)需求
總之,微服務(wù)的設(shè)計(jì)一定要漸進(jìn)式的,總的原則是服務(wù)內(nèi)部高內(nèi)聚,服務(wù)之間低耦合。
微服務(wù)特點(diǎn):
按照業(yè)務(wù)劃分服務(wù),單個(gè)服務(wù)代碼量小,業(yè)務(wù)單一,易于維護(hù) 每個(gè)微服務(wù)都有自己獨(dú)立的基礎(chǔ)組件,例如數(shù)據(jù)庫(kù)、緩存等且運(yùn)行在獨(dú)立的進(jìn)程中 微服務(wù)之間的通信是通過(guò)HTTP協(xié)議或者消息組件,且具有容錯(cuò)能力 微服務(wù)有一套服務(wù)治理的解決方案,服務(wù)之間不耦合,可以隨時(shí)加入和剔除 單個(gè)微服務(wù)能夠集群化部署,并且有負(fù)責(zé) 均衡的能力 整個(gè)微服務(wù)系統(tǒng)應(yīng)該有完整的安全機(jī)制,包括用戶驗(yàn)證,權(quán)限驗(yàn)證,資源保護(hù) 整個(gè)微服務(wù)系統(tǒng)有鏈路追蹤的能力 有一套完整的實(shí)時(shí)日志系統(tǒng)
1. 給數(shù)據(jù)庫(kù)帶來(lái)的挑戰(zhàn)
隨著服務(wù)拆分后,我們遇到最大的問(wèn)題就是后臺(tái)管理的聯(lián)合查詢,每個(gè)微服務(wù)都有自己獨(dú)立的數(shù)據(jù)庫(kù),那么后臺(tái)該怎么處理?
這里一般有如下幾種方式:
- 嚴(yán)格按照微服務(wù)的劃分來(lái)做,微服務(wù)相互獨(dú)立,各微服務(wù)數(shù)據(jù)庫(kù)也獨(dú)立,后臺(tái)需要展示數(shù)據(jù)時(shí),調(diào)用各微服務(wù)的接口來(lái)獲取對(duì)應(yīng)的數(shù)據(jù),再進(jìn)行數(shù)據(jù)處理后展示出來(lái),這是標(biāo)準(zhǔn)的用法,也是最麻煩的用法。
- 將業(yè)務(wù)高度相關(guān)的表放到一個(gè)庫(kù)中,將業(yè)務(wù)關(guān)系不是很緊密的表嚴(yán)格按照微服務(wù)模式來(lái)拆分,這樣既可以使用微服務(wù),也避免了數(shù)據(jù)庫(kù)分散導(dǎo)致后臺(tái)系統(tǒng)統(tǒng)計(jì)功能難以實(shí)現(xiàn),是一個(gè)折中的方案。
- 數(shù)據(jù)庫(kù)嚴(yán)格按照微服務(wù)的要求來(lái)切分,以滿足業(yè)務(wù)高并發(fā),實(shí)時(shí)或者準(zhǔn)實(shí)時(shí)將各微服務(wù)數(shù)據(jù)庫(kù)數(shù)據(jù)同步到NoSQL數(shù)據(jù)庫(kù)中,在同步的過(guò)程中進(jìn)行數(shù)據(jù)清洗,用來(lái)滿足后臺(tái)業(yè)務(wù)系統(tǒng)的使用,推薦使用MongoDB、HBase等。
三種方案在不同的公司我都使用過(guò),第一種方案適合業(yè)務(wù)較為簡(jiǎn)單的小公司;第二種方案,適合在原有系統(tǒng)之上,慢慢演化為微服務(wù)架構(gòu)的公司;第三種適合大型高并發(fā)的互聯(lián)網(wǎng)公司。
五、熔斷器
為了解決分布式系統(tǒng)的雪崩效應(yīng),分布式系統(tǒng)引進(jìn)了熔斷器機(jī)制。
當(dāng)一個(gè)服務(wù)的處理用戶請(qǐng)求的失敗次數(shù)在一定時(shí)間內(nèi)小于設(shè)定的閥值時(shí),熔斷器出于關(guān)閉狀態(tài),服務(wù)正常。
當(dāng)服務(wù)處理用戶請(qǐng)求失敗次數(shù)在一定時(shí)間內(nèi)大于設(shè)定的閥值時(shí),說(shuō)明服務(wù)出現(xiàn)故障,打開熔斷器,這是所有的請(qǐng)求會(huì)快速失敗,不執(zhí)行業(yè)務(wù)邏輯
當(dāng)處于打開狀態(tài)的熔斷器時(shí),一段時(shí)間后出于半打開狀態(tài),并執(zhí)行一定數(shù)量的請(qǐng)求,剩余的請(qǐng)求會(huì)執(zhí)行快速失敗,若執(zhí)行請(qǐng)求失敗了,則繼續(xù)打開熔斷器,若成功了,則將熔斷器關(guān)閉
熔斷器不僅能防止系統(tǒng)的“雪崩”效應(yīng),還具有以下作用
- 將資源進(jìn)行隔離
- 服務(wù)降級(jí)的功能
- 自我修復(fù)能力
六、服務(wù)網(wǎng)關(guān)
在微服務(wù)系統(tǒng)中,API 接口資源通常是有服務(wù)網(wǎng)關(guān)(也稱API網(wǎng)關(guān))統(tǒng)一暴露,內(nèi)部服務(wù)不直接對(duì)外提供API資源的暴露。好處在于隱藏內(nèi)部服務(wù),保護(hù)系統(tǒng)安全
網(wǎng)關(guān)層通常以集群的形式存在。并在服務(wù)網(wǎng)關(guān)層前通常會(huì)加上Nginx 用來(lái)負(fù)載均衡
網(wǎng)關(guān)意義:
- 網(wǎng)關(guān)將所有服務(wù)的API接口資源統(tǒng)一聚合,對(duì)外統(tǒng)一暴露
- 網(wǎng)關(guān)可以做一些用戶身份認(rèn)證,權(quán)限認(rèn)證,防止非法請(qǐng)求操作API 接口,對(duì)內(nèi)部服務(wù)起到保護(hù)作用
- 網(wǎng)關(guān)可以實(shí)現(xiàn)監(jiān)控功能,實(shí)時(shí)日志輸出、對(duì)請(qǐng)求進(jìn)行記錄
- 網(wǎng)關(guān)可以用來(lái)做流量監(jiān)控,在高流量的情況下,對(duì)服務(wù)進(jìn)行降級(jí)
- API 接口從內(nèi)部服務(wù)分離出來(lái),方便做測(cè)試
當(dāng)然,網(wǎng)關(guān)實(shí)現(xiàn)這些功能,需要做高可用,否則網(wǎng)關(guān)很可能成功架構(gòu)的瓶頸,最常用的網(wǎng)關(guān)組件Zuul、Nginx
七、服務(wù)配置統(tǒng)一管理
在微服務(wù)架構(gòu)中,需要有統(tǒng)一管理配置文件的組件,例如:SpringCloud Config組件、阿里的Diamond、百度的Disconf、攜程的Apollo等
八、服務(wù)鏈路追蹤
在微服務(wù)架構(gòu)中,必須實(shí)現(xiàn)分布式鏈路追蹤,去跟進(jìn)一個(gè)請(qǐng)求到底有哪些服務(wù)參與、參與順序,是每個(gè)請(qǐng)求鏈路清晰可見,便于問(wèn)題快速定位
常用鏈路追蹤組件有g(shù)oogle的DApper、Twitter 的Zipkin,以及阿里Eagleeye(鷹眼)
九、微服務(wù)框架
市面常用微服務(wù)框架有:Spring Cloud 、Dubbo 、kubernetes
- 從功能模塊上考慮,Dubbo缺少很多功能模塊,例如網(wǎng)關(guān)、鏈路追蹤等
- 從學(xué)習(xí)成本上考慮,Dubbo 版本趨于穩(wěn)定,穩(wěn)定完善、可以即學(xué)即用,難度簡(jiǎn)單,Spring cloud 基于Spring Boot,需要先掌握Spring Boot ,例外Spring cloud 大多為英文文檔,要求學(xué)習(xí)者有一定的英文閱讀能力
- 從開發(fā)風(fēng)格考慮,Dubbo傾向于xml的配置方式,Spring cloud 基于Spring Boot ,采用基于注解和JAVABean配置方式的敏捷開發(fā)
- 從開發(fā)速度上考慮,Spring cloud 具有更高的開發(fā)和部署速度
- 從通信方式上考慮,Spring cloud 基于HTTP Restful 風(fēng)格,服務(wù)于服務(wù)之間完全無(wú)關(guān)、無(wú)耦合。Dubbo 基于遠(yuǎn)程調(diào)用,對(duì)接口、平臺(tái)和語(yǔ)言有強(qiáng)依賴性,如果需要實(shí)現(xiàn)跨平臺(tái),需要有額外的中間件。
所以Dubbo專注于服務(wù)治理;Spring Cloud關(guān)注于微服務(wù)架構(gòu)生態(tài)。
十、SpringCloud常用組件
- Eureka:服務(wù)注冊(cè)和發(fā)現(xiàn)組件
- Hystrix:熔斷組件
- Ribbon:負(fù)載均衡組件
- Zuul:路由網(wǎng)關(guān)
以上4個(gè)組件來(lái)自于Netflix 公司,統(tǒng)稱為Spring Cloud Netflix
- Spring Cloud Config:配置文件統(tǒng)一管理
- Spring Cloud Security:Spring Security組件封裝,提供用戶驗(yàn)證和權(quán)限驗(yàn)證,一般與Spring Security OAuth2 組一起使用,通過(guò)搭建授權(quán)服務(wù),驗(yàn)證Token或者JWT這種形式對(duì)整個(gè)微服務(wù)系統(tǒng)進(jìn)行安全驗(yàn)證
- Spring Cloud Sleuth:分布式鏈路追蹤組件,他分封裝了Dapper、Zipkin、Kibana 的組件
- Spring Cloud Stream:Spring Cloud框架的數(shù)據(jù)流操作包,可以封裝RabbitMq,ActiveMq,Kafka,redis等消息組件,利用Spring Cloud Stream可以實(shí)現(xiàn)消息的接收和發(fā)送
一個(gè)簡(jiǎn)單的Spring Cloud 構(gòu)建的微服務(wù)系統(tǒng),通常由服務(wù)注冊(cè)中心Eureka、網(wǎng)關(guān)Zuul、配置中心Config和授權(quán)服務(wù)Auth構(gòu)成
Spring Cloud Netflix功能:
- 服務(wù)發(fā)現(xiàn):可以注冊(cè)Eureka實(shí)例,并且客戶端可以使用Spring托管的Bean發(fā)現(xiàn)實(shí)例
- 服務(wù)發(fā)現(xiàn):可以使用聲明性Java配置創(chuàng)建嵌入式Eureka服務(wù)器
- 斷路器:Hystrix客戶端可以使用簡(jiǎn)單的注釋驅(qū)動(dòng)的方法裝飾器構(gòu)建
- 斷路器:具有聲明性Java配置的嵌入式Hystrix儀表板
- 聲明式REST客戶端:Feign創(chuàng)建一個(gè)用JAX-RS或Spring MVC注釋修飾的接口的動(dòng)態(tài)實(shí)現(xiàn)。
- 客戶端負(fù)載均衡器:功能區(qū)
- 外部配置:從Spring Environment到Archaius的橋梁(使用Spring Boot約定啟用Netflix組件的本機(jī)配置)
- 路由器和過(guò)濾器:Zuul過(guò)濾器的自動(dòng)重新注冊(cè),以及用于反向代理創(chuàng)建的簡(jiǎn)單配置約定