SpringCloud Gateway 詳解

SpringCloud Gateway 性能

硬件環(huán)境:三臺機器,分別運行服務端程序披摄,網(wǎng)關(guān)程序和壓測程序
CPU: 4vCPU Intel(R) Xeon(R) CPU E5-2680 v4 @ 2.40GHz
內(nèi)存:8GB

測試結(jié)果:
RPS : 21685.14 請求 / 秒
Average Latency: 4.95ms

專業(yè)數(shù)據(jù)
tps(transaction per second):服務器每秒處理事務數(shù)罐栈,服務器的綜合處理能力的體現(xiàn)蕉堰。吞吐量:網(wǎng)絡每秒能通過的事務台谢。數(shù)據(jù)是通過網(wǎng)絡傳輸张遭,當網(wǎng)絡無瓶頸,tps=吞吐量蠕嫁;當遇到網(wǎng)絡瓶頸锨天,tps!=吞吐量。
rps(request per second):發(fā)起方(用戶)每秒請求率
qps(query per second):每秒查詢率剃毒,服務器的查詢率病袄。如輸入用戶名密碼登錄,首先可能先查詢用戶名是否存在赘阀,再查詢用戶名密碼是否正確益缠,在企業(yè)中,如果沒有嚴格區(qū)分基公,是把1個事務幅慌,當做只查詢1次,但實際請求可能1事務:n查詢轰豆。
hps(hit per second):每秒用戶點擊率胰伍,頁面點擊。在jmeter中執(zhí)行接口酸休,無hps概念骂租,在LoadRunner中有該指標。

SpringCloud Gateway 簡介

SpringCloud Gateway 是 Spring Cloud 的一個全新項目斑司,該項目是基于 Spring 5.0菩咨,Spring Boot 2.0 和 Project Reactor 等技術(shù)開發(fā)的網(wǎng)關(guān),它旨在為微服務架構(gòu)提供一種簡單有效的統(tǒng)一的 API 路由管理方式陡厘。

SpringCloud Gateway 作為 Spring Cloud 生態(tài)系統(tǒng)中的網(wǎng)關(guān)抽米,目標是替代 Zuul,在Spring Cloud 2.0以上版本中糙置,沒有對新版本的Zuul 2.0以上最新高性能版本進行集成云茸,仍然還是使用的Zuul 2.0之前的非Reactor模式的老版本。而為了提升網(wǎng)關(guān)的性能谤饭,SpringCloud Gateway是基于WebFlux框架實現(xiàn)的标捺,而WebFlux框架底層則使用了高性能的Reactor模式通信框架Netty。

Spring Cloud Gateway 的目標揉抵,不僅提供統(tǒng)一的路由方式亡容,并且基于 Filter 鏈的方式提供了網(wǎng)關(guān)基本的功能,例如:安全冤今,監(jiān)控/指標闺兢,和限流。

提前聲明:Spring Cloud Gateway 底層使用了高性能的通信框架Netty戏罢。

SpringCloud Gateway 特征

SpringCloud官方屋谭,對SpringCloud Gateway 特征介紹如下:

  • 基于 Spring Framework 5脚囊,Project Reactor 和 Spring Boot 2.0
  • 集成 Hystrix 斷路器
  • 集成 Spring Cloud DiscoveryClient
  • Predicates 和 Filters 作用于特定路由,易于編寫的 Predicates 和 Filters
  • 具備一些網(wǎng)關(guān)的高級功能:動態(tài)路由桐磁、限流悔耘、路徑重寫

從以上的特征來說,和Zuul的特征差別不大我擂。SpringCloud Gateway和Zuul主要的區(qū)別衬以,還是在底層的通信框架上。

簡單說明一下上文中的三個術(shù)語:
(1)Filter(過濾器):
和Zuul的過濾器在概念上類似校摩,可以使用它攔截和修改請求泄鹏,并且對上游的響應,進行二次處理秧耗。過濾器為org.springframework.cloud.gateway.filter.GatewayFilter類的實例备籽。
(2)Route(路由):
網(wǎng)關(guān)配置的基本組成模塊,和Zuul的路由配置模塊類似分井。一個Route模塊由一個 ID车猬,一個目標 URI,一組斷言和一組過濾器定義尺锚。如果斷言為真珠闰,則路由匹配,目標URI會被訪問瘫辩。
(3)Predicate(斷言):
這是一個 Java 8 的 Predicate伏嗜,可以使用它來匹配來自 HTTP 請求的任何內(nèi)容,例如 headers 或參數(shù)伐厌。斷言的輸入類型是一個 ServerWebExchange承绸。

SpringCloud Gateway和架構(gòu)

Spring在2017年下半年迎來了Webflux,Webflux的出現(xiàn)填補了Spring在響應式編程上的空白挣轨,Webflux的響應式編程不僅僅是編程風格的改變军熏,而且對于一系列的著名框架,都提供了響應式訪問的開發(fā)包卷扮,比如Netty荡澎、Redis等等。
SpringCloud Gateway 使用的Webflux中的reactor-netty響應式編程組件晤锹,底層使用了Netty通訊框架摩幔。


image.png

SpringCloud Zuul的IO模型

Springcloud中所集成的Zuul版本,采用的是Tomcat容器鞭铆,使用的是傳統(tǒng)的Servlet IO處理模型或衡。

大家知道,servlet由servlet container進行生命周期管理。container啟動時構(gòu)造servlet對象并調(diào)用servlet init()進行初始化薇宠;container關(guān)閉時調(diào)用servlet destory()銷毀servlet;container運行時接受請求艰额,并為每個請求分配一個線程(一般從線程池中獲取空閑線程)然后調(diào)用service()澄港。

弊端:servlet是一個簡單的網(wǎng)絡IO模型,當請求進入servlet container時柄沮,servlet container就會為其綁定一個線程回梧,在并發(fā)不高的場景下這種模型是適用的,但是一旦并發(fā)上升祖搓,線程數(shù)量就會上漲狱意,而線程資源代價是昂貴的(上線文切換,內(nèi)存消耗大)嚴重影響請求的處理時間拯欧。在一些簡單的業(yè)務場景下详囤,不希望為每個request分配一個線程,只需要1個或幾個線程就能應對極大并發(fā)的請求镐作,這種業(yè)務場景下servlet模型沒有優(yōu)勢藏姐。


image.png

所以Springcloud Zuul 是基于servlet之上的一個阻塞式處理模型,即spring實現(xiàn)了處理所有request請求的一個servlet(DispatcherServlet)该贾,并由該servlet阻塞式處理處理羔杨。所以Springcloud Zuul無法擺脫servlet模型的弊端。雖然Zuul 2.0開始杨蛋,使用了Netty兜材,并且已經(jīng)有了大規(guī)模Zuul 2.0集群部署的成熟案例,但是逞力,Springcloud官方已經(jīng)沒有集成改版本的計劃了曙寡。

Webflux模型

Webflux模式替換了舊的Servlet線程模型。用少量的線程處理request和response io操作寇荧,這些線程稱為Loop線程卵皂,而業(yè)務交給響應式編程框架處理,響應式編程是非常靈活的砚亭,用戶可以將業(yè)務中阻塞的操作提交到響應式框架的work線程中執(zhí)行灯变,而不阻塞的操作依然可以在Loop線程中進行處理,大大提高了Loop線程的利用率捅膘。官方結(jié)構(gòu)圖:


image.png

Webflux雖然可以兼容多個底層的通信框架添祸,但是一般情況下,底層使用的還是Netty寻仗,畢竟刃泌,Netty是目前業(yè)界認可的最高性能的通信框架。而Webflux的Loop線程,正好就是著名的Reactor 模式IO處理模型的Reactor線程耙替,如果使用的是高性能的通信框架Netty亚侠,這就是Netty的EventLoop線程。

Spring Cloud Gateway的處理流程

客戶端向 Spring Cloud Gateway 發(fā)出請求俗扇。然后在 Gateway Handler Mapping 中找到與請求相匹配的路由硝烂,將其發(fā)送到 Gateway Web Handler。Handler 再通過指定的過濾器鏈來將請求發(fā)送到我們實際的服務執(zhí)行業(yè)務邏輯铜幽,然后返回滞谢。過濾器之間用虛線分開是因為過濾器可能會在發(fā)送代理請求之前(“pre”)或之后(“post”)執(zhí)行業(yè)務邏輯。


image.png

Spring Cloud Gateway路由配置方式

基礎(chǔ)URI一種路由配置方式

如果請求的目標地址除抛,是單個的URI資源路徑狮杨,配置文件示例如下:

server.port=8080
spring.application.name=api-gateway
#id: url-proxy-1
spring.cloud.gateway.routes.uri=http://www.reibang.com/
#path=/test
spring.cloud.gateway.routes.predicates=

各字段含義如下:
id:我們自定義的路由 ID,保持唯一
uri:目標服務地址
predicates:路由條件到忽,Predicate 接受一個輸入?yún)?shù)橄教,返回一個布爾值結(jié)果。該接口包含多種默認方法來將 Predicate 組合成其他復雜的邏輯(比如:與喘漏,或颤陶,非)。
上面這段配置的意思是陷遮,配置了一個 id 為 url-proxy-1的URI代理規(guī)則滓走,路由的規(guī)則為:當訪問地址http://localhost:8080/csdn/1.jsp時,會路由到上游地址https://blog.csdn.net/1.jsp帽馋。

基于代碼的路由配置方式

轉(zhuǎn)發(fā)功能同樣可以通過代碼來實現(xiàn)搅方,我們可以在啟動類 GateWayApplication 中添加方法 customRouteLocator() 來定制轉(zhuǎn)發(fā)規(guī)則。

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
 
@SpringBootApplication
public class GatewayApplication {
 
    public static void main(String[] args) {
        SpringApplication.run(GatewayApplication.class, args);
    }
 
    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
        return builder.routes().route("path_route", r -> r.path("/test").uri("http://www.reibang.com/")).build();
    }
}

我們在properties配置文件中注銷掉相關(guān)路由的配置绽族,重啟服務姨涡,訪問鏈接:http://localhost:8080/ test, 可以看到和上面一樣的頁面吧慢,證明我們測試成功涛漂。

和注冊中心相結(jié)合的路由配置方式

server.port=8084
spring.cloud.gateway.routes.uri=lb://seckill-provider
spring.cloud.gateway.routes.predicates=
spring.cloud.gateway.routes.uri=lb://message-provider
spring.cloud.gateway.routes.predicates=
application.name=cloud-gateway
eureka.instance.prefer-ip-address=true
eureka.client.service-url.defaultZone=http://localhost:8888/eureka/

注冊中心相結(jié)合的路由配置方式,與單個URI的路由配置检诗,區(qū)別其實很小匈仗,僅僅在于URI的schema協(xié)議不同。單個URI的地址的schema協(xié)議逢慌,一般為http或者https協(xié)議悠轩。

SpringCloud Gateway 匹配規(guī)則

Spring Cloud Gateway 的功能很強大,我們僅僅通過 Predicates 的設計就可以看出來攻泼,前面我們只是使用了 predicates 進行了簡單的條件匹配火架,其實 Spring Cloud Gataway 幫我們內(nèi)置了很多 Predicates 功能鉴象。

Spring Cloud Gateway 是通過 Spring WebFlux 的 HandlerMapping 做為底層支持來匹配到轉(zhuǎn)發(fā)路由,Spring Cloud Gateway 內(nèi)置了很多 Predicates 工廠何鸡,這些 Predicates 工廠通過不同的 HTTP 請求參數(shù)來匹配纺弊,多個 Predicates 工廠可以組合使用。

Predicate 斷言條件介紹

Predicate 來源于 Java 8骡男,是 Java 8 中引入的一個函數(shù)淆游,Predicate 接受一個輸入?yún)?shù),返回一個布爾值結(jié)果洞翩。該接口包含多種默認方法來將 Predicate 組合成其他復雜的邏輯(比如:與稽犁,或焰望,非)骚亿。可以用于接口請求參數(shù)校驗熊赖、判斷新老數(shù)據(jù)是否有變化需要進行更新操作来屠。

在 Spring Cloud Gateway 中 Spring 利用 Predicate 的特性實現(xiàn)了各種路由匹配規(guī)則,有通過 Header震鹉、請求參數(shù)等不同的條件來進行作為條件匹配到對應的路由俱笛。網(wǎng)上有一張圖總結(jié)了 Spring Cloud 內(nèi)置的幾種 Predicate 的實現(xiàn)。

image.png

說白了 Predicate 就是為了實現(xiàn)一組匹配規(guī)則传趾,方便讓請求過來找到對應的 Route 進行處理迎膜,接下來我們接下 Spring Cloud GateWay 內(nèi)置幾種 Predicate 的使用。

通過請求參數(shù)匹配

Query Route Predicate 支持傳入兩個參數(shù)浆兰,一個是屬性名一個為屬性值磕仅,屬性值可以是正則表達式。

server.port=8080
spring.application.name=api-gateway
#id: gateway-service
spring.cloud.gateway.routes.uri=https://www.baidu.com
spring.cloud.gateway.routes.order=0
#query=smile
spring.cloud.gateway.routes.predicates=

這樣配置簸呈,只要請求中包含 smile 屬性的參數(shù)即可匹配路由榕订。
使用 curl 測試,命令行輸入:
curl localhost:8080?smile=x&id=2
經(jīng)過測試發(fā)現(xiàn)只要請求匯總帶有 smile 參數(shù)即會匹配路由蜕便,不帶 smile 參數(shù)則不會匹配劫恒。

還可以將 Query 的值以鍵值對的方式進行配置,這樣在請求過來時會對屬性值和正則進行匹配轿腺,匹配上才會走路由两嘴。

server.port=8080
spring.application.name=api-gateway
#id: gateway-service
spring.application.cloud.gateway.routes.uri=https://www.baidu.com
spring.application.cloud.gateway.routes.order=0
#query = keep, pu
spring.application.cloud.gateway.routes.predicates=

這樣只要當請求中包含 keep 屬性并且參數(shù)值是以 pu 開頭的長度為三位的字符串才會進行匹配和路由。
使用 curl 測試族壳,命令行輸入:
curl localhost:8080?keep=pub
測試可以返回頁面代碼溶诞,將 keep 的屬性值改為 pubx 再次訪問就會報 404,證明路由需要匹配正則表達式才會進行路由。

轉(zhuǎn)載自:
SpringCloud gateway (史上最全
Spring Cloud Gateway(六):路由謂詞工廠 RoutePredicateFactory

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末决侈,一起剝皮案震驚了整個濱河市螺垢,隨后出現(xiàn)的幾起案子喧务,更是在濱河造成了極大的恐慌,老刑警劉巖枉圃,帶你破解...
    沈念sama閱讀 217,509評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件功茴,死亡現(xiàn)場離奇詭異,居然都是意外死亡孽亲,警方通過查閱死者的電腦和手機坎穿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評論 3 394
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來返劲,“玉大人玲昧,你說我怎么就攤上這事±郝蹋” “怎么了孵延?”我有些...
    開封第一講書人閱讀 163,875評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長亲配。 經(jīng)常有香客問我尘应,道長,這世上最難降的妖魔是什么吼虎? 我笑而不...
    開封第一講書人閱讀 58,441評論 1 293
  • 正文 為了忘掉前任犬钢,我火速辦了婚禮,結(jié)果婚禮上思灰,老公的妹妹穿的比我還像新娘玷犹。我一直安慰自己,他們只是感情好洒疚,可當我...
    茶點故事閱讀 67,488評論 6 392
  • 文/花漫 我一把揭開白布歹颓。 她就那樣靜靜地躺著,像睡著了一般拳亿。 火紅的嫁衣襯著肌膚如雪晴股。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,365評論 1 302
  • 那天肺魁,我揣著相機與錄音电湘,去河邊找鬼。 笑死鹅经,一個胖子當著我的面吹牛寂呛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播瘾晃,決...
    沈念sama閱讀 40,190評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼贷痪,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了蹦误?” 一聲冷哼從身側(cè)響起劫拢,我...
    開封第一講書人閱讀 39,062評論 0 276
  • 序言:老撾萬榮一對情侶失蹤肉津,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后舱沧,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體妹沙,經(jīng)...
    沈念sama閱讀 45,500評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,706評論 3 335
  • 正文 我和宋清朗相戀三年熟吏,在試婚紗的時候發(fā)現(xiàn)自己被綠了距糖。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,834評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡牵寺,死狀恐怖悍引,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情帽氓,我是刑警寧澤台盯,帶...
    沈念sama閱讀 35,559評論 5 345
  • 正文 年R本政府宣布趁窃,位于F島的核電站玲躯,受9級特大地震影響韭畸,放射性物質(zhì)發(fā)生泄漏师倔。R本人自食惡果不足惜疾宏,卻給世界環(huán)境...
    茶點故事閱讀 41,167評論 3 328
  • 文/蒙蒙 一碟案、第九天 我趴在偏房一處隱蔽的房頂上張望物臂。 院中可真熱鬧壮啊,春花似錦嫉鲸、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至狸眼,卻和暖如春藤树,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背拓萌。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評論 1 269
  • 我被黑心中介騙來泰國打工岁钓, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人微王。 一個月前我還...
    沈念sama閱讀 47,958評論 2 370
  • 正文 我出身青樓屡限,卻偏偏與公主長得像,于是被迫代替她去往敵國和親炕倘。 傳聞我的和親對象是個殘疾皇子钧大,可洞房花燭夜當晚...
    茶點故事閱讀 44,779評論 2 354

推薦閱讀更多精彩內(nèi)容