一、前言
Zuul 網(wǎng)關(guān)是具體核心業(yè)務(wù)服務(wù)的看門神盔憨,相比具體實(shí)現(xiàn)業(yè)務(wù)的系統(tǒng)服務(wù)來說它是一個(gè)邊緣服務(wù)徙菠,主要提供動(dòng)態(tài)路由,監(jiān)控郁岩,彈性婿奔,安全性等功能。在分布式的微服務(wù)系統(tǒng)中问慎,系統(tǒng)被拆為了多套系統(tǒng)萍摊,通過zuul網(wǎng)關(guān)來對用戶的請求進(jìn)行路由,轉(zhuǎn)發(fā)到具體的后臺(tái)服務(wù)系統(tǒng)中如叼。
本 Chat 主要內(nèi)容如下:
- 服務(wù)網(wǎng)關(guān)演化歷程冰木。
- Zuul 1.0 服務(wù)架構(gòu)與源碼剖析。
- Zuul 2.0 服務(wù)架構(gòu)新特性笼恰。
二踊沸、服務(wù)網(wǎng)關(guān)演化歷程
網(wǎng)關(guān)是具體核心業(yè)務(wù)服務(wù)的看門神,相比具體實(shí)現(xiàn)業(yè)務(wù)的系統(tǒng)服務(wù)來說它是一個(gè)邊緣服務(wù)挖腰,主要提供動(dòng)態(tài)路由雕沿,監(jiān)控,彈性猴仑,安全性等功能审轮,下面我們從單體應(yīng)用到多體應(yīng)用的演化過程來講解網(wǎng)關(guān)的演化歷程肥哎。
一般業(yè)務(wù)系統(tǒng)發(fā)展歷程都是基本相似的,從單體應(yīng)用到多應(yīng)用疾渣,從本地調(diào)用到遠(yuǎn)程調(diào)用篡诽。對應(yīng)單體應(yīng)用架構(gòu)模式(如下圖1),由于只需一個(gè)應(yīng)用榴捡,所有業(yè)務(wù)模塊的功能都打包為了一個(gè) War 包進(jìn)行部署杈女,這樣可以減少機(jī)器資源和部署的繁瑣。
圖1 單體應(yīng)用
在單體應(yīng)用中吊圾,網(wǎng)關(guān)模塊是和應(yīng)用部署到同一個(gè)jvm進(jìn)程里面的达椰,當(dāng)外部移動(dòng)設(shè)備或者web站點(diǎn)訪問單體應(yīng)用的功能時(shí)候,請求是先被應(yīng)用的網(wǎng)關(guān)模塊攔截的项乒,網(wǎng)關(guān)模塊對請求進(jìn)行鑒權(quán)啰劲、限流等動(dòng)作后在把具體的請求轉(zhuǎn)發(fā)到當(dāng)前應(yīng)用對應(yīng)的模塊進(jìn)行處理。
隨著業(yè)務(wù)的發(fā)展檀何,網(wǎng)站的流量會(huì)越來越大蝇裤,在單體應(yīng)用中簡單的通過加機(jī)器的方式可以帶來的承受流量沖擊的能力也越來越低,這時(shí)候就會(huì)考慮根據(jù)業(yè)務(wù)將單體應(yīng)用拆成若干個(gè)功能獨(dú)立的應(yīng)用频鉴,單體應(yīng)用拆為多個(gè)應(yīng)用后栓辜,由于不同的應(yīng)用開發(fā)對應(yīng)的功能,所以多應(yīng)用開發(fā)之間可以獨(dú)立開發(fā)而不用去理解對方的業(yè)務(wù)垛孔,另外不同的應(yīng)用模塊只承受對應(yīng)業(yè)務(wù)流量的壓力藕甩,不會(huì)對其他應(yīng)用模塊造成影響,這時(shí)候多體的分布式系統(tǒng)就出現(xiàn)了似炎,如下圖2辛萍。
圖2 多體應(yīng)用
如上圖在多體應(yīng)用中業(yè)務(wù)模塊A和B單獨(dú)起了個(gè)應(yīng)用,每個(gè)應(yīng)用里面有自己的網(wǎng)關(guān)模塊羡藐,如果業(yè)務(wù)模塊多了贩毕,那么每個(gè)應(yīng)用都有自己的網(wǎng)關(guān)模塊,這樣復(fù)用性不好仆嗦,所以可以考慮把網(wǎng)關(guān)模塊提起出來辉阶,單獨(dú)作為一個(gè)應(yīng)用來做服務(wù)路由,如下圖3:
如上圖當(dāng)移動(dòng)設(shè)備發(fā)起請求時(shí)候是具體發(fā)送到網(wǎng)關(guān)應(yīng)用的瘩扼,經(jīng)過鑒權(quán)后請求會(huì)被轉(zhuǎn)發(fā)到具體的后端服務(wù)應(yīng)用上谆甜,對應(yīng)前端移動(dòng)設(shè)備來說他們不在乎也不知道后端服務(wù)器應(yīng)用是一個(gè)還是多個(gè),他們只能感知到網(wǎng)關(guān)應(yīng)用的存在集绰。
Zuul是Netflix開源的一個(gè)網(wǎng)關(guān)組件规辱,在Netflix內(nèi)部系統(tǒng)中Zuul被用來作為內(nèi)部系統(tǒng)的門面,如下圖是Zuul在Netflix內(nèi)部使用的一個(gè)架構(gòu)圖:
如上圖最上層的移動(dòng)設(shè)備或者網(wǎng)站首先通過aws負(fù)載均衡器把請求路由到zuul網(wǎng)關(guān)上栽燕,zuul網(wǎng)關(guān)則負(fù)責(zé)把請求路由到具體的后端service上罕袋。
Zuul開源地址 https://github.com/Netflix/zuul
三改淑、Zuul 1.0 服務(wù)架構(gòu)與源碼剖析
3.1 Zuul 1.0 服務(wù)架構(gòu)概述
Zuul網(wǎng)關(guān)的核心是一系列的過濾器,這些過濾器可以對請求或者響應(yīng)結(jié)果做一系列過濾浴讯,Zuul 提供了一個(gè)框架可以支持動(dòng)態(tài)加載朵夏,編譯,運(yùn)行這些過濾器榆纽,這些過濾器是使用責(zé)任鏈方式順序?qū)φ埱蠡蛘唔憫?yīng)結(jié)果進(jìn)行處理的仰猖,這些過濾器直接不會(huì)直接進(jìn)行通信奈籽,但是通過責(zé)任鏈傳遞的RequestContext參數(shù)可以共享一些東西饥侵。
雖然Zuul 支持任何可以在jvm上跑的語言,但是目前zuul的過濾器只能使用Groovy腳本來編寫唠摹。編寫好的過濾器腳本一般放在zuul服務(wù)器的固定目錄爆捞,zuul服務(wù)器會(huì)開啟一個(gè)線程定時(shí)去輪詢被修改或者新增的過濾器奉瘤,然后動(dòng)態(tài)進(jìn)行編譯勾拉,加載到內(nèi)存,然后等后續(xù)有請求進(jìn)來盗温,新增或者修改后的過濾器就會(huì)生效了藕赞。
在zuul中過濾器分為四種:
PRE Filters(前置過濾器) :當(dāng)請求會(huì)路由轉(zhuǎn)發(fā)到具體后端服務(wù)器前執(zhí)行的過濾器,比如鑒權(quán)過濾器卖局,日志過濾器斧蜕,還有路由選擇過濾器
ROUTING Filters (路由過濾器):該過濾器作用是把請求具體轉(zhuǎn)發(fā)到后端服務(wù)器上,一般是通過Apache HttpClient 或者 Netflix Ribbon把請求發(fā)送到具體的后端服務(wù)器上
POST Filters(后置過濾器):當(dāng)把請求路由到具體后端服務(wù)器后執(zhí)行的過濾器砚偶;場景有添加標(biāo)準(zhǔn)http 響應(yīng)頭批销,收集一些統(tǒng)計(jì)數(shù)據(jù)(比如請求耗時(shí)等),寫入請求結(jié)果到請求方等染坯。
ERROR Filters(錯(cuò)誤過濾器):當(dāng)上面任何一個(gè)類型過濾器執(zhí)行出錯(cuò)時(shí)候執(zhí)行該過濾器
如下圖為zuul1.0的工作原理:
如上圖均芽,當(dāng)zuul接受到請求后,首先會(huì)由前置過濾器進(jìn)行處理单鹿,然后在由路由過濾器具體把請求轉(zhuǎn)發(fā)到后端應(yīng)用掀宋,然后在執(zhí)行后置過濾器把執(zhí)行結(jié)果寫會(huì)到請求方,當(dāng)上面任何一個(gè)類型過濾器執(zhí)行出錯(cuò)時(shí)候執(zhí)行該過濾器仲锄。
3.2 Zuul 1.0 源碼分析
本節(jié)作者使用zuul的版本:
<dependency>
<groupId>com.netflix.zuul</groupId>
<artifactId>zuul-core</artifactId>
<version>1.0.28</version>
</dependency>
3.2.1 核心處理流程-ZuulServlet類
...
3.2.2 動(dòng)態(tài)裝載過濾器-FilterFileManager類
....
總結(jié):zuul1.0時(shí)候當(dāng)zuul接受到一個(gè)請求后會(huì)同步執(zhí)行前置過濾器劲妙、路由過濾器、后置過濾器儒喊,等執(zhí)行完畢后在同步把結(jié)果返回為調(diào)用方镣奋,調(diào)用方在整個(gè)過程中是阻塞的。其實(shí)SpringBoot集成的zuul就是自己實(shí)現(xiàn)了個(gè)前置過濾器做選擇路由怀愧,然后自己實(shí)現(xiàn)了個(gè)路由過濾器根據(jù)前置過濾器選擇的路由具體做路由轉(zhuǎn)發(fā)侨颈。
四富雅、Zuul 2.0 服務(wù)架構(gòu)新特性
4.1 新特性
Netty作為高性能異步網(wǎng)絡(luò)通訊框架,在dubbo肛搬,rocketmq,sofa等知名開源框架中都有使用没佑,如下圖zuul2.0使用netty server作為網(wǎng)關(guān)監(jiān)聽服務(wù)器監(jiān)聽客戶端發(fā)來的請求,然后把請求轉(zhuǎn)發(fā)到前置過濾器(inbound filters)進(jìn)行處理温赔,處理完畢后在把請求使用netty client代理到具體的后端服務(wù)器進(jìn)行處理蛤奢,處理完畢后在把結(jié)果交給后者過濾器(outbound filters)進(jìn)行處理,然后把處理結(jié)果通過nettyServer寫回客戶端陶贼。
...
總: 在zuul1.0時(shí)候客戶端發(fā)起的請求后需要同步等待zuul網(wǎng)關(guān)返回啤贩,zuul網(wǎng)關(guān)這邊對每個(gè)請求會(huì)分派一個(gè)線程來進(jìn)行處理,這會(huì)導(dǎo)致并發(fā)請求數(shù)量有限拜秧。而zuul2.0使用netty作為異步通訊痹屹,可以大大加大并發(fā)請求量。