微服務(wù)架構(gòu)設(shè)計時有哪些要點呢猬仁?先看下圖是 Spring Cloud 的整個生態(tài)帝璧。
下圖是完美實現(xiàn)微服務(wù)的十二原則:
接下來,細說微服務(wù)架構(gòu)設(shè)計中不得不知的十大要點湿刽。
負載均衡 + API 網(wǎng)關(guān)
在實施微服務(wù)的過程中的烁,不免要面臨服務(wù)的聚合與拆分。
當后端服務(wù)的拆分相對比較頻繁的時候诈闺,作為手機 App 來講渴庆,往往需要一個統(tǒng)一的入口,將不同的請求路由到不同的服務(wù)雅镊,無論后面如何拆分與聚合襟雷,對于手機端來講都是透明的。
有了 API 網(wǎng)關(guān)以后仁烹,簡單的數(shù)據(jù)聚合可以在網(wǎng)關(guān)層完成耸弄,這樣就不用在手機 App 端完成,從而手機 App 耗電量較小晃危,用戶體驗較好叙赚。
有了統(tǒng)一的 API 網(wǎng)關(guān),還可以進行統(tǒng)一的認證和鑒權(quán)僚饭,盡管服務(wù)之間的相互調(diào)用比較復(fù)雜震叮,接口也會比較多。
API 網(wǎng)關(guān)往往只暴露必須的對外接口鳍鸵,并且對接口進行統(tǒng)一的認證和鑒權(quán)苇瓣,使得內(nèi)部的服務(wù)相互訪問的時候,不用再進行認證和鑒權(quán)偿乖,效率會比較高击罪。
有了統(tǒng)一的 API 網(wǎng)關(guān),可以在這一層設(shè)定一定的策略贪薪,進行 A/B 測試媳禁,藍綠發(fā)布,預(yù)發(fā)環(huán)境導(dǎo)流等等画切。
API 網(wǎng)關(guān)往往是無狀態(tài)的竣稽,可以橫向擴展,從而不會成為性能瓶頸。
無狀態(tài)化與獨立有狀態(tài)集群
影響應(yīng)用遷移和橫向擴展的重要因素就是應(yīng)用的狀態(tài)毫别。無狀態(tài)服務(wù)娃弓,是要把這個狀態(tài)往外移,將 Session 數(shù)據(jù)岛宦,文件數(shù)據(jù)台丛,結(jié)構(gòu)化數(shù)據(jù)保存在后端統(tǒng)一的存儲中,從而應(yīng)用僅僅包含商務(wù)邏輯砾肺。
狀態(tài)是不可避免的挽霉,例如 ZooKeeper,DB债沮,Cache 等炼吴,把這些所有有狀態(tài)的東西收斂在一個非常集中的集群里面。
整個業(yè)務(wù)就分兩部分疫衩,一個是無狀態(tài)的部分硅蹦,一個是有狀態(tài)的部分。
無狀態(tài)的部分能實現(xiàn)兩點:
跨機房隨意地部署闷煤,也即遷移性童芹。
彈性伸縮,很容易地進行擴容鲤拿。
有狀態(tài)的部分假褪,如ZooKeeper,DB近顷,Cache 有自己的高可用機制生音,要利用到它們自己高可用的機制來實現(xiàn)這個狀態(tài)的集群。
雖說無狀態(tài)化窒升,但是當前處理的數(shù)據(jù)缀遍,還是會在內(nèi)存里面的,當前的進程掛掉數(shù)據(jù)饱须,肯定也是有一部分丟失的域醇。
為了實現(xiàn)這一點,服務(wù)要有重試的機制蓉媳,接口要有冪等的機制譬挚,通過服務(wù)發(fā)現(xiàn)機制,重新調(diào)用一次后端服務(wù)的另一個實例就可以了酪呻。
數(shù)據(jù)庫的橫向擴展
數(shù)據(jù)庫是保存狀態(tài)减宣,是最重要的也是最容易出現(xiàn)瓶頸的。有了分布式數(shù)據(jù)庫可以使數(shù)據(jù)庫的性能隨著節(jié)點增加線性地增加玩荠。
分布式數(shù)據(jù)庫最最下面是 RDS蚪腋,是主備的丰歌,通過 MySQL 的內(nèi)核開發(fā)能力姨蟋,我們能夠?qū)崿F(xiàn)主備切換數(shù)據(jù)零丟失屉凯。
所以數(shù)據(jù)落在這個 RDS 里面,是非常放心的眼溶,哪怕是掛了一個節(jié)點悠砚,切換完了以后,你的數(shù)據(jù)也是不會丟的堂飞。
再往上就是橫向怎么承載大的吞吐量的問題灌旧,上面有一個負載均衡 NLB,用 ?LVS绰筛,HAProxy枢泰,Keepalived,下面接了一層 Query Server铝噩。
Query Server 是可以根據(jù)監(jiān)控數(shù)據(jù)進行橫向擴展的衡蚂,如果出現(xiàn)了故障,可以隨時進行替換的修復(fù)骏庸,對于業(yè)務(wù)層是沒有任何感知的毛甲。
另外一個就是雙機房的部署,DDB 開發(fā)了一個數(shù)據(jù)運河 NDC 的組件具被,可以使得不同的 DDB 之間在不同的機房里面進行同步玻募。
這時候不但在一個數(shù)據(jù)中心里面是分布式的一姿,在多個數(shù)據(jù)中心里面也會有一個類似雙活的一個備份七咧,高可用性有非常好的保證。
緩存
在高并發(fā)場景下緩存是非常重要的叮叹。要有層次的緩存艾栋,使得數(shù)據(jù)盡量靠近用戶。數(shù)據(jù)越靠近用戶能承載的并發(fā)量也越大衬横,響應(yīng)時間越短裹粤。
在手機客戶端 App 上就應(yīng)該有一層緩存,不是所有的數(shù)據(jù)都每時每刻從后端拿蜂林,而是只拿重要的遥诉,關(guān)鍵的,時常變化的數(shù)據(jù)噪叙。
尤其對于靜態(tài)數(shù)據(jù)矮锈,可以過一段時間去取一次,而且也沒必要到數(shù)據(jù)中心去取睁蕾,可以通過 CDN苞笨,將數(shù)據(jù)緩存在距離客戶端最近的節(jié)點上债朵,進行就近下載。
有時候 CDN 里面沒有瀑凝,還是要回到數(shù)據(jù)中心去下載序芦,稱為回源,在數(shù)據(jù)中心的最外層粤咪,我們稱為接入層谚中,可以設(shè)置一層緩存,將大部分的請求攔截寥枝,從而不會對后臺的數(shù)據(jù)庫造成壓力宪塔。
如果是動態(tài)數(shù)據(jù),還是需要訪問應(yīng)用囊拜,通過應(yīng)用中的商務(wù)邏輯生成某筐,或者去數(shù)據(jù)庫讀取,為了減輕數(shù)據(jù)庫的壓力冠跷,應(yīng)用可以使用本地的緩存南誊,也可以使用分布式緩存。
如 Memcached 或者 Redis蔽莱,使得大部分請求讀取緩存即可弟疆,不必訪問數(shù)據(jù)庫。
當然動態(tài)數(shù)據(jù)還可以做一定的靜態(tài)化盗冷,也即降級成靜態(tài)數(shù)據(jù)怠苔,從而減少后端的壓力。
服務(wù)拆分與服務(wù)發(fā)現(xiàn)
當系統(tǒng)扛不住仪糖,應(yīng)用變化快的時候柑司,往往要考慮將比較大的服務(wù)拆分為一系列小的服務(wù)。
這樣第一個好處就是開發(fā)比較獨立锅劝,當非常多的人在維護同一個代碼倉庫的時候攒驰,往往對代碼的修改就會相互影響。
常常會出現(xiàn)我沒改什么測試就不通過了故爵,而且代碼提交的時候玻粪,經(jīng)常會出現(xiàn)沖突,需要進行代碼合并诬垂,大大降低了開發(fā)的效率劲室。
另一個好處就是上線獨立兔综,物流模塊對接了一家新的快遞公司色徘,需要連同下單一起上線,這是非常不合理的行為岁诉。
我沒改還要我重啟隧枫,我沒改還讓我發(fā)布喉磁,我沒改還要我開會谓苟,都是應(yīng)該拆分的時機。
再就是高并發(fā)時段的擴容协怒,往往只有最關(guān)鍵的下單和支付流程是核心涝焙,只要將關(guān)鍵的交易鏈路進行擴容即可,如果這時候附帶很多其他的服務(wù)斤讥,擴容既是不經(jīng)濟的纱皆,也是很有風險的。
另外的容災(zāi)和降級芭商,在大促的時候,可能需要犧牲一部分的邊角功能搀缠,但是如果所有的代碼耦合在一起铛楣,很難將邊角的部分功能進行降級。
當然拆分完畢以后艺普,應(yīng)用之間的關(guān)系就更加復(fù)雜了簸州,因而需要服務(wù)發(fā)現(xiàn)的機制,來管理應(yīng)用相互的關(guān)系歧譬,實現(xiàn)自動的修復(fù)岸浑,自動的關(guān)聯(lián),自動的負載均衡瑰步,自動的容錯切換矢洲。
服務(wù)編排與彈性伸縮
當服務(wù)拆分了,進程就會非常的多缩焦,因而需要服務(wù)編排來管理服務(wù)之間的依賴關(guān)系读虏,以及將服務(wù)的部署代碼化,也就是我們常說的基礎(chǔ)設(shè)施即代碼袁滥。
這樣對于服務(wù)的發(fā)布盖桥,更新,回滾题翻,擴容揩徊,縮容,都可以通過修改編排文件來實現(xiàn)嵌赠,從而增加了可追溯性塑荒,易管理性,和自動化的能力猾普。
既然編排文件也可以用代碼倉庫進行管理袜炕,就可以實現(xiàn)一百個服務(wù)中,更新其中五個服務(wù)初家,只要修改編排文件中的五個服務(wù)的配置就可以偎窘。
當編排文件提交的時候乌助,代碼倉庫自動觸發(fā)自動部署升級腳本,從而更新線上的環(huán)境陌知。
當發(fā)現(xiàn)新的環(huán)境有問題時他托,當然希望將這五個服務(wù)原子性地回滾,如果沒有編排文件仆葡,需要人工記錄這次升級了哪五個服務(wù)赏参。
有了編排文件,只要在代碼倉庫里面 Revert沿盅,就回滾到上一個版本了把篓。所有的操作在代碼倉庫里都是可以看到的。
統(tǒng)一配置中心
服務(wù)拆分以后腰涧,服務(wù)的數(shù)量非常多韧掩,如果所有的配置都以配置文件的方式放在應(yīng)用本地的話,非常難以管理窖铡。
可以想象當有幾百上千個進程中有一個配置出現(xiàn)了問題疗锐,是很難將它找出來的,因而需要有統(tǒng)一的配置中心费彼,來管理所有的配置滑臊,進行統(tǒng)一的配置下發(fā)。
在微服務(wù)中箍铲,配置往往分為以下幾類:
一類是幾乎不變的配置雇卷,這種配置可以直接打在容器鏡像里面。
第二類是啟動時就會確定的配置虹钮,這種配置往往通過環(huán)境變量聋庵,在容器啟動的時候傳進去。
第三類就是統(tǒng)一的配置芙粱,需要通過配置中心進行下發(fā)祭玉。例如在大促的情況下,有些功能需要降級春畔,哪些功能可以降級脱货,哪些功能不能降級,都可以在配置文件中統(tǒng)一配置律姨。
統(tǒng)一日志中心
同樣是進程數(shù)目非常多的時候振峻,很難對成千上百個容器,一個一個登錄進去查看日志择份,所以需要統(tǒng)一的日志中心來收集日志扣孟。
為了使收集到的日志容易分析,對于日志的規(guī)范荣赶,需要有一定的要求凤价,當所有的服務(wù)都遵守統(tǒng)一的日志規(guī)范的時候鸽斟,在日志中心就可以對一個交易流程進行統(tǒng)一的追溯。
例如在最后的日志搜索引擎中利诺,搜索交易號富蓄,就能夠看到在哪個過程出現(xiàn)了錯誤或者異常。
熔斷慢逾,限流立倍,降級
服務(wù)要有熔斷,限流侣滩,降級的能力口注,當一個服務(wù)調(diào)用另一個服務(wù),出現(xiàn)超時的時候胜卤,應(yīng)及時返回疆导,而非阻塞在那個地方,從而影響其他用戶的交易葛躏,可以返回默認的托底數(shù)據(jù)。
當一個服務(wù)發(fā)現(xiàn)被調(diào)用的服務(wù)悠菜,因為過于繁忙舰攒,線程池滿,連接池滿悔醋,或者總是出錯摩窃,則應(yīng)該及時熔斷,防止因為下一個服務(wù)的錯誤或繁忙芬骄,導(dǎo)致本服務(wù)的不正常猾愿,從而逐漸往前傳導(dǎo),導(dǎo)致整個應(yīng)用的雪崩账阻。
當發(fā)現(xiàn)整個系統(tǒng)的確負載過高的時候蒂秘,可以選擇降級某些功能或某些調(diào)用,保證最重要的交易流程的通過淘太,以及最重要的資源全部用于保證最核心的流程姻僧。
還有一種手段就是限流,當既設(shè)置了熔斷策略蒲牧,又設(shè)置了降級策略撇贺,通過全鏈路的壓力測試,應(yīng)該能夠知道整個系統(tǒng)的支撐能力冰抢。
因而就需要制定限流策略松嘶,保證系統(tǒng)在測試過的支撐能力范圍內(nèi)進行服務(wù),超出支撐能力范圍的挎扰,可拒絕服務(wù)翠订。
當你下單的時候巢音,系統(tǒng)彈出對話框說 “系統(tǒng)忙,請重試”蕴轨,并不代表系統(tǒng)掛了港谊,而是說明系統(tǒng)是正常工作的,只不過限流策略起到了作用橙弱。
全方位的監(jiān)控
當系統(tǒng)非常復(fù)雜的時候歧寺,要有統(tǒng)一的監(jiān)控,主要有兩個方面棘脐,一個是是否健康斜筐,一個是性能瓶頸在哪里。
當系統(tǒng)出現(xiàn)異常的時候蛀缝,監(jiān)控系統(tǒng)可以配合告警系統(tǒng)顷链,及時地發(fā)現(xiàn),通知屈梁,干預(yù)嗤练,從而保障系統(tǒng)的順利運行。
當壓力測試的時候在讶,往往會遭遇瓶頸煞抬,也需要有全方位的監(jiān)控來找出瓶頸點,同時能夠保留現(xiàn)場构哺,從而可以追溯和分析革答,進行全方位的優(yōu)化。
注: 【轉(zhuǎn)載】51CTO>劉超