概述
微服務(wù)架構(gòu)只是將一個(gè)單體應(yīng)用程序拆分為多個(gè)相對獨(dú)立的服務(wù),每一個(gè)服務(wù)擁有獨(dú)立的進(jìn)程和數(shù)據(jù),每一個(gè)服務(wù)都是以輕量級的通信機(jī)制進(jìn)行交互的,一般為HTTP API(現(xiàn)今最流行的是REST風(fēng)格)。
一般來說,這些服務(wù)都是圍繞著業(yè)務(wù)模塊來建設(shè)的,是獨(dú)立的產(chǎn)品,因此完全可以獨(dú)立地自動(dòng)化部署和維護(hù),這樣更加有利于我們進(jìn)行更小粒度的開發(fā)、維護(hù)和部署。這些服務(wù)可以由不同的語言編寫,采用不同的數(shù)據(jù)存儲(chǔ),最低限度地集中管理。
微服務(wù)是一個(gè)模糊的概念,而不是一個(gè)標(biāo)準(zhǔn),沒有明確的定義。微服務(wù)它屬于分布式范疇,我們可以把微服務(wù)看成是分布式系統(tǒng)設(shè)計(jì)和架構(gòu)的理念之一,并并不是說能解決所有的分布式系統(tǒng)的問題,它只是尋求一個(gè)平衡點(diǎn),讓架構(gòu)師能夠更為簡單、容易地構(gòu)建分布式系統(tǒng)。
微服務(wù)設(shè)計(jì)原則
要架構(gòu)并開發(fā)一個(gè)微服務(wù)系統(tǒng),首先要考慮的是服務(wù)拆分方法,其次是微服務(wù)的設(shè)計(jì)和整體架構(gòu)。
服務(wù)拆分
服務(wù)拆分是微服務(wù)系統(tǒng)開發(fā)的第一步,也是最重要的一步。
首要考慮的是按業(yè)務(wù)拆分,這就要求架構(gòu)師,先分析業(yè)務(wù)需求,做好業(yè)務(wù)邊界,然后再按照業(yè)務(wù)模塊對系統(tǒng)進(jìn)行拆分。
服務(wù)拆分需要考慮以下幾點(diǎn):
- 服務(wù)的獨(dú)立性
拆分出來的服務(wù),應(yīng)該是獨(dú)立的,它可以獨(dú)立運(yùn)行,支撐某一塊業(yè)務(wù),是一個(gè)獨(dú)立的產(chǎn)品,應(yīng)該具備高內(nèi)聚和低耦合的特點(diǎn),同時(shí)它會(huì)保留一些明確的接口,提供給第三方進(jìn)行服務(wù)調(diào)用 - 明確服務(wù)粒度
比如一個(gè)用戶服務(wù),當(dāng)系統(tǒng)中用戶角色變多,業(yè)務(wù)變復(fù)雜,會(huì)拆分出普通會(huì)員服務(wù)、商戶服務(wù)、專家服務(wù)等等細(xì)分粒度。 - 團(tuán)隊(duì)分配
因?yàn)槊恳粋€(gè)服務(wù)是一個(gè)獨(dú)立的產(chǎn)品,原則上要求獨(dú)立團(tuán)隊(duì)負(fù)責(zé)開發(fā)、運(yùn)維和部署,為了節(jié)約成本,一般會(huì)是一個(gè)團(tuán)隊(duì)負(fù)責(zé)多個(gè)業(yè)務(wù)微服務(wù),按業(yè)務(wù)和工作量合理分配。 - 演進(jìn)型
微服務(wù)的拆分不是一成不變的,它會(huì)隨著時(shí)間的變化而變化的。正如第二點(diǎn)所述,業(yè)務(wù)一開始不復(fù)雜的情況下,可能就劃分出一個(gè)用戶服務(wù),當(dāng)業(yè)務(wù)發(fā)展中,越來越復(fù)雜,用戶數(shù)據(jù)越來越大,需要按用戶角色和業(yè)務(wù)拆分成多個(gè)細(xì)分服務(wù),所以在設(shè)計(jì)的時(shí)候,需要考慮未來可能的細(xì)化方向。 -
避免循環(huán)依賴和雙向依賴
一個(gè)業(yè)務(wù)不能同時(shí)由兩個(gè)系統(tǒng)維護(hù),必須有清晰的邊界。比如電商場景中,商品和財(cái)務(wù)都是有相關(guān)性的,有時(shí)候財(cái)務(wù)報(bào)表需要按照商品的交易情況等維度來統(tǒng)計(jì),這里需要明確商品相關(guān)的信息操作只在商品服務(wù)中處理,財(cái)務(wù)服務(wù)需要商品相關(guān)信息,需要有明確的接口和同步時(shí)間界限,以避免在財(cái)務(wù)服務(wù)中去維護(hù)商品的內(nèi)容。
系統(tǒng)設(shè)計(jì)
當(dāng)服務(wù)劃分好之后,就能清晰得看到各個(gè)獨(dú)立的服務(wù)了,接下來進(jìn)入系統(tǒng)設(shè)計(jì)。
系統(tǒng)設(shè)計(jì)中需要考慮以下幾點(diǎn):
- 高可用性
高可用性是微服務(wù)設(shè)計(jì)的第一原則。為了盡可能保證微服務(wù)能夠持續(xù)穩(wěn)定地提供給用戶服務(wù),任何一個(gè)服務(wù)都應(yīng)該至少有2個(gè)實(shí)例,任何一個(gè)實(shí)例出現(xiàn)故障,都可以被微服務(wù)系統(tǒng)發(fā)現(xiàn),并且微服務(wù)系統(tǒng)可以通過自我修復(fù)排除故障節(jié)點(diǎn)。 - 伸縮性
根據(jù)業(yè)務(wù)的發(fā)展,對服務(wù)的增加和減少有彈性的支持。 - 容錯(cuò)性
在高并發(fā)情況下,通過限流、熔斷和服務(wù)降級來保證服務(wù)之間的故障不蔓延 -
弱一致性
在之前的分布式事務(wù)中提到過,微服務(wù)不推薦使用強(qiáng)一致性,因?yàn)閺?qiáng)一致性緩慢且復(fù)雜。弱一致性則相對簡單,響應(yīng)速度快。 - 性能
微服務(wù)推薦的是使用REST風(fēng)格的請求來暴露服務(wù)接口,但是REST風(fēng)格緩慢,在一些性能要求高的場景可以選擇使用RPC。
下邊兩點(diǎn)屬于運(yùn)維范疇 - 基礎(chǔ)設(shè)施自動(dòng)化
可使用DevOps的理念進(jìn)行開發(fā)和測試,也可使用容器(如Docker等)簡化微服務(wù)的部署,使用這些工具可進(jìn)一步簡化開發(fā)、測試、部署和運(yùn)維工作,使得工作更少,更加智能 - 可監(jiān)控
服務(wù)實(shí)例都是可以監(jiān)控的,出現(xiàn)故障可以及時(shí)發(fā)現(xiàn),并且提示運(yùn)維人員進(jìn)行維護(hù)
微服務(wù)架構(gòu)
接下來開始系統(tǒng)架構(gòu),如圖

圖中,我們會(huì)用到許多組件,來幫我們組成一個(gè)微服務(wù)系統(tǒng)
- 服務(wù)注冊中心
可選組件:Eureka、Nacos、Consul,推薦Nacos - API網(wǎng)關(guān)組件
可選擇 SpringCloud gateway - 配置中心
可選組件:Nacos、Config、Consul,推薦Nacos - 服務(wù)限流
可選組件: sentinel - 負(fù)載均衡
可選組件:Ribbon - 遠(yuǎn)程調(diào)用
可選組件:Fegin/OpenFegin - 服務(wù)監(jiān)控
可選組件:SpringBootAdmin - 分布式事務(wù)管理
可選組件: Seata
API網(wǎng)關(guān):API網(wǎng)關(guān)可以實(shí)現(xiàn)路由、限流和降級的功能
服務(wù)和實(shí)例:服務(wù)是根據(jù)服務(wù)拆分方法得到的一個(gè)獨(dú)立的產(chǎn)品,它有明確的業(yè)務(wù)規(guī)則、邊界和接口。服務(wù)是由多個(gè)實(shí)例來完成的,多個(gè)實(shí)例可以滿足高可用和高性能的需求
服務(wù)調(diào)用:各個(gè)服務(wù)通過服務(wù)調(diào)用來完成企業(yè)的業(yè)務(wù)。在一般情況下,我們可以使用基于REST風(fēng)格的服務(wù)調(diào)用(如Ribbon和OpenFeign),它具備更高的可讀性和獨(dú)立性,但是性能不高,如果需要提升性能的,還可以考慮遠(yuǎn)程調(diào)用(RPC)技術(shù)
微服務(wù)系統(tǒng)如何優(yōu)化提高性能?
優(yōu)化主要集中在以下幾點(diǎn):
- 數(shù)據(jù)庫技術(shù)
- 緩存技術(shù)
- 動(dòng)靜分離
- 服務(wù)調(diào)用
- 數(shù)據(jù)庫優(yōu)化
主要對索引、SQL和鎖的優(yōu)化,以及數(shù)據(jù)庫讀寫分離,分庫分表等
索引:不是越多越好,數(shù)據(jù)量少的表可以不用索引,一般來說,表主要是考慮在常用的檢索字段上添加索引,每表索引應(yīng)該在5個(gè)以下,索引只需要滿足大部分的查詢即可,而不是全部查詢
SQL:SQL語句的有這里不鋪開敘述
鎖:有些sql會(huì)使表鎖定,比如update語句,需要優(yōu)化sql語句避免表鎖定。
數(shù)據(jù)庫讀寫分離:參考《如何搭建經(jīng)典的MySQL 主從復(fù)制架構(gòu)》
分庫分表:參考《分布式系統(tǒng)中,數(shù)據(jù)庫的分表、分庫和分區(qū)基本概念梳理》
《Springboot整合 ShardingSphere 實(shí)現(xiàn)分庫分表》 - 使用緩存
緩存一般是將數(shù)據(jù)存放在內(nèi)存中,而數(shù)據(jù)庫的數(shù)據(jù)卻存放在磁盤中,內(nèi)存的速度是磁盤的幾倍到幾十倍,所以如果大部分的數(shù)據(jù)是從內(nèi)存讀取,就能夠顯著提升性能。一般我們會(huì)選擇Redis作為緩存數(shù)據(jù)存儲(chǔ)服務(wù)。
3.服務(wù)調(diào)用優(yōu)化
對于性能要求高的服務(wù),可以采用RPC替代REST調(diào)用
- 動(dòng)靜分離
把常常訪問的靜態(tài)內(nèi)容,存儲(chǔ)于CDN服務(wù)器上
微服務(wù)系統(tǒng)如何保證服務(wù)高可用?
在高并發(fā)出現(xiàn)各種不穩(wěn)定因素時(shí),需要使用一定的技術(shù)手段,保證服務(wù)的可用性。目前流行的方法有限流和服務(wù)降級、隔離術(shù)、網(wǎng)關(guān)過濾和斷路器。
限流和服務(wù)降級
Spring cloud Gateway結(jié)合 Alibaba Sentinel隔離術(shù)
隔離術(shù)是處理高并發(fā)高的一種常用方法。隔離分為物理隔離和邏輯隔離兩大類。
機(jī)房隔離就屬于物理隔離。目前主要用的是線程隔離,可采用組件有:Resilience4j(艙壁)網(wǎng)關(guān)過濾
網(wǎng)關(guān)過濾也是常用的處理高并發(fā)的技術(shù)之一,通過它可以區(qū)分請求的有效性。
判斷請求是否有效的辦法,常見的有這么幾種:驗(yàn)證碼(如圖片驗(yàn)證碼、短信驗(yàn)證碼和拖動(dòng)驗(yàn)證碼等)、用戶黑名單、限制用戶單位時(shí)間戳的請求數(shù)、實(shí)名制、區(qū)分僵尸用戶和IP封禁等。
一般,可以使用redis 存儲(chǔ)ip黑名單,然后驗(yàn)證過后拒絕請求。斷路器
因服務(wù)依賴引發(fā)的服務(wù)器雪崩現(xiàn)象,在高并發(fā)時(shí),更容易產(chǎn)生這個(gè)現(xiàn)象,因此,往往還需要使用斷路器,保護(hù)那些可能引發(fā)問題的服務(wù)調(diào)用。
總結(jié)
微服務(wù)作為近幾年的新潮技術(shù),席卷了整個(gè)IT行業(yè),筆者也是因?yàn)槲⒎?wù)而接觸了SpringBoot,開啟了SpringCloud的學(xué)習(xí)。