5.1 網(wǎng)關(guān)簡介
大家都都知道在微服務(wù)架構(gòu)中,一個(gè)系統(tǒng)會(huì)被拆分為很多個(gè)微服務(wù)。那么作為客戶端要如何去調(diào)用
這么多的微服務(wù)呢?如果沒有網(wǎng)關(guān)的存在,我們只能在客戶端記錄每個(gè)微服務(wù)的地址,然后分別去調(diào)用。
?這樣的架構(gòu),會(huì)存在著諸多的問題:
- 客戶端多次請求不同的微服務(wù),增加客戶端代碼或配置編寫的復(fù)雜性
- 認(rèn)證復(fù)雜,每個(gè)服務(wù)都需要獨(dú)立認(rèn)證。
- 存在跨域請求,在一定場景下處理相對復(fù)雜。
上面的這些問題可以借助
API
網(wǎng)關(guān)
來解決。
所謂的
API
網(wǎng)關(guān),就是指系統(tǒng)的
統(tǒng)一入口
,它封裝了應(yīng)用程序的內(nèi)部結(jié)構(gòu),為客戶端提供統(tǒng)一服
務(wù),一些與業(yè)務(wù)本身功能無關(guān)的公共邏輯可以在這里實(shí)現(xiàn),諸如認(rèn)證、鑒權(quán)、監(jiān)控、路由轉(zhuǎn)發(fā)等等。
添加上
API
網(wǎng)關(guān)之后,系統(tǒng)的架構(gòu)圖變成了如下所示:
我們也可以觀察下,我們現(xiàn)在的整體架構(gòu)圖:
在業(yè)界比較流行的網(wǎng)關(guān),有下面這些:
使用
nginx
的反向代理和負(fù)載均衡可實(shí)現(xiàn)對
api
服務(wù)器的負(fù)載均衡及高可用
lua
是一種腳本語言
,
可以來編寫一些簡單的邏輯
, nginx
支持
lua
腳本
基于
Nginx+Lua
開發(fā),性能高,穩(wěn)定,有多個(gè)可用的插件
(
限流、鑒權(quán)等等
)
可以開箱即用。 問題:
只支持
Http
協(xié)議;二次開發(fā),自由擴(kuò)展困難;提供管理
API
,缺乏更易用的管控、配置方式。
-
Zuul Netflflix開源的網(wǎng)關(guān),功能豐富,使用JAVA開發(fā),易于二次開發(fā) 問題:缺乏管控,無法動(dòng)態(tài)配 置;依賴組件較多;處理Http請求依賴的是Web容器,性能不如Nginx
- Spring Cloud Gateway
Spring
公司為了替換
Zuul
而開發(fā)的網(wǎng)關(guān)服務(wù),將在下面具體介紹。
注意:SpringCloud alibaba技術(shù)棧中并沒有提供自己的網(wǎng)關(guān),我們可以采用Spring Cloud Gateway 來做網(wǎng)關(guān)
5.2 Gateway簡介
Spring Cloud Gateway
是
Spring
公司基于
Spring 5.0
,
Spring Boot 2.0
和
Project Reactor
等技術(shù)
開發(fā)的網(wǎng)關(guān),它旨在為微服務(wù)架構(gòu)提供一種簡單有效的統(tǒng)一的
API
路由管理方式。它的目標(biāo)是替代 Netflflix Zuul,其不僅提供統(tǒng)一的路由方式,并且基于
Filter
鏈的方式提供了網(wǎng)關(guān)基本的功能,例如:安全,監(jiān)控和限流。
優(yōu)點(diǎn):
-
性能強(qiáng)勁:是第一代網(wǎng)關(guān)Zuul的1.6倍
- 功能強(qiáng)大:內(nèi)置了很多實(shí)用的功能,例如轉(zhuǎn)發(fā)、監(jiān)控、限流等
- 設(shè)計(jì)優(yōu)雅,容易擴(kuò)展
缺點(diǎn):
-
其實(shí)現(xiàn)依賴Netty與WebFlux,不是傳統(tǒng)的Servlet編程模型,學(xué)習(xí)成本高
-
不能將其部署在Tomcat、Jetty等Servlet容器里,只能打成jar包執(zhí)行
-
需要Spring Boot 2.0及以上的版本,才支持
5.3 Gateway快速入門
要求
:
通過瀏覽器訪問
api
網(wǎng)關(guān)
,
然后通過網(wǎng)關(guān)將請求轉(zhuǎn)發(fā)到商品微服務(wù)
5.3.1 基礎(chǔ)版
第
1
步:創(chuàng)建一個(gè)
api
-
gateway
的模塊
,
導(dǎo)入相關(guān)依賴
第
2
步
:
創(chuàng)建主類
第
3
步
:
添加配置文件
第
4
步
:
啟動(dòng)項(xiàng)目
,
并通過網(wǎng)關(guān)去訪問微服務(wù)
5.3.2 增強(qiáng)版
現(xiàn)在在配置文件中寫死了轉(zhuǎn)發(fā)路徑的地址
,
前面我們已經(jīng)分析過地址寫死帶來的問題
,
接下來我們從
注冊中心獲取此地址。
第
1
步:加入
nacos
依賴
第2步:在主類上添加注解
第
3
步:修改配置文件
第
4
步
:
測試
5.3.3 簡寫版
第
1
步
:
去掉關(guān)于路由的配置
第
2
步
:
啟動(dòng)項(xiàng)目,并通過網(wǎng)關(guān)去訪問微服務(wù)
這時(shí)候,就發(fā)現(xiàn)只要按照
網(wǎng)關(guān)地址
/
微服務(wù)
/
接口
的格式去訪問,就可以得到成功響應(yīng)。
5.4 Gateway核心架構(gòu)
5.4.1 基本概念
路由
(Route)
是
gateway
中最基本的組件之一,表示一個(gè)具體的路由信息載體。主要定義了下面的幾個(gè)信息:
-
id,路由標(biāo)識符,區(qū)別于其他 Route。
-
uri,路由指向的目的地 uri,即客戶端請求最終被轉(zhuǎn)發(fā)到的微服務(wù)。
-
order,用于多個(gè) Route 之間的排序,數(shù)值越小排序越靠前,匹配優(yōu)先級越高。
-
predicate,斷言的作用是進(jìn)行條件判斷,只有斷言都返回真,才會(huì)真正的執(zhí)行路由。
-
fifilter,過濾器用于修改請求和響應(yīng)信息。
5.4.2 執(zhí)行流程

執(zhí)行流程大體如下:
-
Gateway Client向Gateway Server發(fā)送請求
-
?請求首先會(huì)被HttpWebHandlerAdapter進(jìn)行提取組裝成網(wǎng)關(guān)上下文
-
然后網(wǎng)關(guān)的上下文會(huì)傳遞到DispatcherHandler,它負(fù)責(zé)將請求分發(fā)給 RoutePredicateHandlerMapping
-
RoutePredicateHandlerMapping負(fù)責(zé)路由查找,并根據(jù)路由斷言判斷路由是否可用
-
如果過斷言成功,由FilteringWebHandler創(chuàng)建過濾器鏈并調(diào)用
-
請求會(huì)一次經(jīng)過PreFilter--微服務(wù)--PostFilter的方法,最終返回響應(yīng)
5.5 斷言
Predicate(
斷言
,
謂詞
)
用于進(jìn)行條件判斷,只有斷言都返回真,才會(huì)真正的執(zhí)行路由。
斷言就是說
:
在
什么條件下
才能進(jìn)行路由轉(zhuǎn)發(fā)
5.5.1 內(nèi)置路由斷言工廠
SpringCloud Gateway
包括許多內(nèi)置的斷言工廠,所有這些斷言都與
HTTP
請求的不同屬性匹配。具體如下:
此類型的斷言根據(jù)時(shí)間做判斷,主要有三個(gè):
-
AfterRoutePredicateFactory: 接收一個(gè)日期參數(shù),判斷請求日期是否晚于指定日期
-
BeforeRoutePredicateFactory: 接收一個(gè)日期參數(shù),判斷請求日期是否早于指定日期
-
BetweenRoutePredicateFactory: 接收兩個(gè)日期參數(shù),判斷請求日期是否在指定時(shí)間段內(nèi)
-After=2019-12-31T23:59:59.789+08:00[Asia/Shanghai]
-
基于遠(yuǎn)程地址的斷言工廠 RemoteAddrRoutePredicateFactory:接收一個(gè)IP地址段,判斷請求主機(jī)地址是否在地址段中
-RemoteAddr=192.168.1.1/24
CookieRoutePredicateFactory
:接收兩個(gè)參數(shù),
cookie
名字和一個(gè)正則表達(dá)式。 判斷請求
cookie
是否具有給定名稱且值與正則表達(dá)式匹配。
-Cookie=chocolate, ch.
HeaderRoutePredicateFactory
:接收兩個(gè)參數(shù),標(biāo)題名稱和正則表達(dá)式。 判斷請求
Header
是否
具有給定名稱且值與正則表達(dá)式匹配。
-Header=X-Request-Id, \d+
HostRoutePredicateFactory
:接收一個(gè)參數(shù),主機(jī)名模式。判斷請求的
Host
是否滿足匹配規(guī)則。
-Host=**.testhost.org
MethodRoutePredicateFactory
:接收一個(gè)參數(shù),判斷請求類型是否跟指定的類型匹配。
-Method=GET
PathRoutePredicateFactory
:接收一個(gè)參數(shù),判斷請求的
URI
部分是否滿足路徑規(guī)則。
-Path=/foo/{segment}
QueryRoutePredicateFactory
:接收兩個(gè)參數(shù),請求
param
和正則表達(dá)式, 判斷請求參數(shù)是否具
有給定名稱且值與正則表達(dá)式匹配。
-Query=baz, ba.
WeightRoutePredicateFactory
:接收一個(gè)
[
組名
,
權(quán)重
],
然后對于同一個(gè)組內(nèi)的路由按照權(quán)重轉(zhuǎn)發(fā)
routes:
-id: weight_route1 uri: host1 predicates:
-Path=/product/**
-Weight=group3, 1
-id: weight_route2 uri: host2 predicates:
-Path=/product/**
-Weight= group3, 9
內(nèi)置路由斷言工廠的使用
接下來我們驗(yàn)證幾個(gè)內(nèi)置斷言的使用
:
5.5.2 自定義路由斷言工廠
我們來設(shè)定一個(gè)場景
:
假設(shè)我們的應(yīng)用僅僅讓
age
在
(min,max)
之間的人來訪問。
第
1
步:在配置文件中
,
添加一個(gè)
Age
的斷言配置
第
2
步:自定義一個(gè)斷言工廠
,
實(shí)現(xiàn)斷言方法
第3
步:啟動(dòng)測試
5.6 過濾器
三個(gè)知識點(diǎn):
-
作用: 過濾器就是在請求的傳遞過程中,對請求和響應(yīng)做一些手腳
-
生命周期: Pre Post
-
分類: 局部過濾器(作用在某一個(gè)路由上) 全局過濾器(作用全部路由上)
在Gateway中, Filter的生命周期只有兩個(gè):“pre” 和 “post”。
-
PRE: 這種過濾器在請求被路由之前調(diào)用。我們可利用這種過濾器實(shí)現(xiàn)身份驗(yàn)證、在集群中選擇請求的微服務(wù)、記錄調(diào)試信息等。
-
POST:這種過濾器在路由到微服務(wù)以后執(zhí)行。這種過濾器可用來為響應(yīng)添加標(biāo)準(zhǔn)的HTTP Header、收集統(tǒng)計(jì)信息和指標(biāo)、將響應(yīng)從微服務(wù)發(fā)送給客戶端等。

Gateway 的Filter從作用范圍可分為兩種: GatewayFilter與GlobalFilter。
-
GatewayFilter:應(yīng)用到單個(gè)路由或者一個(gè)分組的路由上。
-
GlobalFilter:應(yīng)用到所有的路由上。
5.6.1 局部過濾器
局部過濾器是針對單個(gè)路由的過濾器。
5.6.1.1
內(nèi)置局部過濾器
在
SpringCloud Gateway
中內(nèi)置了很多不同類型的網(wǎng)關(guān)路由過濾器。具體如下:
內(nèi)置局部過濾器的使用
5.6.1.2
自定義局部過濾器
第
1
步:在配置文件中
,
添加一個(gè)
Log
的過濾器配置
第
2
步:自定義一個(gè)過濾器工廠
,
實(shí)現(xiàn)方法
第
3
步:啟動(dòng)測試
5.6.2 全局過濾器
全局過濾器作用于所有路由
,
無需配置。通過全局過濾器可以實(shí)現(xiàn)對權(quán)限的統(tǒng)一校驗(yàn),安全性驗(yàn)證等功能。
5.6.2.1
內(nèi)置全局過濾器
SpringCloud Gateway
內(nèi)部也是通過一系列的內(nèi)置全局過濾器對整個(gè)路由轉(zhuǎn)發(fā)進(jìn)行處理如下:
5.6.2.2
自定義全局過濾器
內(nèi)置的過濾器已經(jīng)可以完成大部分的功能,但是對于企業(yè)開發(fā)的一些業(yè)務(wù)功能處理,還是需要我們
自己編寫過濾器來實(shí)現(xiàn)的,那么我們一起通過代碼的形式自定義一個(gè)過濾器,去完成統(tǒng)一的權(quán)限校驗(yàn)。
開發(fā)中的鑒權(quán)邏輯:
- 當(dāng)客戶端第一次請求服務(wù)時(shí),服務(wù)端對用戶進(jìn)行信息認(rèn)證(登錄)
-
認(rèn)證通過,將用戶信息進(jìn)行加密形成token,返回給客戶端,作為登錄憑證
-
以后每次請求,客戶端都攜帶認(rèn)證的token
-
服務(wù)端對token進(jìn)行解密,判斷是否有效。
文章來源:http://www.zghlxwxcb.cn/news/detail-572541.html
如上圖,對于驗(yàn)證用戶是否已經(jīng)登錄鑒權(quán)的過程可以在網(wǎng)關(guān)統(tǒng)一檢驗(yàn)。
檢驗(yàn)的標(biāo)準(zhǔn)就是請求中是否攜帶
token
憑證以及
token
的正確性。
下面的我們自定義一個(gè)
GlobalFilter
,去校驗(yàn)所有請求的請求參數(shù)中是否包含
“token”
,如何不包含請求參數(shù)“token”
則不轉(zhuǎn)發(fā)路由,否則執(zhí)行正常的邏輯。
5.7 網(wǎng)關(guān)限流
網(wǎng)關(guān)是所有請求的公共入口,所以可以在網(wǎng)關(guān)進(jìn)行限流,而且限流的方式也很多,我們本次采用前
面學(xué)過的
Sentinel
組件來實(shí)現(xiàn)網(wǎng)關(guān)的限流。
Sentinel
支持對
SpringCloud Gateway
、
Zuul
等主流網(wǎng)關(guān)進(jìn)行限流。
從
1.6.0
版本開始,
Sentinel
提供了
SpringCloud Gateway
的適配模塊,可以提供兩種資源維度的限流:
-
route維度:即在Spring配置文件中配置的路由條目,資源名為對應(yīng)的routeId
-
自定義API維度:用戶可以利用Sentinel提供的API來自定義一些API分組
1
導(dǎo)入依賴
2
編寫配置類
基于
Sentinel
的
Gateway
限流是通過其提供的
Filter
來完成的,使用時(shí)只需注入對應(yīng)的
SentinelGatewayFilter
實(shí)例以及
SentinelGatewayBlockExceptionHandler
實(shí)例即可。
3
測試
在一秒鐘內(nèi)多次訪問
http://localhost:7000/product-serv/product/1
就可以看到限流啟作用了。
?
文章來源地址http://www.zghlxwxcb.cn/news/detail-572541.html
4
自定義
API
分組
自定義
API
分組是一種更細(xì)粒度的限流規(guī)則定義
到了這里,關(guān)于5.微服務(wù)項(xiàng)目實(shí)戰(zhàn)---Gateway--服務(wù)網(wǎng)關(guān),實(shí)現(xiàn)統(tǒng)一認(rèn)證、鑒權(quán)、監(jiān)控、路由轉(zhuǎn)發(fā)等的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!