一.網關
1.問題提出
我們通過Eureka,Nacos解決了服務注冊,服務發現的問題,使用SpringCloud LoadBalance解決了負載均衡的問題,使用OpenFeign解決了遠程調用的問題。
但是當前所有微服務的接口都是直接對外暴露的,可以直接通過外部訪問。為了保證對外服務的安全性,?服務端實現的微服務接口通常都帶有?定的權限校驗機制。
由于使用了微服務,原本?個應用的多個模塊拆分成了多個應用,我們不得不實現多次校驗邏輯。當這套邏輯需要修改時,我們需要修改多個應用,比較麻煩。
這個時候就可以使用網關Gateway了。
2.API網關
API網關也是?個服務,通常是后端服務的唯一入口。它的定義類似設計模式中的Facade模式。它就類似整個微服務架構的門面,所有的外部客戶端訪問,都需要經過它來進行調度和過濾。
網關的核心功能:
1)權限控制:作為入口,可對用戶進行權限校驗,對校驗失敗的用戶進行攔截;
2)動態路由:?切請求先經過網關,但網關不處理業務,而是根據某種規則,把請求轉發到某個微服務;
3)負載均衡:當路由的目標服務有多個時,需要做負載均衡;
4)限流:請求流量過高時,按照網關中配置微服務能夠接受的流量進行放行。
二.SpringCloudGateway
由于API網關是一個服務,所以我們要先創建一個項目(服務)。
1.引入網關依賴
<!--網關-->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!--Nacos-->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--負載均衡-->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
2.編寫啟動類
@SpringBootApplication
public class GatewayApplication {public static void main(String[] args) {SpringApplication.run(GatewayApplication.class,args);}
}
3.添加Gateway的路由配置
創建application.yml文件,添加配置:
server:port: 10030
spring:application:name: gatewaycloud:nacos:discovery:server-addr: 127.0.0.1:8848gateway:metrics:enabled: trueroutes:- id: order-service uri: lb://order-service/ predicates: - Path=/order/**,/feign/**- id: product-serviceuri: lb://product-service/predicates:- Path=/product/**
字段說明:
1)id:自定義路由ID,保持唯一,不能重復;
2)uri:目標服務地址,支持普通URI及 lb:// 應用注冊服務名稱。lb標識負載均衡,使用 lb:// 方式標識從注冊中心獲取服務地址;
3)predicates:路由條件,根據匹配結果決定是否執行該請求路由,上述代碼中,我們把符合Path規則的一切請求,都代理到uri參數指定的地址。
三.Route Predicate Factories
Route Predicate Factories,在Spring Cloud Gateway中,Predicate提供了路由規則的匹配機制。
這里舉幾個例子給大家看。
After | 匹配指定日期之后的請求 |
Before | 匹配指定日期之前的請求 |
Between | 匹配兩個指定時間之間的請求 datetime2 的參數必須在 datetime1 之后 |
具體寫一下After的例子:
可以先通過下面的代碼獲取時間:
System.out.println(ZonedDateTime.now());
在配置網關的配置文件中添加:
predicates:- Path=/product/**- After=2025-04-28T15:40:18.609323500+08:00[Asia/Shanghai]
詳細內容大家可以去Spring官網查看:Route Predicate Factories :: Spring Cloud Gateway
四.Gateway Filter Factories
1.簡介
Predicate決定了請求由哪?個路由處理,如果在請求處理前后需要加?些邏輯,這就是Filter(過濾器)的作用范圍了。
Filter分為兩種類型:
1)Pre類型過濾器:路由處理之前執行(請求轉發到后端服務之前執行),在Pre類型過濾器中可以做鑒權,限流等.;
2)Post類型過濾器::求執行完成后,將結果返回給客戶端之前執行。
Spring Cloud Gateway中內置了很多Filter,用于攔截和鏈式處理web請求。
Spring Cloud Gateway從作用范圍上,也看把Filter可分為兩類:
1)GatewayFilter:應用到單個路由或者?個分組的路由上;
2)GlobalFilter:應用到所有的路由上,也就是對所有的請求生效。
2.GatewayFilter
GatewayFilter也是將配置信息放在配置文件中,Spring Cloud Gateway提供了不少Filter,具體大家可以去官網看:AddRequestHeader GatewayFilter Factory :: Spring Cloud Gateway
左面的那些就是Filter,下面我舉一個例子:AddRequestParameter
spring:cloud:gateway:routes:- id: add_request_header_routeuri: https://example.orgfilters:- AddRequestParameter=userName,Kobayashi
使用這個Filter可以為所有請求添加一個參數userName。
在Spring Cloud Gateway提供的所有Filter中,有一個特殊的Filter:Default Filters,默認過濾器。
默認過濾器可以對全部路由生效:
spring:cloud:gateway:default-filters:- AddResponseHeader=X-Response-Default-Red, Default-Blue- PrefixPath=/httpbin
其實從代碼中也可以看出,default-filters是與routes同級的,這也能說明默認過濾器不僅僅是對某一些路由生效,而是對所有路由生效。
3.GlobalFilter
GlobalFilter是Spring Cloud Gateway中的全局過濾器。
1)添加過濾器
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
2)添加配置
spring:cloud:gateway:metrics:enabled: true
management:endpoints:web:exposure:include: "*"endpoint:health:show-details: alwaysshutdown:enabled: true
4.過濾器執行順序
請求路由后,網關會把當前項目中的GatewayFilter和GlobalFilter合并到?個過濾器鏈(集合)中,并進行排序,依次執行過濾器。
每?個過濾器都必須指定?個int類型的order值,默認值為0,表示該過濾的優先級。order值越小,優先級越高,執行順序越靠前。
1)Filter通過實現Order接口或者添加@Order注解來指定order值。
2)SpringCloudGateway提供的Filter由Spring指定。用戶也可以自定義Filter,由用戶指定。
3)當過濾器的order值?樣時,會按照defaultFilter>GatewayFilter>GlobalFilter的順序執行。