買單俠微服務(wù)的API網(wǎng)關(guān)演化之路

伴隨著買單俠業(yè)務(wù)的快速發(fā)展,能夠支持獨立開發(fā)、獨立部署、獨立擴展的微服務(wù)在秦蒼得到了廣泛應(yīng)用和蓬勃發(fā)展,短短3年左右時間,已經(jīng)發(fā)展到了300+個微服務(wù),并且還在快速增長中。

研發(fā)逐漸意識到伴隨著微服務(wù)規(guī)?;脑鲩L,必需要重視微服務(wù)的基礎(chǔ)設(shè)施建設(shè)(API網(wǎng)關(guān)、服務(wù)注冊中心、調(diào)用鏈跟蹤等)才能保持開發(fā)效率和產(chǎn)品的質(zhì)量。

API網(wǎng)關(guān)作為訪問微服務(wù)的大門, 是訪問后臺服務(wù)的入口,作為最常用的基礎(chǔ)服務(wù)之一,其重要性不言而喻。在買單俠微服務(wù)的發(fā)展道路上,經(jīng)過了以下摸索發(fā)展階段,希望能給規(guī)?;瘧?yīng)用微服務(wù)的攻城獅們更多參考和啟發(fā)。

原始時代-沒有API網(wǎng)關(guān)的數(shù)百微服務(wù)

最初在沒有API網(wǎng)關(guān)的日子,我們部署在阿里云上的服務(wù)全部使用阿里云的負(fù)載均衡SLB直接進行通信。不同的服務(wù)不同的環(huán)境配置不同的SLB地址,運維維護的配置文件存在著大量的SLB地址,稍不留意配置錯誤,就會影響發(fā)布上線。

客戶端直接和各個服務(wù)直接交互,客戶端和服務(wù)端有強耦合。服務(wù)端的波動會直接影響到客戶端。

各個服務(wù)也是任意調(diào)用,公司服務(wù)調(diào)用的拓?fù)鋱D,其實是一個混亂、混沌的蜘蛛網(wǎng)狀圖。對數(shù)百個這樣微服務(wù)而言,沒有隔離、沒有把控,不僅容易引起問題,而且各個服務(wù)的通用需求認(rèn)證、監(jiān)控、轉(zhuǎn)換等功能需要多次實現(xiàn),無法重用。

買單俠微服務(wù)的API網(wǎng)關(guān)演化之路

青銅時代-面向服務(wù)的網(wǎng)關(guān)Spring Cloud Zuul

痛則思變,買單俠的微服務(wù)需要一個入口,就是API網(wǎng)關(guān),幫助解耦客戶端和具體后端微服務(wù),它在微服務(wù)架構(gòu)中很像面向?qū)ο笤O(shè)計模式中的Facade模式封裝內(nèi)部系統(tǒng)的架構(gòu),并且提供API給各個客戶端作為服務(wù)入口。

由于買單俠微服務(wù)技術(shù)路線采用Spring Cloud,基于Netflix開源的基礎(chǔ)組件搭建基礎(chǔ)設(shè)施,例如服務(wù)注冊中心Eureka,在API網(wǎng)關(guān)選項中,考慮和Eureka、Ribbon等的兼容,Zuul成了我們的不二選擇。

作為API網(wǎng)關(guān),Zuul能根據(jù)簡單配置就能完成PATH和URL的路由映射轉(zhuǎn)發(fā)。

Zuul提供了一個技術(shù)框架從請求抵達(pre),請求路由(route)到請求結(jié)束(post)以及請求出錯(error)各個階段Zuul都有專門類型的過濾器filter及示例,參見下圖。開發(fā)可以在請求路由轉(zhuǎn)發(fā)過程中的各個階段實現(xiàn)自己的過濾器完成邏輯控制。

買單俠微服務(wù)的API網(wǎng)關(guān)演化之路

Zuul可以定時掃描指定目錄下用戶自己實現(xiàn)的groovy過濾器,通過groovy類加載器動態(tài)加載,從而在不用重啟API網(wǎng)關(guān)下達到動態(tài)添加、更新過濾器。

由于買單俠的微服務(wù)使用了基于Spring Cloud Netflix的Eureka作為服務(wù)注冊發(fā)現(xiàn),Zuul也能作為Eureka Client從Eureka Server自動發(fā)現(xiàn)注冊在上面的服務(wù)。

這樣服務(wù)名可以作為發(fā)往網(wǎng)關(guān)請求的RootPath,比如業(yè)務(wù)線定義了一個API: /user 給手機端,以前得在Zuul添加mapping, /user --> /serviceName/user, 添加時需要改APIGateway的配置,改完需要重啟。

現(xiàn)在,只要暴露給手機端是/demo-service/user, demo-service是服務(wù)名,經(jīng)過Zuul時不用任何配置,它會根據(jù)eureka的服務(wù)名自動routing到demo-service, 然后調(diào)用user,所以serviceName 可以作為RootPath。無需額外配置,非常方便。

買單俠微服務(wù)的API網(wǎng)關(guān)演化之路

在產(chǎn)品線入口,買單俠開始引入Zuul作為API網(wǎng)關(guān)作為API門戶管理轉(zhuǎn)發(fā)請求到后端服務(wù),并支持了請求校驗和跨域功能。走出了原始時代的混沌。

白銀時代-支持灰度發(fā)布的服務(wù)分組入口Zuul

Zuul開始幫助我們解耦了客戶端和具體后端微服務(wù),但對于上百微服務(wù)的規(guī)?;芾硖魬?zhàn)一直存在,我們希望能達到微服務(wù)的分組和系統(tǒng)化管理。

比如一條產(chǎn)品線,可能會有直銷商城、賬務(wù)、審核、基礎(chǔ)應(yīng)用服務(wù)(字典服務(wù))等業(yè)務(wù)系統(tǒng)(分組的服務(wù))。而每個分組,會期望在請求抵達自己業(yè)務(wù)系統(tǒng)中做一些通用操作。

在這種背景下,我們期望Zuul成為服務(wù)分組后各個業(yè)務(wù)系統(tǒng)自己的入口服務(wù)。為此,我們改造了我們服務(wù)發(fā)現(xiàn)的調(diào)用方式。

類型調(diào)用方式

服務(wù)分組內(nèi)服務(wù)發(fā)現(xiàn)直接調(diào)用

跨服務(wù)分組的服務(wù)發(fā)現(xiàn)調(diào)用發(fā)給Zuul,再由Zuul轉(zhuǎn)發(fā)到具體服務(wù)

服務(wù)分組內(nèi)的服務(wù)每個服務(wù)注冊到Eureka的metadata中專門有一項說明自己服務(wù)分組內(nèi)的入口API網(wǎng)關(guān)Zuul的服務(wù)ID。然后服務(wù)調(diào)用時,先發(fā)現(xiàn)對應(yīng)服務(wù)的Zuul是否和自己本身分組的Zuul服務(wù)ID一樣,是就直接調(diào)用,否則請求自動發(fā)往對應(yīng)服務(wù)Zuul,然后路由轉(zhuǎn)發(fā)到對應(yīng)服務(wù)。

Zuul可以自治化管理自己業(yè)務(wù)系統(tǒng)。比如我們要對一個業(yè)務(wù)系統(tǒng)中的部分服務(wù)做灰度發(fā)布。那么只需要更改直銷商城業(yè)務(wù)系統(tǒng)API網(wǎng)關(guān)。

所以我們在Zuul里實現(xiàn)了灰度發(fā)布的策略管理,可以選擇權(quán)重策略,白名單策略,用戶區(qū)域策略等對用戶進行自定義路由分流。

比如白名單策略,Zuul可以根據(jù)請求里的header信息,例如用戶token來判斷是否白名單中用戶路由到指定服務(wù),這樣發(fā)布系統(tǒng)時,可以在舊服務(wù)在線情況下,發(fā)布新版本服務(wù)。讓我們的QA作為白名單策略中用戶路由到新版本服務(wù)系統(tǒng)中進行測試。測試通過后再切換流量到新版本服務(wù),關(guān)閉老服務(wù)。

另外,買單俠微服務(wù)部署開始應(yīng)用docker技術(shù)解決快速部署并達到跨環(huán)境標(biāo)準(zhǔn)一致。上百微服務(wù)不可能一次性遷移到容器環(huán)境,我們采取了分業(yè)務(wù)系統(tǒng),按照服務(wù)分組逐步遷移的方式。這里的一個挑戰(zhàn)是服務(wù)容器化后,基于overlay網(wǎng)絡(luò),有了獨立于阿里云ECS機器的容器IP,現(xiàn)在注冊到Eureka的就是容器IP。

在同一個集群內(nèi),即容器化的服務(wù)間基于容器IP是可以相互訪問,但是集群外,即非容器化的服務(wù)根據(jù)容器IP是沒法訪問容器化的服務(wù),網(wǎng)絡(luò)是不同的。

阿里云容器平臺推薦的遷移方案是給每個容器化服務(wù)綁定SLB(server load balance)一個靜態(tài)IP地址來實現(xiàn)容器集群外服務(wù)訪問容器服務(wù)。但是對于上百規(guī)模的微服務(wù),每個服務(wù)配置SLB是巨大的工程,特別我們還有QA,Staging,Production三套環(huán)境,工作量翻了三倍。

API網(wǎng)關(guān)Zuul在這里繼續(xù)扮演了極其重要的角色,簡化解決了我們的這個遷移問題。我們僅僅把API網(wǎng)關(guān)Zuul作為每個服務(wù)分組的代理入口綁定了SLB,并且把這個靜態(tài)IP作為Zuul的hostname注冊到Eureka。服務(wù)分組外的服務(wù)對容器內(nèi)服務(wù)1的訪問包括下面幾步:

1. 先獲取到該服務(wù)1注冊到Eureka的metadata,得到服務(wù)分組入口Zuul service ID。從Eureka中查到Zuul注冊的hostname即SLB靜態(tài)IP地址。

2. 按照SLB發(fā)送請求給Zuul,請求路徑中攜帶服務(wù)1的serviced.

3. Zuul根據(jù)serviceId自動路由到服務(wù)1。

買單俠微服務(wù)的API網(wǎng)關(guān)演化之路

由此可見,Zuul作為每個服務(wù)分組的入口在買單俠微服務(wù)體系中作用巨大,解決了灰度發(fā)布、容器遷移等一系列關(guān)鍵問題,并將繼續(xù)扮演舉足輕重的角色。

黃金時代-面向終端用戶的出入口網(wǎng)關(guān)Nginx

當(dāng)眾多服務(wù)分組有了自己的入口Zuul,在產(chǎn)品線面向用戶的入口處網(wǎng)關(guān)又發(fā)現(xiàn)了一種尷尬情況。

原來有一個直接面向用戶的Zuul將用戶請求轉(zhuǎn)發(fā)給后臺服務(wù),現(xiàn)在還有一個管理服務(wù)分組的入口網(wǎng)關(guān),將服務(wù)分組外的后臺請求轉(zhuǎn)發(fā)給組內(nèi)服務(wù)。

出現(xiàn)了兩個入口!

同時,Zuul由于啟用了Spring Boot Actuator,暴露了Log, Trace, Dump等敏感Endpoint,在安全方面引起了我們的擔(dān)心顧慮。并且基于服務(wù)注冊發(fā)現(xiàn),理論上你知道serviceId可以把任意請求轉(zhuǎn)發(fā)給對應(yīng)服務(wù)。

面向終端用戶,Zuul是最合適的入口選擇嗎?

并且在我們性能壓力測試下,Zuul雖然適合編程實現(xiàn)業(yè)務(wù)邏輯,本身的性能并不占優(yōu),特別更改配置重啟服務(wù)通常要2分鐘左右非常慢。通常要部署多個Zuul容器保證高可用,還是有一定資源消耗。

對于終端用戶,隱藏內(nèi)部服務(wù)細(xì)節(jié),并提供高性能的轉(zhuǎn)發(fā)服務(wù),Nginx其實是非常不錯的選擇。并在我們產(chǎn)品線開始推廣使用。并且在一條產(chǎn)品線上可被多個業(yè)務(wù)系統(tǒng)(服務(wù)分組)共享使用,比如直銷商城和直銷客戶,從而提高資源利用率。

買單俠微服務(wù)的API網(wǎng)關(guān)演化之路

解決了入口問題,出口其實也是非常需要引起重視的。

我們的微服務(wù)會有一些對外渠道,比如資金源需要訪問不同的資金渠道,支付需要訪問不同的支付渠道,不同渠道往往有不同的安全性要求,例如僅僅允許運行IP白名單的服務(wù)訪問,需要特定證書。之前訪問這些渠道都是由具體服務(wù)自己直接負(fù)責(zé)。

當(dāng)業(yè)務(wù)規(guī)模,服務(wù)規(guī)模增大,對外出口的訪問管理也容易引起混亂,對統(tǒng)一出口的需求變得強烈。

容器部署讓統(tǒng)一出口成為必要需求,因為容器會在集群內(nèi)機器上隨機部署,具有隨機IP,而給容器集群內(nèi)所有機器配置白名單,裝證書并不現(xiàn)實。

我們需要統(tǒng)一的API出口網(wǎng)關(guān),在這里我們可以統(tǒng)一管理證書,提供固定IP。實際上就是一個代理幫助我們轉(zhuǎn)發(fā)請求到外部渠道服務(wù)。

Nginx再次以優(yōu)異表現(xiàn)勝任了我們的需求,擔(dān)當(dāng)我們的出口API網(wǎng)關(guān),我們親切地稱呼它outlets。

每臺Nginx代理固定在一臺ECS上,提供ECS固定IP給外部數(shù)據(jù)提供商。Nginx啟動速度快,并能動態(tài)加載配置,平滑升級。容器可以訪問出口API網(wǎng)關(guān)來代理訪問外部依賴服務(wù)。

買單俠微服務(wù)的API網(wǎng)關(guān)演化之路

白金時代-接入層網(wǎng)關(guān)探索升級從Nginx到Kong

在我們使用Nginx作為出入口網(wǎng)關(guān)過程中,我們也關(guān)注到基于Nginx的Kong。作為接入層網(wǎng)關(guān),Kong繼承Nginx的優(yōu)異性能表現(xiàn)并且體現(xiàn)了更多的擴展性和網(wǎng)關(guān)管理功能。

買單俠微服務(wù)的API網(wǎng)關(guān)演化之路

基于OpenResty,所有對Kong的配置操作都通過REST API完成并且即時生效。

由于Kong基于Nginx,很多基本配置都可以映射到Nginx。

Kong一個非常吸引人的特色是它的豐富插件,有認(rèn)證,安全,限流,監(jiān)控,轉(zhuǎn)換,日志等多種類型插件,能輕松配置完成訪問控制,黑白名單設(shè)置,限流,跨域等等功能。

買單俠微服務(wù)的API網(wǎng)關(guān)演化之路

當(dāng)然,由于Kong的靈活性,對于Kong的權(quán)限管理和使用流程上還有待規(guī)范。

不久我們可預(yù)期各條產(chǎn)品線不僅具有對外的接入層網(wǎng)關(guān)Kong,在這里可以基于Kong的插件實現(xiàn)業(yè)務(wù)無關(guān)的出入口基本管理,而且在它后面是由獨立Zuul作為入口的各個業(yè)務(wù)系統(tǒng),開發(fā)可以利用Zuul實現(xiàn)自己業(yè)務(wù)相關(guān)的入口控制管理。

總結(jié)

買單俠微服務(wù)的API網(wǎng)關(guān)演化之路著重分享了買單俠微服務(wù)體系中,API網(wǎng)關(guān)建設(shè)從無到有,從少到多,從單一到多元化的演進過程,下表總結(jié)了目前我們主要采用的網(wǎng)關(guān)技術(shù)方案。

在保障基本路由轉(zhuǎn)發(fā)外,API網(wǎng)關(guān)更在買單俠的微服務(wù)治理中扮演重要角色,隨著規(guī)?;芾砗蜆I(yè)務(wù)需求,其在服務(wù)分組管控、灰度發(fā)布、熔斷監(jiān)控、容器化遷移、統(tǒng)一出入口管理等場景都有深入實踐,并且還在不斷演進發(fā)展中。

極客網(wǎng)企業(yè)會員

免責(zé)聲明:本網(wǎng)站內(nèi)容主要來自原創(chuàng)、合作伙伴供稿和第三方自媒體作者投稿,凡在本網(wǎng)站出現(xiàn)的信息,均僅供參考。本網(wǎng)站將盡力確保所提供信息的準(zhǔn)確性及可靠性,但不保證有關(guān)資料的準(zhǔn)確性及可靠性,讀者在使用前請進一步核實,并對任何自主決定的行為負(fù)責(zé)。本網(wǎng)站對有關(guān)資料所引致的錯誤、不確或遺漏,概不負(fù)任何法律責(zé)任。任何單位或個人認(rèn)為本網(wǎng)站中的網(wǎng)頁或鏈接內(nèi)容可能涉嫌侵犯其知識產(chǎn)權(quán)或存在不實內(nèi)容時,應(yīng)及時向本網(wǎng)站提出書面權(quán)利通知或不實情況說明,并提供身份證明、權(quán)屬證明及詳細(xì)侵權(quán)或不實情況證明。本網(wǎng)站在收到上述法律文件后,將會依法盡快聯(lián)系相關(guān)文章源頭核實,溝通刪除相關(guān)內(nèi)容或斷開相關(guān)鏈接。

2019-09-20
買單俠微服務(wù)的API網(wǎng)關(guān)演化之路
伴隨著買單俠業(yè)務(wù)的快速發(fā)展,能夠支持獨立開發(fā)、獨立部署、獨立擴展的微服務(wù)在秦蒼得到了廣泛應(yīng)用和蓬勃發(fā)展,短短3年左右時間,已經(jīng)發(fā)展到了300+個微服務(wù),并且還在

長按掃碼 閱讀全文