今年,ServiceMesh(服務(wù)網(wǎng)格) 概念在社區(qū)里頭非?;穑腥颂岢?2018 年是 ServiceMesh 年,還有人提出 ServiceMesh 是下一代的微服務(wù)架構(gòu)基礎(chǔ)。作為架構(gòu)師,如果你現(xiàn)在還不了解 ServiceMesh 的話,是否感覺有點(diǎn)落伍了?
那么到底什么是 ServiceMesh?它的誕生是為了解決什么問(wèn)題?企業(yè)是否適合引入 ServiceMesh?通過(guò)這篇文章,將為你一一解答這些問(wèn)題。
微服務(wù)架構(gòu)的核心技術(shù)問(wèn)題
在業(yè)務(wù)規(guī)?;脱邪l(fā)效能提升等因素的驅(qū)動(dòng)下,從單塊應(yīng)用向微服務(wù)架構(gòu)的轉(zhuǎn)型 (如下圖所示),已經(jīng)成為很多企業(yè) (尤其是互聯(lián)網(wǎng)企業(yè)) 數(shù)字化轉(zhuǎn)型的趨勢(shì)。
在微服務(wù)模式下,企業(yè)內(nèi)部服務(wù)少則幾個(gè)到幾十個(gè),多則上百個(gè),每個(gè)服務(wù)一般都以集群方式部署,這時(shí)自然產(chǎn)生兩個(gè)問(wèn)題 (如下圖所示):
一、服務(wù)發(fā)現(xiàn):服務(wù)的消費(fèi)方 (Consumer) 如何發(fā)現(xiàn)服務(wù)的提供方 (Provider)?
二、負(fù)載均衡:服務(wù)的消費(fèi)方如何以某種負(fù)載均衡策略訪問(wèn)集群中的服務(wù)提供方實(shí)例?
作為架構(gòu)師,如果你理解了這兩個(gè)問(wèn)題,也就理解了微服務(wù)架構(gòu)在技術(shù)上最核心問(wèn)題。
三種服務(wù)發(fā)現(xiàn)模式
服務(wù)發(fā)現(xiàn)和負(fù)載均衡并不是新問(wèn)題,業(yè)界其實(shí)已經(jīng)探索和總結(jié)出一些常用的模式,這些模式的核心其實(shí)是代理 (Proxy,如下圖所以),以及代理在架構(gòu)中所處的位置。
在服務(wù)消費(fèi)方和服務(wù)提供方之間增加一層代理,由代理負(fù)責(zé)服務(wù)發(fā)現(xiàn)和負(fù)載均衡功能,消費(fèi)方通過(guò)代理間接訪問(wèn)目標(biāo)服務(wù)。根據(jù)代理在架構(gòu)上所處的位置不同,當(dāng)前業(yè)界主要有三種不同的服務(wù)發(fā)現(xiàn)模式:
模式一:傳統(tǒng)集中式代理
這是最簡(jiǎn)單和傳統(tǒng)做法,在服務(wù)消費(fèi)者和生產(chǎn)者之間,代理作為獨(dú)立一層集中部署,由獨(dú)立團(tuán)隊(duì) (一般是運(yùn)維或框架) 負(fù)責(zé)治理和運(yùn)維。常用的集中式代理有硬件負(fù)載均衡器 (如 F5),或者軟件負(fù)載均衡器 (如 Nginx),F(xiàn)5(4 層負(fù)載)+Nginx(7 層負(fù)載) 這種軟硬結(jié)合兩層代理也是業(yè)內(nèi)常見做法,兼顧配置的靈活性 (Nginx 比 F5 易于配置)。
這種方式通常在 DNS 域名服務(wù)器的配合下實(shí)現(xiàn)服務(wù)發(fā)現(xiàn),服務(wù)注冊(cè) (建立服務(wù)域名和 IP 地址之間的映射關(guān)系) 一般由運(yùn)維人員在代理上手工配置,服務(wù)消費(fèi)方僅依賴服務(wù)域名,這個(gè)域名指向代理,由代理解析目標(biāo)地址并做負(fù)載均衡和調(diào)用。
國(guó)外知名電商網(wǎng)站 eBay,雖然體量巨大,但其內(nèi)部的服務(wù)發(fā)現(xiàn)機(jī)制仍然是基于這種傳統(tǒng)的集中代理模式,國(guó)內(nèi)公司如攜程,也是采用這種模式。
模式二:客戶端嵌入式代理
這是很多互聯(lián)網(wǎng)公司比較流行的一種做法,代理 (包括服務(wù)發(fā)現(xiàn)和負(fù)載均衡邏輯) 以客戶庫(kù)的形式嵌入在應(yīng)用程序中。這種模式一般需要獨(dú)立的服務(wù)注冊(cè)中心組件配合,服務(wù)啟動(dòng)時(shí)自動(dòng)注冊(cè)到注冊(cè)中心并定期報(bào)心跳,客戶端代理則發(fā)現(xiàn)服務(wù)并做負(fù)載均衡。
Netflix 開源的 Eureka(注冊(cè)中心)[附錄 1] 和 Ribbon(客戶端代理)[附錄 2] 是這種模式的典型案例,國(guó)內(nèi)阿里開源的 Dubbo 也是采用這種模式。
模式三:主機(jī)獨(dú)立進(jìn)程代理
這種做法是上面兩種模式的一個(gè)折中,代理既不是獨(dú)立集中部署,也不嵌入在客戶應(yīng)用程序中,而是作為獨(dú)立進(jìn)程部署在每一個(gè)主機(jī)上,一個(gè)主機(jī)上的多個(gè)消費(fèi)者應(yīng)用可以共用這個(gè)代理,實(shí)現(xiàn)服務(wù)發(fā)現(xiàn)和負(fù)載均衡,如下圖所示。這個(gè)模式一般也需要獨(dú)立的服務(wù)注冊(cè)中心組件配合,作用同模式二。
Airbnb 的 SmartStack[附錄 3] 是這種模式早期實(shí)踐產(chǎn)品,國(guó)內(nèi)公司唯品會(huì)對(duì)這種模式也有探索和實(shí)踐。
三種服務(wù)發(fā)現(xiàn)模式的比較
上面介紹的三種服務(wù)發(fā)現(xiàn)模式各有優(yōu)劣,沒(méi)有絕對(duì)的好壞,可以認(rèn)為是三種不同的架構(gòu)風(fēng)格,在不同的公司都有成功實(shí)踐。下表總結(jié)三種服務(wù)發(fā)現(xiàn)模式的優(yōu)劣比較,業(yè)界案例和適用場(chǎng)景建議,供架構(gòu)師選型參考:
服務(wù)網(wǎng)格 ServiceMesh?
所謂的 ServiceMesh,其實(shí)本質(zhì)上就是上面提到的模式三:主機(jī)獨(dú)立進(jìn)程模式,這個(gè)模式其實(shí)并不新鮮,業(yè)界 (國(guó)外的 Airbnb 和國(guó)內(nèi)的唯品會(huì)等) 早有實(shí)踐,那么為什么現(xiàn)在這個(gè)概念又流行起來(lái)了呢?我認(rèn)為主要原因如下:
上述模式一和二有一些固有缺陷,模式一相對(duì)比較重,有單點(diǎn)問(wèn)題和性能問(wèn)題;模式二則有客戶端復(fù)雜,支持多語(yǔ)言困難,無(wú)法集中治理的問(wèn)題。模式三是模式一和二的折中,彌補(bǔ)了兩者的不足,它是純分布式的,沒(méi)有單點(diǎn)問(wèn)題,性能也不錯(cuò),應(yīng)用語(yǔ)言棧無(wú)關(guān),可以集中治理。
微服務(wù)化、多語(yǔ)言和容器化發(fā)展的趨勢(shì),企業(yè)迫切需要一種輕量級(jí)的服務(wù)發(fā)現(xiàn)機(jī)制,ServiceMesh 正是迎合這種趨勢(shì)誕生,當(dāng)然這還和一些大廠 (如 Google/IBM 等) 的背后推動(dòng)有關(guān)。
模式三 (ServiceMesh) 也被形象稱為邊車 (Sidecar) 模式,如下圖,早期有一些摩托車,除了主駕駛位,還帶一個(gè)邊車位,可以額外坐一個(gè)人。在模式三中,業(yè)務(wù)代碼進(jìn)程 (相當(dāng)于主駕駛) 共享一個(gè)代理 (相當(dāng)于邊車),代理除了負(fù)責(zé)服務(wù)發(fā)現(xiàn)和負(fù)載均衡,還負(fù)責(zé)動(dòng)態(tài)路由、容錯(cuò)限流、監(jiān)控度量和安全日志等功能,這些功能是具體業(yè)務(wù)無(wú)關(guān)的,屬于跨橫切面關(guān)注點(diǎn) (Cross-Cutting Concerns) 范疇。
在新一代的 ServiceMesh 架構(gòu)中 (下圖上方),服務(wù)的消費(fèi)方和提供方主機(jī) (或者容器) 兩邊都會(huì)部署代理 SideCar。ServiceMesh 比較正式的術(shù)語(yǔ)也叫數(shù)據(jù)平面 (DataPlane),與數(shù)據(jù)平面對(duì)應(yīng)的還有一個(gè)獨(dú)立部署的控制平面 (ControlPlane),用來(lái)集中配置和管理數(shù)據(jù)平面,也可以對(duì)接各種服務(wù)發(fā)現(xiàn)機(jī)制 (如 K8S 服務(wù)發(fā)現(xiàn))。術(shù)語(yǔ)數(shù)據(jù)平面和控制平面,估計(jì)是偏網(wǎng)絡(luò) SDN 背景的人提出來(lái)的。
上圖左下角,每個(gè)主機(jī)上同時(shí)居住了業(yè)務(wù)邏輯代碼 (綠色表示) 和代理 (藍(lán)色表示),服務(wù)之間通過(guò)代理發(fā)現(xiàn)和調(diào)用目標(biāo)服務(wù),形成服務(wù)之間的一種網(wǎng)絡(luò)狀依賴關(guān)系,控制平面則可以配置這種依賴調(diào)用關(guān)系,也可以調(diào)撥路由流量。如果我們把主機(jī)和業(yè)務(wù)邏輯剝離,就出現(xiàn)一種網(wǎng)格狀架構(gòu) (上圖右下角),服務(wù)網(wǎng)格由此得名。
Istio[附錄 4] 是 Google/IBM 等大廠支持和推進(jìn)的一個(gè) ServiceMesh 標(biāo)準(zhǔn)化工作組,上圖是 Istio 給出的 ServiceMesh 參考架構(gòu) (注意這個(gè)是老版架構(gòu),新版有一些調(diào)整,但是大框架沒(méi)變)。Istio 專注在控制平面的架構(gòu)、功能、以及控制平面和數(shù)據(jù)平面之間 API 的標(biāo)準(zhǔn)化,它的控制平面功能主要包括:
Istio-Manager:負(fù)責(zé)服務(wù)發(fā)現(xiàn),路由分流,熔斷限流等配置數(shù)據(jù)的管理和下發(fā)
Mixer:負(fù)責(zé)收集代理上采集的度量數(shù)據(jù),進(jìn)行集中監(jiān)控
Istio-Auth:負(fù)責(zé)安全控制數(shù)據(jù)的管理和下發(fā)
Envoy[附錄 5] 是目前 Istio 主力支持的數(shù)據(jù)平面代理,其它主流代理如 nginx/kong 等也正在陸續(xù)加入這個(gè)陣營(yíng)。kubernetes 是目前 Isito 主力支持的容器云環(huán)境。
我的建議
目前我本人并不特別看好 ServiceMesh,也不是特別建議企業(yè)在生產(chǎn)上試水 ServiceMesh,主要原因如下:
本質(zhì)上,ServiceMesh 其實(shí)并不是新東西,它只是模式三主機(jī)獨(dú)立進(jìn)程模式,這個(gè)模式早就有公司在探索和實(shí)踐了,但是并未流行起來(lái),可見這個(gè)模式也是存在落地挑戰(zhàn)的。
表面上看,模式三既是模式一和模式二的折中,也解決了模式一和模式二存在的問(wèn)題。
但是在每個(gè)主機(jī)上獨(dú)立部署一個(gè)代理進(jìn)程,是有很大運(yùn)維管理開銷的,一方面是規(guī)?;渴鸬膯?wèn)題 (考慮服務(wù)很多,機(jī)器也很多的場(chǎng)景);另一方面是如何監(jiān)控治理的問(wèn)題,代理掛了怎么辦?你的團(tuán)隊(duì)是否具備自動(dòng)化運(yùn)維和監(jiān)控的能力?另外開發(fā)人員在服務(wù)調(diào)試的時(shí)候,會(huì)依賴于這個(gè)獨(dú)立的代理,調(diào)試排錯(cuò)比較麻煩,這個(gè)問(wèn)題怎么解決?
Istio 的確做了一些標(biāo)準(zhǔn)化工作,但是沒(méi)有什么特別的創(chuàng)新,可是說(shuō)換湯不換藥,就是把模式三規(guī)范化和包裝了一下。透過(guò)現(xiàn)象看本質(zhì),Google/IBM 等行業(yè)大廠在背后推 Isito/ServiceMesh,背后有一些市場(chǎng)利益訴求考慮,例如 Google 要推進(jìn)它的 kubernates 和公有云生態(tài)。
ServiceMesh 在年初聲音比較大,最近漸漸安靜下來(lái),我聽到國(guó)內(nèi)只有一些大廠 (華為,新浪微博,螞蟻金服等) 在試水,實(shí)際生產(chǎn)級(jí)落地的案例聊聊無(wú)幾。大多數(shù)企業(yè)對(duì) ServiceMesh 只是觀望,很多架構(gòu)師對(duì) ServiceMesh 實(shí)際落地都存在疑慮。
所以我的個(gè)人建議,對(duì)于大部分企業(yè) (一般運(yùn)維和研發(fā)能力不是特別強(qiáng)),采用模式一集中代理模式就足夠了。這個(gè)模式比較傳統(tǒng)不新鮮,但是在很多一線企業(yè)已經(jīng)切實(shí)落地,我甚至認(rèn)為,除了一些大廠,大部分中小企業(yè)的服務(wù)發(fā)現(xiàn)架構(gòu)采用的就是集中代理。我本人經(jīng)歷過(guò)三家互聯(lián)網(wǎng)公司,大的有 eBay,中等有攜程,小的有拍拍貸,都是采用集中式代理模式,而且玩得都很好。我的架構(gòu)理念很簡(jiǎn)單,對(duì)于生產(chǎn)級(jí)應(yīng)用,不追新,老實(shí)采用大部分企業(yè)落地過(guò)的方案。
模式一的最大好處是集中治理,應(yīng)用不侵入,語(yǔ)言棧無(wú)關(guān),另外因?yàn)槟J揭皇羌胁渴鸬?,不像模式三是分布式部署,所以模式一的運(yùn)維開銷也遠(yuǎn)小于模式三。對(duì)于模式一,大家最大的顧慮是性能和單點(diǎn)問(wèn)題,其實(shí)性能還是 OK 的,如果架構(gòu)和容量規(guī)劃合理的話,實(shí)際生產(chǎn)中經(jīng)過(guò)集中代理的性能開銷一般可以控制在小于 10 個(gè) ms,eBay 和攜程等大流量企業(yè)的成功實(shí)踐已經(jīng)驗(yàn)證了這點(diǎn)。單點(diǎn)問(wèn)題一般建議采用兩層負(fù)載結(jié)構(gòu),例如硬件 F5+ 軟件 nginx 兩層負(fù)載,F(xiàn)5 以主從 HA 部署,nginx 則以集群多實(shí)例部署,這種架構(gòu)兼顧了高可用和配置的靈活性。
另外,模式一還可以和服務(wù)注冊(cè)中心結(jié)合,從而降低手工配置的復(fù)雜性,實(shí)現(xiàn) DevOps 研發(fā)自助部署,一種方案如下圖所示:
服務(wù)啟動(dòng)時(shí)自動(dòng)注冊(cè)到服務(wù)注冊(cè)中心并定期報(bào)心跳,Proxy 則定期到服務(wù)注冊(cè)中心同步實(shí)例。這種方式下,不需要為每個(gè)服務(wù)申請(qǐng)一個(gè)域名,只需一個(gè)泛域名即可,消費(fèi)者訪問(wèn)服務(wù)時(shí)采用服務(wù)名 + 泛域名即可,整個(gè)服務(wù)上線流程可以做到 DevOps 研發(fā)自助。目前社區(qū)流行的一些開源代理如 traefik[附錄 7] 和 kong[附錄 8] 等都支持和多種服務(wù)注冊(cè)中心 (Consul/Eureka/Etcd/Zookeeper 等) 進(jìn)行集成。目前這種方案在拍拍貸有初步成功實(shí)踐,采用 kong[附錄 7] 和自研服務(wù)注冊(cè)中心 Radar[附錄 8],同時(shí)和容器云調(diào)度平臺(tái)配合,實(shí)現(xiàn)了研發(fā)全自助式發(fā)布上線。
結(jié)? ?論
1、服務(wù)注冊(cè)發(fā)現(xiàn)和負(fù)載均衡是微服務(wù)架構(gòu)在技術(shù)上的根本問(wèn)題,解決的辦法是采用代理 Proxy。根據(jù)代理在架構(gòu)上的位置不同,服務(wù)發(fā)現(xiàn)代理一般有三種模式:
模式一:集中式代理
模式二:客戶端嵌入式代理
模式三:主機(jī)獨(dú)立進(jìn)程代理
這三種模式?jīng)]有絕對(duì)的好壞之分,只是三種不同的架構(gòu)風(fēng)格,各有優(yōu)劣和適用場(chǎng)景,在不同企業(yè)都有成功落地案例。
2、ServiceMesh 本質(zhì)上就是模式三中主機(jī)獨(dú)立進(jìn)程代理,它結(jié)合了模式一和模式二的優(yōu)勢(shì),但是分布式部署運(yùn)維管理開銷大。Istio 對(duì) ServiceMesh 的架構(gòu)、功能和 API 進(jìn)行了標(biāo)準(zhǔn)化。
3、ServiceMesh 還在演進(jìn)中,生產(chǎn)落地仍有挑戰(zhàn),一般企業(yè)不建議生產(chǎn)級(jí)使用。集中式代理最成熟,對(duì)于一般中小企業(yè),建議從集中式代理開始,等達(dá)到一定規(guī)模和具備一定的研發(fā)運(yùn)維能力,再根據(jù)需要考慮其它服務(wù)發(fā)現(xiàn)模式。
4、架構(gòu)師不要盲目追新,在理解微服務(wù)架構(gòu)原理的基礎(chǔ)上,可以學(xué)習(xí)和試點(diǎn)新技術(shù),但是對(duì)于生產(chǎn)級(jí)應(yīng)用,應(yīng)該以成熟穩(wěn)定,有大規(guī)模落地案例作為選型第一準(zhǔn)則。
歡迎工作一到五年的Java工程師朋友們加入Java程序員開發(fā): 854393687
群內(nèi)提供免費(fèi)的Java架構(gòu)學(xué)習(xí)資料(里面有高可用、高并發(fā)、高性能及分布式、Jvm性能調(diào)優(yōu)、Spring源碼,MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多個(gè)知識(shí)點(diǎn)的架構(gòu)資料)合理利用自己每一分每一秒的時(shí)間來(lái)學(xué)習(xí)提升自己,不要再用"沒(méi)有時(shí)間“來(lái)掩飾自己思想上的懶惰!趁年輕,使勁拼,給未來(lái)的自己一個(gè)交代!