什么是 Spring Cloud Gateway
Spring Cloud Gateway 作為 Spring Cloud 生態(tài)系統(tǒng)中的網(wǎng)關(guān),目標(biāo)是替代 Netflix Zuul续语,其不僅提供統(tǒng)一的路由方式旗笔,并且還基于 Filter 鏈的方式提供了網(wǎng)關(guān)基本的功能挠羔。目前最新版 Spring Cloud 中引用的還是 Zuul 1.x 版本,而這個(gè)版本是基于過(guò)濾器的性芬,是阻塞 IO慨蓝,不支持長(zhǎng)連接。
Zuul 2.x 版本一直跳票竹伸,2019 年 5 月泥栖,Netflix 終于開源了支持異步調(diào)用模式的 Zuul 2.0 版本,真可謂千呼萬(wàn)喚始出來(lái)。但是 Spring Cloud 已經(jīng)不再集成 Zuul 2.x 了聊倔,那么是時(shí)候了解一下 Spring Cloud Gateway 了晦毙。
Spring Cloud Gateway 是基于 Spring 生態(tài)系統(tǒng)之上構(gòu)建的 API 網(wǎng)關(guān),包括:Spring 5耙蔑,Spring Boot 2 和 Project Reactor见妒。Spring Cloud Gateway 旨在提供一種簡(jiǎn)單而有效的方法來(lái)路由到 API,并為它們提供跨領(lǐng)域的關(guān)注點(diǎn)甸陌,例如:安全性须揣,監(jiān)視/指標(biāo),限流等钱豁。由于 Spring 5.0 支持 Netty耻卡,Http2,而 Spring Boot 2.0 支持 Spring 5.0牲尺,因此 Spring Cloud Gateway 支持 Netty 和 Http2 順理成章卵酪。
什么是服務(wù)網(wǎng)關(guān)
API Gateway(APIGW / API 網(wǎng)關(guān)),顧名思義谤碳,是出現(xiàn)在系統(tǒng)邊界上的一個(gè)面向 API 的溃卡、串行集中式的強(qiáng)管控服務(wù),這里的邊界是企業(yè) IT 系統(tǒng)的邊界蜒简,可以理解為企業(yè)級(jí)應(yīng)用防火墻
瘸羡,主要起到隔離外部訪問(wèn)與內(nèi)部系統(tǒng)的作用
。在微服務(wù)概念的流行之前搓茬,API 網(wǎng)關(guān)就已經(jīng)誕生了犹赖,例如銀行、證券等領(lǐng)域常見的前置機(jī)系統(tǒng)卷仑,它也是解決訪問(wèn)認(rèn)證峻村、報(bào)文轉(zhuǎn)換、訪問(wèn)統(tǒng)計(jì)等問(wèn)題的锡凝。
API 網(wǎng)關(guān)的流行粘昨,源于近幾年來(lái)移動(dòng)應(yīng)用與企業(yè)間互聯(lián)需求的興起。移動(dòng)應(yīng)用私爷、企業(yè)互聯(lián),使得后臺(tái)服務(wù)支持的對(duì)象膊夹,從以前單一的Web應(yīng)用衬浑,擴(kuò)展到多種使用場(chǎng)景,且每種使用場(chǎng)景對(duì)后臺(tái)服務(wù)的要求都不盡相同放刨。這不僅增加了后臺(tái)服務(wù)的響應(yīng)量工秩,還增加了后臺(tái)服務(wù)的復(fù)雜性。隨著微服務(wù)架構(gòu)概念的提出,API網(wǎng)關(guān)成為了微服務(wù)架構(gòu)的一個(gè)標(biāo)配組件
助币。
API 網(wǎng)關(guān)是一個(gè)服務(wù)器浪听,是系統(tǒng)對(duì)外的唯一入口。API 網(wǎng)關(guān)封裝了系統(tǒng)內(nèi)部架構(gòu)眉菱,為每個(gè)客戶端提供定制的 API迹栓。所有的客戶端和消費(fèi)端都通過(guò)統(tǒng)一的網(wǎng)關(guān)接入微服務(wù),在網(wǎng)關(guān)層處理所有非業(yè)務(wù)功能俭缓。API 網(wǎng)關(guān)并不是微服務(wù)場(chǎng)景中必須的組件克伊,如下圖,不管有沒有 API 網(wǎng)關(guān)华坦,后端微服務(wù)都可以通過(guò) API 很好地支持客戶端的訪問(wèn)愿吹。
但對(duì)于服務(wù)數(shù)量眾多、復(fù)雜度比較高惜姐、規(guī)模比較大的業(yè)務(wù)來(lái)說(shuō)犁跪,引入 API 網(wǎng)關(guān)也有一系列的好處:
- 聚合接口使得服務(wù)對(duì)調(diào)用者透明,客戶端與后端的耦合度降低
- 聚合后臺(tái)服務(wù)歹袁,節(jié)省流量坷衍,提高性能,提升用戶體驗(yàn)
- 提供安全宇攻、流控惫叛、過(guò)濾、緩存逞刷、計(jì)費(fèi)嘉涌、監(jiān)控等 API 管理功能
為什么要使用網(wǎng)關(guān)
- 單體應(yīng)用:瀏覽器發(fā)起請(qǐng)求到單體應(yīng)用所在的機(jī)器,應(yīng)用從數(shù)據(jù)庫(kù)查詢數(shù)據(jù)原路返回給瀏覽器夸浅,對(duì)于單體應(yīng)用來(lái)說(shuō)是不需要網(wǎng)關(guān)的仑最。
- 微服務(wù):微服務(wù)的應(yīng)用可能部署在不同機(jī)房,不同地區(qū)帆喇,不同域名下警医。此時(shí)客戶端(瀏覽器/手機(jī)/軟件工具)想要請(qǐng)求對(duì)應(yīng)的服務(wù),都需要知道機(jī)器的具體 IP 或者域名 URL坯钦,當(dāng)微服務(wù)實(shí)例眾多時(shí)预皇,這是非常難以記憶的,對(duì)于客戶端來(lái)說(shuō)也太復(fù)雜難以維護(hù)婉刀。此時(shí)就有了網(wǎng)關(guān)吟温,客戶端相關(guān)的請(qǐng)求直接發(fā)送到網(wǎng)關(guān),由網(wǎng)關(guān)根據(jù)請(qǐng)求標(biāo)識(shí)解析判斷出具體的微服務(wù)地址突颊,再把請(qǐng)求轉(zhuǎn)發(fā)到微服務(wù)實(shí)例鲁豪。這其中的記憶功能就全部交由網(wǎng)關(guān)來(lái)操作了潘悼。
總結(jié)
如果讓客戶端直接與各個(gè)微服務(wù)交互:
- 客戶端會(huì)多次請(qǐng)求不同的微服務(wù),增加了客戶端的復(fù)雜性
- 存在跨域請(qǐng)求爬橡,在一定場(chǎng)景下處理相對(duì)復(fù)雜
- 身份認(rèn)證問(wèn)題治唤,每個(gè)微服務(wù)需要獨(dú)立身份認(rèn)證
- 難以重構(gòu),隨著項(xiàng)目的迭代糙申,可能需要重新劃分微服務(wù)
- 某些微服務(wù)可能使用了防火墻/瀏覽器不友好的協(xié)議宾添,直接訪問(wèn)會(huì)有一定的困難
因此,我們需要網(wǎng)關(guān)介于客戶端與服務(wù)器之間的中間層郭宝,所有外部請(qǐng)求率先經(jīng)過(guò)微服務(wù)網(wǎng)關(guān)辞槐,客戶端只需要與網(wǎng)關(guān)交互,只需要知道網(wǎng)關(guān)地址即可粘室。這樣便簡(jiǎn)化了開發(fā)且有以下優(yōu)點(diǎn):
- 易于監(jiān)控榄檬,可在微服務(wù)網(wǎng)關(guān)收集監(jiān)控?cái)?shù)據(jù)并將其推送到外部系統(tǒng)進(jìn)行分析
- 易于認(rèn)證,可在微服務(wù)網(wǎng)關(guān)上進(jìn)行認(rèn)證衔统,然后再將請(qǐng)求轉(zhuǎn)發(fā)到后端的微服務(wù)鹿榜,從而無(wú)需在每個(gè)微服務(wù)中進(jìn)行認(rèn)證
- 減少了客戶端與各個(gè)微服務(wù)之間的交互次數(shù)
網(wǎng)關(guān)解決了什么問(wèn)題
網(wǎng)關(guān)具有身份認(rèn)證與安全、審查與監(jiān)控锦爵、動(dòng)態(tài)路由舱殿、負(fù)載均衡、緩存险掀、請(qǐng)求分片與管理沪袭、靜態(tài)響應(yīng)處理等功能。當(dāng)然最主要的職責(zé)還是與“外界聯(lián)系”樟氢。
總結(jié)一下冈绊,網(wǎng)關(guān)應(yīng)當(dāng)具備以下功能:
- 性能:API 高可用,負(fù)載均衡埠啃,容錯(cuò)機(jī)制死宣。
- 安全:權(quán)限身份認(rèn)證、脫敏碴开,流量清洗毅该,后端簽名(保證全鏈路可信調(diào)用),黑名單(非法調(diào)用的限制)潦牛。
- 日志:日志記錄眶掌,一旦涉及分布式,全鏈路跟蹤必不可少巴碗。
- 緩存:數(shù)據(jù)緩存朴爬。
- 監(jiān)控:記錄請(qǐng)求響應(yīng)數(shù)據(jù),API 耗時(shí)分析良价,性能監(jiān)控寝殴。
- 限流:流量控制,錯(cuò)峰流控明垢,可以定義多種限流規(guī)則蚣常。
- 灰度:線上灰度部署,可以減小風(fēng)險(xiǎn)痊银。
- 路由:動(dòng)態(tài)路由規(guī)則抵蚊。
常用網(wǎng)關(guān)解決方案
Nginx + Lua
Nginx 是由 IgorSysoev 為俄羅斯訪問(wèn)量第二的 Rambler.ru 站點(diǎn)開發(fā)的,一個(gè)高性能的 HTTP 和反向代理服務(wù)器溯革。Ngnix 一方面可以做反向代理贞绳,另外一方面做可以做靜態(tài)資源服務(wù)器。
Nginx 適合做門戶網(wǎng)關(guān)致稀,是作為整個(gè)全局的網(wǎng)關(guān)冈闭,對(duì)外的處于最外層的那種;而 Gateway 屬于業(yè)務(wù)網(wǎng)關(guān)抖单,主要用來(lái)對(duì)應(yīng)不同的客戶端提供服務(wù)萎攒,用于聚合業(yè)務(wù)。各個(gè)微服務(wù)獨(dú)立部署矛绘,職責(zé)單一耍休,對(duì)外提供服務(wù)的時(shí)候需要有一個(gè)東西把業(yè)務(wù)聚合起來(lái)。
Gateway 可以實(shí)現(xiàn)熔斷货矮、重試等功能羊精,這是 Nginx 不具備的。
Kong
Kong 是 Mashape 提供的一款 API 管理軟件囚玫,它本身是基于 Ngnix + Lua 的喧锦,但比 Nginx 提供了更簡(jiǎn)單的配置方式,數(shù)據(jù)采用了 ApacheCassandra/PostgreSQL 存儲(chǔ)劫灶,并且提供了一些優(yōu)秀的插件裸违,比如驗(yàn)證,日志本昏,調(diào)用頻次限制等供汛。Kong 非常誘人的地方就是提供了大量的插件來(lái)擴(kuò)展應(yīng)用,通過(guò)設(shè)置不同的插件可以為服務(wù)提供各種增強(qiáng)的功能涌穆。
優(yōu)點(diǎn):基于 Nginx 所以在性能和穩(wěn)定性上都沒有問(wèn)題怔昨。Kong 作為一款商業(yè)軟件,在 Nginx 上做了很擴(kuò)展工作宿稀,而且還有很多付費(fèi)的商業(yè)插件趁舀。Kong 本身也有付費(fèi)的企業(yè)版,其中包括技術(shù)支持祝沸、使用培訓(xùn)服務(wù)以及 API 分析插件矮烹。
缺點(diǎn):如果你使用 Spring Cloud越庇,Kong 如何結(jié)合目前已有的服務(wù)治理體系?
Traefik
Traefik 是一個(gè)開源的 GO 語(yǔ)言開發(fā)的為了讓部署微服務(wù)更加便捷而誕生的現(xiàn)代HTTP反向代理奉狈、負(fù)載均衡工具卤唉。 它支持多種后臺(tái) (Docker, Swarm, Kubernetes, Marathon, Mesos, Consul, Etcd, Zookeeper, BoltDB, Rest API, file…) 來(lái)自動(dòng)化、動(dòng)態(tài)的應(yīng)用它的配置文件設(shè)置仁期。Traefik 擁有一個(gè)基于 AngularJS 編寫的簡(jiǎn)單網(wǎng)站界面桑驱,支持 Rest API,配置文件熱更新跛蛋,無(wú)需重啟進(jìn)程熬的。高可用集群模式等。
相對(duì) Spring Cloud 和 Kubernetes 而言赊级,目前比較適合 Kubernetes押框。
Spring Cloud Netflix Zuul
Zuul 是 Netflix 公司開源的一個(gè) API 網(wǎng)關(guān)組件,Spring Cloud 對(duì)其進(jìn)行二次基于 Spring Boot 的注解式封裝做到開箱即用理逊。目前來(lái)說(shuō)强戴,結(jié)合 Sring Cloud 提供的服務(wù)治理體系,可以做到請(qǐng)求轉(zhuǎn)發(fā)挡鞍,根據(jù)配置或者默認(rèn)的路由規(guī)則進(jìn)行路由和 Load Balance骑歹,無(wú)縫集成 Hystrix。
雖然可以通過(guò)自定義 Filter 實(shí)現(xiàn)我們想要的功能墨微,但是由于 Zuul 本身的設(shè)計(jì)是基于
單線程的接收請(qǐng)求和轉(zhuǎn)發(fā)處理
道媚,是阻塞 IO,不支持長(zhǎng)連接翘县。目前來(lái)看 Zuul 就顯得很雞肋最域,隨著 Zuul 2.x 一直跳票(2019 年 5 月發(fā)布了 Zuul 2.0 版本),Spring Cloud 推出自己的 Spring Cloud Gateway锈麸。大意就是:Zuul 已死镀脂,Spring Cloud Gateway 永生(手動(dòng)狗頭)。
Zuul 1.0
Zuul 2.0
Spring Cloud Gateway
本文主角忘伞。
環(huán)境準(zhǔn)備
gateway-demo
聚合工程薄翅。SpringBoot 2.2.4.RELEASE
、Spring Cloud Hoxton.SR1
氓奈。
-
eureka-server
:注冊(cè)中心 -
eureka-server02
:注冊(cè)中心 -
product-service
:商品服務(wù)翘魄,提供了根據(jù)主鍵查詢商品接口http://localhost:7070/product/{id}
-
order-service
:訂單服務(wù),提供了根據(jù)主鍵查詢訂單接口http://localhost:9090/order/{id}
且訂單服務(wù)調(diào)用商品服務(wù)舀奶。
Nginx 實(shí)現(xiàn) API 網(wǎng)關(guān)
點(diǎn)擊鏈接觀看:Nginx 實(shí)現(xiàn) API 網(wǎng)關(guān)視頻(獲取更多請(qǐng)關(guān)注公眾號(hào)「哈嘍沃德先生」)
之前的課程中我們已經(jīng)詳細(xì)的講解過(guò) Nginx 關(guān)于反向代理暑竟、負(fù)載均衡等功能的使用,這里不再贅述育勺。這里主要通過(guò) Nginx 來(lái)實(shí)現(xiàn) API 網(wǎng)關(guān)方便大家更好的學(xué)習(xí)和理解 Spring Cloud Gateway 的使用但荤。
下載
官網(wǎng):http://nginx.org/en/download.html 下載穩(wěn)定版罗岖。為了方便學(xué)習(xí),請(qǐng)下載 Windows 版本腹躁。
安裝
解壓文件后直接運(yùn)行根路徑下的 nginx.exe
文件即可呀闻。
Nginx 默認(rèn)端口為 80,訪問(wèn):http://localhost:80/ 看到下圖說(shuō)明安裝成功潜慎。
配置路由規(guī)則
進(jìn)入 Nginx 的 conf
目錄,打開 nginx.conf
文件蓖康,配置路由規(guī)則:
http {
...
server {
listen 80;
server_name localhost;
...
# 路由到商品服務(wù)
location /api-product {
proxy_pass http://localhost:7070/;
}
# 路由到訂單服務(wù)
location /api-order {
proxy_pass http://localhost:9090/;
}
...
}
...
}
訪問(wèn)
之前我們?nèi)绻L問(wèn)服務(wù)铐炫,必須由客戶端指定具體服務(wù)地址訪問(wèn),現(xiàn)在統(tǒng)一訪問(wèn) Nginx蒜焊,由 Nginx 實(shí)現(xiàn)網(wǎng)關(guān)功能將請(qǐng)求路由至具體的服務(wù)倒信。
訪問(wèn):http://localhost/api-product/product/1 結(jié)果如下:
訪問(wèn):http://localhost/api-order/order/1 結(jié)果如下:
Gateway 實(shí)現(xiàn) API 網(wǎng)關(guān)
點(diǎn)擊鏈接觀看:Gateway 網(wǎng)關(guān)核心概念視頻(獲取更多請(qǐng)關(guān)注公眾號(hào)「哈嘍沃德先生」)
官網(wǎng)文檔:https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/
核心概念
路由(Route):路由是網(wǎng)關(guān)最基礎(chǔ)的部分,路由信息由 ID泳梆、目標(biāo) URI鳖悠、一組斷言和一組過(guò)濾器組成。如果斷言路由為真优妙,則說(shuō)明請(qǐng)求的 URI 和配置匹配乘综。
斷言(Predicate):Java8 中的斷言函數(shù)。Spring Cloud Gateway 中的斷言函數(shù)輸入類型是 Spring 5.0 框架中的 ServerWebExchange套硼。Spring Cloud Gateway 中的斷言函數(shù)允許開發(fā)者去定義匹配來(lái)自于 Http Request 中的任何信息卡辰,比如請(qǐng)求頭和參數(shù)等。
過(guò)濾器(Filter):一個(gè)標(biāo)準(zhǔn)的 Spring Web Filter邪意。Spring Cloud Gateway 中的 Filter 分為兩種類型九妈,分別是 Gateway Filter 和 Global Filter。過(guò)濾器將會(huì)對(duì)請(qǐng)求和響應(yīng)進(jìn)行處理雾鬼。
工作原理
如上圖所示萌朱,客戶端向 Spring Cloud Gateway
發(fā)出請(qǐng)求。再由網(wǎng)關(guān)處理程序 Gateway Handler Mapping
映射確定與請(qǐng)求相匹配的路由策菜,將其發(fā)送到網(wǎng)關(guān) Web 處理程序 Gateway Web Handler
晶疼。該處理程序通過(guò)指定的過(guò)濾器鏈將請(qǐng)求發(fā)送到我們實(shí)際的服務(wù)執(zhí)行業(yè)務(wù)邏輯,然后返回又憨。過(guò)濾器由虛線分隔的原因是冒晰,過(guò)濾器可以在發(fā)送代理請(qǐng)求之前和之后運(yùn)行邏輯。所有 pre
過(guò)濾器邏輯均被執(zhí)行竟块。然后發(fā)出代理請(qǐng)求壶运。發(fā)出代理請(qǐng)求后,將運(yùn)行 post
過(guò)濾器邏輯浪秘。
搭建網(wǎng)關(guān)服務(wù)
點(diǎn)擊鏈接觀看:Gateway 實(shí)現(xiàn) API 網(wǎng)關(guān)視頻(獲取更多請(qǐng)關(guān)注公眾號(hào)「哈嘍沃德先生」)
創(chuàng)建項(xiàng)目
在gateway-demo
聚合工程下創(chuàng)建 gateway-server
項(xiàng)目蒋情。
添加依賴
添加 spring cloud gateway 依賴埠况。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>gateway-server</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- 繼承父依賴 -->
<parent>
<groupId>com.example</groupId>
<artifactId>gateway-demo</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<!-- 項(xiàng)目依賴 -->
<dependencies>
<!-- spring cloud gateway 依賴 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
</dependencies>
</project>
配置文件
application.yml
server:
port: 9000 # 端口
spring:
application:
name: gateway-server # 應(yīng)用名稱
啟動(dòng)類
package com.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class GatewayServerApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayServerApplication.class, args);
}
}
配置路由規(guī)則
spring:
application:
name: gateway-server # 應(yīng)用名稱
cloud:
gateway:
# 路由規(guī)則
routes:
- id: product-service # 路由 ID,唯一
uri: http://localhost:7070/ # 目標(biāo) URI棵癣,路由到微服務(wù)的地址
predicates: # 斷言(判斷條件)
- Path=/product/** # 匹配對(duì)應(yīng) URL 的請(qǐng)求辕翰,將匹配到的請(qǐng)求追加在目標(biāo) URI 之后
- 請(qǐng)求
http://localhost:9000/product/1
將會(huì)路由至http://localhost:7070/product/1
訪問(wèn):http://localhost:9000/product/1 結(jié)果如下:
本篇文章先讓大家簡(jiǎn)單認(rèn)識(shí)一下 Gateway 網(wǎng)關(guān),下一篇我們講解 Gateway 網(wǎng)關(guān)的多種路由規(guī)則狈谊、動(dòng)態(tài)路由規(guī)則(配合服務(wù)發(fā)現(xiàn)的路由規(guī)則)喜命,記得關(guān)注噢~
本文采用 知識(shí)共享「署名-非商業(yè)性使用-禁止演繹 4.0 國(guó)際」許可協(xié)議
。
大家可以通過(guò) 分類
查看更多關(guān)于 Spring Cloud
的文章河劝。
?? 您的點(diǎn)贊
和轉(zhuǎn)發(fā)
是對(duì)我最大的支持壁榕。
?? 關(guān)注公眾號(hào) 哈嘍沃德先生
「文檔 + 視頻」每篇文章都配有專門視頻講解,學(xué)習(xí)更輕松噢 ~