分布式技術(shù)的發(fā)展,深刻地改變了我們編程的模式和思考軟件的模式。值 2019 歲末,PingCAP 聯(lián)合 InfoQ 共同策劃出品“分布式系統(tǒng)前沿技術(shù) ”專(zhuān)題, 邀請(qǐng)眾多技術(shù)團(tuán)隊(duì)共同參與,一起探索這個(gè)古老領(lǐng)域的新生機(jī)。本文出自轉(zhuǎn)轉(zhuǎn)首席架構(gòu)師孫玄。
微服務(wù)架構(gòu)模式經(jīng)過(guò) 5 年多的發(fā)展,在各行各業(yè)如火如荼地應(yīng)用和實(shí)踐。如何在企業(yè)中優(yōu)雅地設(shè)計(jì)微服務(wù)架構(gòu)?是企業(yè)面對(duì)的一個(gè)重要問(wèn)題。本文將講述微服務(wù)架構(gòu) 1.0 設(shè)計(jì)與實(shí)踐以及面臨問(wèn)題和破局,最后講述微服務(wù)架構(gòu) 2.0 設(shè)計(jì)與實(shí)踐等方面,嘗試去回答這個(gè)難題。
微服務(wù)架構(gòu) 1.0 設(shè)計(jì)與實(shí)踐
微服務(wù)架構(gòu)定義
2014 年馬丁福勒提出了微服務(wù)架構(gòu)設(shè)計(jì)模式,微服務(wù)架構(gòu)最核心的設(shè)計(jì)有二點(diǎn)(如圖 1 綠框所示):
第一,把單體服務(wù)拆分成一系列小服務(wù);
第二,拆分后的這些小服務(wù)是去中心化的,即每個(gè)服務(wù)都可以使用不同的編程語(yǔ)言,也可以使用不同的數(shù)據(jù)庫(kù)和緩存存儲(chǔ)數(shù)據(jù)。
圖 1 微服務(wù)架構(gòu)模式
微服務(wù)架構(gòu)拆分設(shè)計(jì)實(shí)踐
第一個(gè)問(wèn)題是服務(wù)如何拆分的問(wèn)題。架構(gòu)拆分沒(méi)有新鮮事,即不同領(lǐng)域的架構(gòu)設(shè)計(jì)在道(哲學(xué))的層面都是相通的。
我們來(lái)思考一下公司數(shù)據(jù)庫(kù)集群遇到讀寫(xiě)和存儲(chǔ)的性能問(wèn)題時(shí),是如何解決的?假如公司電商業(yè)務(wù)包含用戶、商品以及交易等數(shù)據(jù),每種數(shù)據(jù)使用一張單獨(dú)的表存儲(chǔ),這些數(shù)據(jù)放在一個(gè)數(shù)據(jù)庫(kù)(DB4Global)中。隨著請(qǐng)求量的增加和數(shù)據(jù)存儲(chǔ)量的增加,單獨(dú)的 DB4Global 數(shù)據(jù)庫(kù)會(huì)遇到性能瓶頸。為了解決數(shù)據(jù)庫(kù)的性能問(wèn)題,需要對(duì) DB4Global 庫(kù)拆分,首先對(duì) DB4Global 庫(kù)按照業(yè)務(wù)領(lǐng)域進(jìn)行垂直拆分,拆分為多個(gè)獨(dú)立的用戶庫(kù)(DB4User)、商品庫(kù)(DB4Info)、交易庫(kù)(DB4Trade)等;其次為了進(jìn)一步提升數(shù)據(jù)庫(kù)的性能,再次根據(jù)功能對(duì)每個(gè)表進(jìn)行水平方向的拆分,例如用戶表 10 億記錄,主鍵為用戶 UID。Partition Key 選擇為 UID,按照 UID % 128 水平拆分。
架構(gòu)設(shè)計(jì)之道是相通的,微服務(wù)拆分同樣遵循業(yè)務(wù)領(lǐng)域的垂直拆分以及功能的水平拆分。繼續(xù)以電商業(yè)務(wù)為例,首先按照業(yè)務(wù)領(lǐng)域的垂直拆分,分為用戶微服務(wù)、商品微服務(wù)、搜索微服務(wù)、推薦微服務(wù)、交易微服務(wù)等。
繼續(xù)思考一個(gè)問(wèn)題,在垂直方向僅僅按照業(yè)務(wù)領(lǐng)域進(jìn)行拆分是否滿足所有的業(yè)務(wù)場(chǎng)景?答案是否定的。例如用戶服務(wù)分為用戶注冊(cè)(寫(xiě)請(qǐng)求)和用戶登陸(讀請(qǐng)求)等。寫(xiě)請(qǐng)求的重要性往往是大于讀請(qǐng)求,在互聯(lián)網(wǎng)大流量下,讀寫(xiě)比例 10:1,甚至更高的情況下,大量的讀往往會(huì)直接影響寫(xiě)。為了避免大量的讀對(duì)寫(xiě)請(qǐng)求的干擾,需要對(duì)服務(wù)進(jìn)行讀寫(xiě)分離,即用戶注冊(cè)為一個(gè)微服務(wù),用戶登陸為一個(gè)微服務(wù)。此時(shí)按照 API 的細(xì)粒度繼續(xù)進(jìn)行垂直方向的拆分。
在水平方向,按照請(qǐng)求的功能拆分,即對(duì)一個(gè)請(qǐng)求的生命周期繼續(xù)進(jìn)行拆分。請(qǐng)求從用戶端發(fā)出,首先接受到請(qǐng)求的是網(wǎng)關(guān)服務(wù),網(wǎng)關(guān)服務(wù)對(duì)請(qǐng)求進(jìn)行請(qǐng)求鑒權(quán)、通用參數(shù)檢查、協(xié)議轉(zhuǎn)換以及路由轉(zhuǎn)發(fā)等。接下來(lái)業(yè)務(wù)邏輯服務(wù)對(duì)請(qǐng)求進(jìn)行業(yè)務(wù)邏輯的編排處理(比如微信發(fā)送消息,需要進(jìn)行好友關(guān)系檢查、對(duì)消息內(nèi)容進(jìn)行風(fēng)控檢查、進(jìn)行消息的存儲(chǔ)和推送等)。對(duì)業(yè)務(wù)數(shù)據(jù)進(jìn)行存儲(chǔ)和查詢(xún)就需要數(shù)據(jù)訪問(wèn)服務(wù),數(shù)據(jù)訪問(wèn)服務(wù)提供了基本的 CRUD 原子操作,并負(fù)責(zé)海量數(shù)據(jù)的 Sharding(分庫(kù)分表)以及屏蔽底層存儲(chǔ)的差異性等功能。最后是數(shù)據(jù)持久化和緩存服務(wù),比如可以采用 NewSQL TiDB 以及 Redis Cluster 等。
通過(guò)以上的拆分,普適的微服務(wù)架構(gòu)如圖 2 所示。
圖 2 普適的微服務(wù)架構(gòu)
微服務(wù)架構(gòu)通過(guò)業(yè)務(wù)垂直拆分以及水平的功能拆分,服務(wù)演化成更小的顆粒度,各服務(wù)之間相互解耦,每個(gè)服務(wù)都可以快速迭代和持續(xù)交付,從而在公司層面能夠達(dá)到降本增效的終極目標(biāo)。但是服務(wù)粒度越細(xì),服務(wù)之間的交互就會(huì)越來(lái)越多,更多的交互會(huì)使得服務(wù)之間的治理更復(fù)雜。服務(wù)之間的治理包括服務(wù)間的注冊(cè)、通信、路由、負(fù)載均衡、重試、限流、降級(jí)、熔斷、鏈路跟蹤等。
微服務(wù)架構(gòu)技術(shù)選型,包括微服務(wù)本身的研發(fā)框架以及服務(wù)治理框架。目前研發(fā)框架主流的 RPC 有兩類(lèi):一種是 RPC Over TCP,典型代表是 Apache Dubbo;另外一種是 RPC Over HTTP,典型代表是 Spring Cloud。企業(yè)根據(jù)團(tuán)隊(duì)的研發(fā)基因二者選一即可。在服務(wù)治理方面包含了服務(wù)注冊(cè)、服務(wù)配置、服務(wù)熔斷、服務(wù)監(jiān)控等方面,服務(wù)注冊(cè)本質(zhì)是 AP 的模型,可以選用 Nacos,服務(wù)配置可以選用 CTrip Apollo,服務(wù)熔斷可以選用 Netflix Hystrix 組件,服務(wù)監(jiān)控可以選用 Open-Falcon 等配套框架。
微服務(wù)架構(gòu) 1.0 面臨問(wèn)題以及破局
在微服務(wù)架構(gòu) 1.0 中每個(gè)服務(wù)包含了服務(wù)自身的功能設(shè)計(jì)以及服務(wù)治理的功能設(shè)計(jì),他們耦合在一起,這些服務(wù)治理的功能和服務(wù)自身功能沒(méi)有關(guān)系,業(yè)務(wù)方也不需要關(guān)注。使得微服務(wù) 1.0 架構(gòu)不再是銀彈,存在以下幾個(gè)方面的問(wèn)題:
第一,每一個(gè)業(yè)務(wù)服務(wù)為了和其他業(yè)務(wù)服務(wù)交互,都必須關(guān)注和引入服務(wù)間服務(wù)治理組件,使得業(yè)務(wù)服務(wù)迭代速度變慢,如圖 3 所示。
圖 3 業(yè)務(wù)服務(wù)迭代速度慢
第二,服務(wù)治理組件和服務(wù)自身功能耦合在一個(gè)進(jìn)程內(nèi),使得服務(wù)治理組件的升級(jí)強(qiáng)依賴(lài)于業(yè)務(wù)服務(wù)自身,造成基礎(chǔ)設(shè)施研發(fā)團(tuán)隊(duì)的交付能力和交付速度大大降低。如圖 4 所示,服務(wù)降級(jí)功能從 V1 升級(jí)到 V2,需要業(yè)務(wù)服務(wù)更換服務(wù)降級(jí)功能的組件,重新打包編譯和發(fā)布。
圖 4 服務(wù)治理組件升級(jí)困難
第三,前文提到馬丁福勒對(duì)微服務(wù)架構(gòu)的期望是每個(gè)服務(wù)都可以使用業(yè)務(wù)團(tuán)隊(duì)熟悉的語(yǔ)言來(lái)編寫(xiě),但是在服務(wù)自身和服務(wù)治理耦合在一起的情況下,每個(gè)語(yǔ)言都需要一套完整的服務(wù)治理組件,必然造成公司研發(fā)投入成本增大,ROI 不高。如圖 5 所示,Java 語(yǔ)言編寫(xiě)的應(yīng)用程序A和應(yīng)用程序 C 交互,就需要一套完整的 Java 語(yǔ)言服務(wù)治理組件,同樣,世界上最好語(yǔ)言編寫(xiě)的應(yīng)用程序 B 和應(yīng)用程序 C 交互,就需要一套完成的 PHP 語(yǔ)言服務(wù)治理組件。
圖 5 多套服務(wù)治理組件
那么造成這些問(wèn)題的本質(zhì)原因在于服務(wù)自身功能和服務(wù)治理功能的物理耦合,把服務(wù)治理功能完全解耦出來(lái),變成一個(gè)獨(dú)立的服務(wù)治理進(jìn)程,從而以上三個(gè)問(wèn)題得以徹底解決。
微服務(wù)架構(gòu) 2.0 設(shè)計(jì)與實(shí)踐
Serive Mesh 定義
微服務(wù)架構(gòu) 1.0 繼續(xù)演進(jìn),就變成了微服務(wù)架構(gòu) 2.0,即 Service Mesh 架構(gòu)(Service Mesh)。Servie Mesh 架構(gòu)最早由開(kāi)發(fā) Linkerd 的 Buoyant 公司提出,并在內(nèi)部使用。2016 年 09 月 29 日第一次公開(kāi)使用,2017 年初進(jìn)入國(guó)內(nèi)技術(shù)社區(qū)視野。Service Mesh 到底是什么?我們來(lái)看看 Linerd 公司 CEO Willian Morgan 對(duì) Service Mesh 的定義如圖 6 所示:
圖 6 Service Mesh 定義
Service Mesh 是一個(gè)基礎(chǔ)設(shè)施層,用于處理服務(wù)間交互。云原生應(yīng)用有著復(fù)雜的服務(wù)拓?fù),Service Mesh 負(fù)責(zé)在這些拓?fù)渲袑?shí)現(xiàn)請(qǐng)求的可靠傳遞。在線上實(shí)踐中,Service Mesh 通常實(shí)現(xiàn)為一組輕量級(jí)的網(wǎng)絡(luò)代理(Sidecar 邊車(chē)),它們與應(yīng)用程序部署在一起,并且對(duì)應(yīng)用程序透明。
微服務(wù)架構(gòu) 2.0 破局
圖 7 Service Mesh 架構(gòu)
如圖 7 所示,應(yīng)用程序 A 和應(yīng)用程序 B 交互,請(qǐng)求調(diào)用關(guān)系如下:應(yīng)用程序 A 調(diào)用本地的 Sidecar A,Sidecar A 在通過(guò)網(wǎng)絡(luò)交互調(diào)用遠(yuǎn)端的 Sidecar B,再由 Sidecar B 把請(qǐng)求傳遞給應(yīng)用程序 B。請(qǐng)求回應(yīng)關(guān)系也是類(lèi)似:應(yīng)用程序 B 調(diào)用 Sidecar B,Sidecar B 在通過(guò)網(wǎng)絡(luò)交互調(diào)用遠(yuǎn)端的 Sidecar A,再由 Sidecar A 把請(qǐng)求回應(yīng)傳遞給應(yīng)用程序 A。通過(guò)把服務(wù)治理功能從服務(wù)自身中物理剝離出來(lái),下沉形成獨(dú)立的進(jìn)程,從而物理解耦。
在這樣的架構(gòu)模式下,業(yè)務(wù)應(yīng)用程序再也不需要關(guān)注服務(wù)治理的功能,服務(wù)治理的功能升級(jí)也不要依賴(lài)于服務(wù)自身,從而能夠讓業(yè)務(wù)迭代更快速和高效。同時(shí)由于服務(wù)治理功能變成一個(gè)獨(dú)立的進(jìn)程,只需要使用一種語(yǔ)言打造即可,業(yè)務(wù)服務(wù)自身可以選擇業(yè)務(wù)團(tuán)隊(duì)擅長(zhǎng)的語(yǔ)言進(jìn)行編寫(xiě),從而能夠真正達(dá)到馬丁福勒對(duì)微服務(wù)的期望。
我們?cè)偕钊敕治鱿聟f(xié)議,在通信協(xié)議方面,業(yè)務(wù)應(yīng)用程序和 Sidecar 的通信可以基于 TCP 長(zhǎng)連接,也可以基于 HTTP 1.0 或者 2.0 的長(zhǎng)連接(思考下:是否一定要使用長(zhǎng)連接?),Sidecar 間的通信協(xié)議沒(méi)有特殊要求;在數(shù)據(jù)傳輸協(xié)議方面,可以是 JSON/XML 等跨語(yǔ)言的文本協(xié)議,也可以選擇 Protobuffers/MessagePack 等跨語(yǔ)言的二進(jìn)制協(xié)議。
保證了通信協(xié)議和數(shù)據(jù)傳輸協(xié)議的跨語(yǔ)言,不同語(yǔ)言的應(yīng)用程序就可以無(wú)縫地和 Sidecar 進(jìn)行交與。在應(yīng)用程序和對(duì)應(yīng)的 Sidecar 部署層面,需要部署在同機(jī)(可以是同一臺(tái)物理機(jī)/虛擬機(jī),也可以是同一個(gè) Pod),思考下,如果部署在不同的機(jī)器上,就會(huì)又引入服務(wù)通信交互的問(wèn)題,那么就會(huì)變成無(wú)解的難題:為了解決通信交互的問(wèn)題,又引入新的通信交互的問(wèn)題。
微服務(wù)架構(gòu) 2.0 實(shí)踐
按照新的微服務(wù)架構(gòu) 2.0 打造,微服務(wù)架構(gòu) 1.0 的升級(jí)演變?nèi)鐖D 8 所示:
圖 8 微服務(wù)架構(gòu) 2.0
Service Mesh 架構(gòu)框架方面,業(yè)內(nèi)陸續(xù)開(kāi)源了不少的優(yōu)秀框架,Istio 是集大成者,由 Google、IBM、Lyft 等三家公司聯(lián)合打造,并已經(jīng)開(kāi)源,社區(qū)版本也已經(jīng)發(fā)展到 V1.4.2。IstioService Mesh 邏輯上分為數(shù)據(jù)面板(執(zhí)行者)和控制面板(指揮者),數(shù)據(jù)面板由一組智能代理(Envoy)組成,代理部署為 Sidecar,調(diào)解和控制微服務(wù)之間所有的網(wǎng)絡(luò)通信。控制面板負(fù)責(zé)管理和配置代理來(lái)路由流量,以及在運(yùn)行時(shí)執(zhí)行策略。如圖 9 所示,控制面板(Pilot、Mixer、Citadel)加數(shù)據(jù)面板(Envoy Proxy)即是服務(wù)治理功能,svcA 和 svcB 是業(yè)務(wù)服務(wù)自身。
圖 9 Istio 架構(gòu)
未來(lái)展望
與純粹的微服務(wù)架構(gòu)相比,Service Mesh 又向前邁了一步。它最大的優(yōu)勢(shì)是解耦應(yīng)用業(yè)務(wù),企業(yè)能夠徹底從業(yè)務(wù)角度考慮問(wèn)題,同時(shí)還可以與容器編排部署平臺(tái)的集成,成為企業(yè)級(jí)應(yīng)用編排部署和服務(wù)治理的標(biāo)準(zhǔn)形態(tài)。
但是企業(yè)想要全面切換到 Service Mesh 并不是一件易事,還有一段路需要走。以 Istio 為例,如果要切換,會(huì)面臨以下問(wèn)題:
第一,老服務(wù)切換到 Istio 的過(guò)程中,由于歷史服務(wù)使用的框架不同,如何保證老服務(wù)的平穩(wěn)遷移以及新老服務(wù)如何無(wú)縫交互,是企業(yè)面臨的第一個(gè)難題;
第二,切換到 Istio 后,由于通信鏈路會(huì)變長(zhǎng),必將增加請(qǐng)求的響應(yīng)延遲,對(duì)請(qǐng)求響應(yīng)延遲極其敏感的業(yè)務(wù)場(chǎng)景,比如量化交易等場(chǎng)景,增加的請(qǐng)求相應(yīng)延遲對(duì)業(yè)務(wù)來(lái)說(shuō)是致命的,如何進(jìn)一步優(yōu)化處理;
第三,Istio 的 Mixer 功能存在單點(diǎn)瓶頸問(wèn)題,那么對(duì)高并發(fā)的業(yè)務(wù)場(chǎng)景如何突破,是公司需要考慮和解決的問(wèn)題;
第四,切換到 Istio,將會(huì)增加基礎(chǔ)設(shè)施團(tuán)隊(duì)的運(yùn)維成本,并且遇到業(yè)務(wù)問(wèn)題,定位問(wèn)題涉及到業(yè)務(wù)研發(fā)團(tuán)隊(duì)和基礎(chǔ)設(shè)施研發(fā)團(tuán)隊(duì)頻繁溝通交互,自然成本也會(huì)相應(yīng)增加。
作者介紹:孫玄,畢業(yè)于浙江大學(xué),現(xiàn)任轉(zhuǎn)轉(zhuǎn)公司首席架構(gòu)師,技術(shù)委員會(huì)主席,大中后臺(tái)技術(shù)負(fù)責(zé)人(交易平臺(tái)、基礎(chǔ)服務(wù)、智能客服、基礎(chǔ)架構(gòu)、智能運(yùn)維、數(shù)據(jù)庫(kù)、安全、IT等方向);前 58 集團(tuán)技術(shù)委員會(huì)主席,高級(jí)系統(tǒng)架構(gòu)師;前百度資深研發(fā)工程師;“架構(gòu)之美” 〔beautyArch〕微信公眾號(hào)作者;擅長(zhǎng)系統(tǒng)架構(gòu)設(shè)計(jì),大數(shù)據(jù),運(yùn)維、機(jī)器學(xué)習(xí)、技術(shù)管理等領(lǐng)域;代表公司多次在業(yè)界頂級(jí)技術(shù)大會(huì) CIO 峰會(huì)、Artificial Intelligence Conference、A2M、QCon、ArchSummit、SACC、SDCC、CCTC、DTCC、Top100、Strata + Hadoop World、WOT、GITC、GIAC、TID 等發(fā)表演講,并為《程序員》雜志撰稿 2 篇。
————————————————
版權(quán)聲明:本文為CSDN博主「TiDB_PingCAP」的原創(chuàng)文章,遵循 CC 4.0 BY-SA 版權(quán)協(xié)議,轉(zhuǎn)載請(qǐng)附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/TiDB_PingCAP/article/details/103729413
聲明:本網(wǎng)部份文章為轉(zhuǎn)載文章,在每篇文章底部有說(shuō)明,文章的觀點(diǎn)和立場(chǎng)僅代表作者個(gè)人立場(chǎng),不代表微網(wǎng)立場(chǎng),若是文章轉(zhuǎn)載中有侵范您的權(quán)益,請(qǐng)發(fā)郵件到 493149@qq.com或致電13922854199通知?jiǎng)h除,謝謝!