Gateway服務網關
- Gateway服務網關概述
- Gateway核心概念
- Gateway執行個體與配置
- 通過微服務名實作動态路由
-
- 路由斷言工廠(Route Predicate Factories)
-
- 一、After Route Predicate
- 二、Before Route Predicate
- 三、Between Route Predicate
- 四、Cookie Route Predicate
- 五、Header Route Predicate
- 六、Host Route Predicate
- 七、Method Route Predicate
- 八、Path Route Predicate
- 九、Query Route Predicate
- 十、RemoteAddress Route Predicate
- 十一、Weight Route Predicate
- 網關過濾器工廠(GatewayFilter Factories)
-
- 官網網關過濾器
- 自定義網關過濾器
- Gateway實作服務降級、熔斷、限流
Gateway服務網關概述
1、是 SpringCloud 的一個全新項目,基于
SpringCloud Gateway
等技術開發的服務網關,
Spring 5.0 + Springboot 2.0 和 Project Reactor
SpringCloud Gateway 作為 SpringCloud 生态系統中的網關,目标是替代Zuul,在SpringCloud 2.0以上版本中,沒有對新版本的Zuul 2.0以上最新高性能版本進行內建,仍然還是使用的Zuul 1.x非Reactor模式的老版本。而為了提升網關的性能,SpringCloud Gateway 是基于
它旨在為微服務架構提供一種簡單有效的統一的 API 路由管理方式。
實作的,而WebFlux架構底層則使用了高性能的Reactor模式通信架構Netty。
WebFlux
:Spring Cloud Gateway的目标提供統一的路由方式且基于Filter鍊的方式提供了網關基本的功能,例如:安全、監控/名額,和限流。(
作用
)
反向代理、鑒權、流量控制、熔斷、日志監控.......
2、為什麼要選擇Gateway?
(1)Gateway 是基于
Gateway:
異步非阻塞模型
進行開發的,性能強大。
(2)基于Spring 5.0、Project Reactor 和 SpringBoot 2.0 建構。
(3)動态路由:能夠比對任何請求屬性;
(4)可以對路由指定 Predicate(斷言)和 Filter(過濾器)。
(5)內建 Hystrix 的斷路器功能。
(6)內建SpringCloud的服務發現功能。
(7)易于編寫的 Predicate(斷言)和 Filter(過濾器)。
(8)請求限流功能。
(9)支援路徑重寫。
(1)Zuul 1.x 是一個
Zuul:
基于阻塞 I/O
的API網關
(2)
,它
Zuul 1.x 是基于Servlet2.5 使用阻塞架構
(如:WebSocket),Zuul的設計模式和Nginx較像,每次 I/O 操作都是從工作線程中選擇一個執行,請求線程被阻塞到工作線程完成,但是差别是Nginx是用C++實作。
不支援在任何長連接配接
Zuul用Java實作,而JVM本省會有第一次加載較慢的情況,使得Zuul的性能相對較差
。
(3)Zuul 2.x 理念更先進,想基于Netty 非阻塞和支援長連接配接,但SpringCloud目前還沒有整合。Zuul 2.x 的性能較Zuul 1.x 有較大提升。在性能方面,根據官方提供的基準測試,SpringCloud Gateway 的 RPS(每秒請求數)是 Zuul 的1.6倍。
(4)SpringCloud Gateway 建立在Spring 5.0、Project Reactor 和 SpringBoot 2.0 之上,使用非阻塞API。
(5)SpringCloud Gateway還支援WebSocket,并且與spring緊密繼承擁有更好的開發體驗。
Gateway核心概念
一、總體概念圖示:
1、
路由(Route):
路由是建構網關的基本子產品,它由ID、目标URI,一系列的斷言和過濾器組成,如果斷言為true,則比對該路由。
2、
參考Java8的java.util.function.Predicate。
斷言(predicate):
開發人員可以比對HTTP請求中的所有内容(如:請求頭、請求參數),如果請求與斷言相比對則進行路由
。
3、
指的是Spring架構中 GatewayFilter的執行個體,使用過濾器,可以在請求之前或者之後對請求進行修改。 web請求,通過與Predicate相比對,定位到真正的服務節點,并在這個轉發過程前後,進行一些精細化控制。Predicate就是請求的比對條件。而FIlter,就可以了解為一個無所不能的攔截器。有了這兩個元素,再加上目标URI,就可以實作一個具體的路由
過濾器(Filter):
二、Gateway工作流程圖
用戶端向 Spring Cloud Gateway 送出請求。如果網關處理程式映射确定請求與路由比對,則将其發送到網關 Web 處理程式。此處理程式通過特定于請求的過濾器鍊運作請求。過濾器被虛線分隔的原因是過濾器可以在發送代理請求之前和之後運作邏輯。執行所有過濾器邏輯。然後進行代理請求。發出代理請求後,将運作
pre
post
過濾器邏輯。
Filter在
類型的過濾器可以做
pre
在
參數校驗、權限校驗、流量監控、日志輸出、協定轉換等。
類型的過濾器中可以做
post
等非常重要的作用。
相應内容、響應頭的修改、日志輸出、流量監控
Gateway執行個體與配置
官網配置:https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html
一、方式一:yml 配置檔案配置
1、建立module:cloud-gateway-gateway9527
2、引入 pom 依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
3、yml 配置檔案
server:
port: 9527
spring:
application:
name: cloud-gateway
cloud:
gateway:
routes:
#路由的ID,沒有固定的配置規則,但要求唯一,建議配合服務名配置
- id: payment_route1
#比對後提供服務的路由位址
uri: http://localhost:8001
predicates:
#斷言,路徑相比對的進行路由
- Path=/payment/get/**
- id: payment_route2
uri: http://localhost:8001
predicates:
- Path=/payment/lb/**
#注冊中心配置
eureka:
client:
#表示收将自己注冊到EurekaServer,預設為true
register-with-eureka: true
#是否從EurekaServer抓取已有的注冊資訊,預設為true,單節點無所謂,叢集必須設定為true才能配合ribbon使用負載均衡
fetchRegistry: true
service-url:
# defaultZone: http://localhost:7001/eureka
defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka
instance:
hostname: cloud-gateway-service
instance-id: cloud-gateway-service9527
prefer-ip-address: true #通路路徑可以顯示IP位址
4、主啟動類
@SpringBootApplication
@EnableEurekaClient
public class GatewayMain9527 {
public static void main(String[] args) {
SpringApplication.run(GatewayMain9527.class, args);
}
}
5、測試
測試位址:、
http://localhost:8001/payment/get/1
測試發現兩個位址的通路結果一緻。
http://localhost:9527/payment/get/1
一、方式二:RouteLocator(路由定位)配置
@Configuration
public class GatewayConfig {
/*路由國内新聞*/
@Bean
public RouteLocator customRouteRule(RouteLocatorBuilder routeLocatorBuilder) {
RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();
routes.route("path_route_atguigu",
route -> route.path("/guonei")
.uri("https://news.baidu.com/")).build();
return routes.build();
}
}
通過微服務名實作動态路由
預設情況下
:Gateway 會根據注冊中心的服務清單,以注冊中心上微服務名為路徑建立動态路由進行轉發,進而實作動态路由的功能。
server:
port: 9527
spring:
application:
name: cloud-gateway
cloud:
gateway:
discovery:
locator:
enabled: true #開啟從注冊中心動态建立路由的功能,通過微服務名進行路由
routes:
#路由的ID,沒有固定的配置規則,但要求唯一,建議配合服務名配置
- id: payment_route1
#uri: http://localhost:8001 #比對後提供服務的路由位址
uri: lb://cloud-payment-service #比對後提供服務的路由位址
predicates:
#斷言,路徑相比對的進行路由
- Path=/payment/get/**
- id: payment_route2
#uri: http://localhost:8001
uri: lb://cloud-payment-service #比對後提供服務的路由位址
predicates:
- Path=/payment/lb/**
- After=2021-09-29T11:42:42.915+08:00[Asia/Shanghai]
eureka:
client:
#表示收将自己注冊到EurekaServer,預設為true
register-with-eureka: true
#是否從EurekaServer抓取已有的注冊資訊,預設為true,單節點無所謂,叢集必須設定為true才能配合ribbon使用負載均衡
fetchRegistry: true
service-url:
#defaultZone: http://localhost:7001/eureka
defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka
instance:
hostname: cloud-gateway-service
instance-id: cloud-gateway-service9527
prefer-ip-address: true #通路路徑可以顯示IP位址
需要注意的是:uri的協定為
lb
,表示啟用
Gateway的負載均衡功能
。
lb://micro-service-name
是 SpringCloud Gateway 在微服務中自動為我們建立的負載均衡 uri。
路由斷言工廠(Route Predicate Factories)
注
:
隻有滿足斷言的比對規則才能通過網關正常通路路由位址。
官網位址:https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gateway-request-predicates-factories
一、After Route Predicate
spring:
cloud:
gateway:
routes:
- id: after_route
uri: https://example.org
predicates:
- After=2017-01-20T17:42:47.789-07:00[America/Denver]
表示在
指定時間之後
可以對該路由位址進行通路,否則通路
404 Not Found
,擷取改時間格式可通過如下方式擷取:
ZonedDateTime zonedDateTime = ZonedDateTime.now(); System.out.println(zonedDateTime);
zonedDateTime
就是我們需要配置的時間格式。
二、Before Route Predicate
spring:
cloud:
gateway:
routes:
- id: before_route
uri: https://example.org
predicates:
- Before=2017-01-20T17:42:47.789-07:00[America/Denver]
表示在
指定時間之前
可以對該路由位址進行通路,否則通路
404 Not Found
,擷取時間格式同上。
三、Between Route Predicate
spring:
cloud:
gateway:
routes:
- id: between_route
uri: https://example.org
predicates:
- Between=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver]
表示在
指定的時間區間内
可以對改路由位址正常通路,否則通路
404 Not Found
,擷取時間格式同上。
四、Cookie Route Predicate
spring:
cloud:
gateway:
routes:
- id: cookie_route
uri: https://example.org
predicates:
- Cookie=name,test
postman測試:
表示此路由比對具有名為
name
的 cookie 的請求,該 cookie 的值與
test
正規表達式
比對時,才能夠對改路由位址進行通路。否則通路 否則通路
404 Not Found
。
五、Header Route Predicate
spring:
cloud:
gateway:
routes:
- id: header_route
uri: https://example.org
predicates:
- Header=token,123
postman測試:
表示請求頭中包含字段名(任意字段)
token
,并且值與
123
正規表達式比對的請求,才能夠對該路由位址進行通路。否則通路
404 Not Found
。
六、Host Route Predicate
spring:
cloud:
gateway:
routes:
- id: host_route
uri: https://example.org
predicates:
- Host=**.gateway.com,**.springcloudgateway.com
postman測試:
表示請求頭中包含字段名
Host
,并且值與
123
正規表達式比對的請求,才能夠對該路由位址進行通路。否則通路
404 Not Found
。
七、Method Route Predicate
spring:
cloud:
gateway:
routes:
- id: method_route
uri: https://example.org
predicates:
- Method=GET,POST
表示該請求方法必須是與指定的斷言中的Method比對,才能對該路由位址進行通路,否則通路
404 Not Found
。
八、Path Route Predicate
spring:
cloud:
gateway:
routes:
- id: path_route
uri: https://example.org
predicates:
- Path=/red/{segment},/blue/{segment}
表示該請求的位址與指定斷言Path比對,才能對該路由位址進行通路,否則通路
404 Not Found
。
九、Query Route Predicate
1、隻要包含該查詢參數就可以比對成功
spring:
cloud:
gateway:
routes:
- id: query_route
uri: https://example.org
predicates:
- Query=green
2、包含查詢參數和值,其中值可以使用正規表達式比對,隻有key和value都比對上才能對該路由位址正常通路。
spring:
cloud:
gateway:
routes:
- id: query_route
uri: https://example.org
predicates:
- Query=red, gree.
十、RemoteAddress Route Predicate
1、如果請求的用戶端的ip位址是192.168.1.1到192.168.1.24的範圍。則路由會被轉發到 https://example.org。
spring:
cloud:
gateway:
routes:
- id: remoteaddr_route
uri: https://example.org
predicates:
- RemoteAddr=192.168.1.1/24
2、
暫未解決
spring:
cloud:
gateway:
discovery:
locator:
enabled: true #開啟從注冊中心動态建立路由的功能,通過微服務名進行路由
routes:
- id: payment_route2
uri: lb://cloud-payment-service #比對後提供服務的路由位址
predicates:
- Path=/payment/lb/**
- RemoteAddr=192.168.0.1/24
十一、Weight Route Predicate
spring:
cloud:
gateway:
routes:
- id: weight_high
uri: https://weighthigh.org
predicates:
- Weight=group1, 8
- id: weight_low
uri: https://weightlow.org
predicates:
- Weight=group1, 2
表示該路由會将約 80% 的流量轉發到 weighthigh.org,約 20% 的流量轉發到 weightlow.org。
網關過濾器工廠(GatewayFilter Factories)
官網網關過濾器
官網配置:https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gatewayfilter-factories
1、生命周期:
pre
、
post
2、種類:
31種
。見逛網配置。
自定義網關過濾器
1、Filter配置類(例:全局網關過濾器)
package com.atguigu.springcloud.filter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.util.Date;
/**
* @author 李宏偉
* @version 1.0
* @ClassName GlobalLogGatewayFilter
* @Description
* @date 2021年10月14日 10:14
*/
@Component
@Slf4j
public class GlobalLogGatewayFilter implements GlobalFilter, Ordered {
/**
* 全局日志網關過濾器:
* ServerWebExchange:表示Web請求服務,可擷取請求HttpServletRequest、響應HttpServletResponse等
* chain:表示網關過濾連
*
* @return
* @params
*/
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
log.info("***********Come in GlobalLogGatewayFilter:" + new Date());
ServerHttpRequest request = exchange.getRequest();
String name = request.getQueryParams().getFirst("name");
if (name == null) {
log.info("***********使用者名不能為空,非法使用者");
//驗證失敗,設定請求失敗狀态
exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
//最後終止向下一個過濾器方法提供委托,并傳回響應
return exchange.getResponse().setComplete();
}
// 放行,并将委托給過濾鍊中的下一個過濾器
return chain.filter(exchange);
}
/**
* 可以在全局網關過濾器配置類中加入 @Order 注解代替實作Ordered接口
* 加載過濾器的優先級,數值越小,加載優先級越高;反之越小
*
* @return
* @params
*/
@Override
public int getOrder() {
return 0;
}
}
2、測試:請求通路:
http://localhost:9527/payment/lb?name=123
能夠
正常傳回
,通路:
http://localhost:9527/payment/lb?age=123
是傳回如下狀态:
Gateway實作服務降級、熔斷、限流
參考文章:https://blog.csdn.net/zhuyu19911016520/article/details/86499528