微服務【SpringCloud】--Gateway入門
阿新 • • 發佈:2020-12-11
技術標籤:2020實習SpringCloud過濾器gateway網路
文章目錄
- Spring Cloud Gateway入門
- Spring Cloud Gateway入門
- 面向服務的路由 uri
- 路由字首處理 filter
- 過濾器簡介
- 過濾器分類
- 自定義全域性過濾器
- 自定義區域性過濾器
Spring Cloud Gateway入門
(1)閘道器是什麼?
閘道器(Gateway) 就是一個網路連線到另一個網路的“關口”。就是網路關卡。
從一個房間走到另一個房間,必然要經過一扇門。同樣,從一個網路向另一個網路傳送資訊,也必須經過一道“關口”
(2)SpringCloud的閘道器是什麼?
Spring Cloud Gateway的核心就是一系列的過濾器,可以將客戶端的請求轉發到不同的微服務。主要作用:過濾和路由。
Spring Cloud Gateway入門
(1)GateWay如何使用
- 依賴
-配置路由資訊
id 路由id,可以任意
uri 代理的服務地址
predicates 路由斷言: 可以匹配對映路徑 - 啟用
-啟動
pom.xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
< groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
application.properties
spring.application.name=demo04_gateway_1001
server.port=1001
eureka.client.service-url.defaultZone=http://127.0.0.1:10086/eureka
# route
spring.cloud.gateway.routes[0].id=demo04_gateway_1001
#spring.cloud.gateway.routes[0].uri.=http://127.0.0.1:8001
spring.cloud.gateway.routes[0].uri=lb://demo01-provider-user
spring.cloud.gateway.routes[0].predicates[0]=Path=/**
#spring.cloud.gateway.routes[0].predicates[0]=Path=/users/*
spring.cloud.gateway.routes[0].filters[0]=PrefixPath=/users
main
@SpringBootApplication
@EnableDiscoveryClient
public class Demo04Gateway1001Application
面向服務的路由 uri
(1)面向服務的路由是什麼?
配置路由資訊時,使用服務的名稱來代替 ip+port的配置方式
只需要在配置檔案中指定路由路徑類似: lb://user-service
(2)代理的服務地址;lb表示從eureka中獲取具體服務
(3)注意事項
lb 之後編寫的服務名必須要在eureka中註冊才能使用
(4)分析
路由配置中uri所用的協議為lb時(以uri: lb://user-service為例),gateway將使用 LoadBalancerClient把user-service通過eureka解析為實際的主機和埠,並進行ribbon負載均衡。
路由字首處理 filter
(1)路由的字首
請求地址與微服務的服務地址如果不一致的時候,可以通過配置路徑過濾器實現路徑字首的新增和去除。
提供服務的地址:http://127.0.0.1:8001/user/8
- 新增字首:對請求地址新增字首路徑之後再作為代理的服務地址;
http://127.0.0.1:101/8 --> http://127.0.0.1:8001/user/8 新增字首路徑/user
spring.cloud.gateway.routes[0].predicates[0]=Path=/**
spring.cloud.gateway.routes[0].filters[0]=PrefixPath=/users
- 去除字首:將請求地址中路徑去除一些字首路徑之後再作為代理的服務地址;
http://127.0.0.1:101/api/user/8 --> http://127.0.0.1:8001/user/8 去除字首路徑/api
spring.cloud.gateway.routes[0].predicates[0]=Path=/api/users/**
spring.cloud.gateway.routes[0].filters[0]=StripPrefix=1
過濾器簡介
(1)過濾器
符合條件的請求放行,否則不放行
(2)Gateway自帶過濾器有幾十個,常見自帶過濾器有
在配置檔案中指定要使用的過濾器名稱
(3)案例:新增響應頭過濾器
spring.cloud.gateway.default-filters[0]=AddResponseHeader=name,rose
spring.cloud.gateway.default-filters[1]=AddResponseHeader=age,34
過濾器分類
過濾器的分類 兩類
- 區域性過濾器
只對當前路由起作用
spring.cloud.gateway.routes.filters - 全域性過濾器
作用在所有的路由上 - spring.cloud.gateway.default-filters + 實現GatewayFilterFactory介面的過濾器
- 實現GlobalFilter介面,不需要配置
自定義全域性過濾器
判斷請求上的token值是否為空,不為空放行
- (1)實現GlobalFilter
- (2)實現Ordered介面
- (3)符合條件,放行
- (4)否則結束響應
//1:本類為全域性閘道器過濾器 /*
@Component
@Slf4j
public class MyGlobalFilter implements GlobalFilter, Ordered {
//exchange = req + resp
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
//攔截方法,攔截到請求後,自動執行
log.info("filter 攔截方法,攔截到請求後,自動執行 ");
//以後開發中,不會將 user物件存到session,只會在地址上帶上token
//根據token是否有空可以判斷是否登入
//http://localhost:8001/users/3?token=10001&pageSize=30
String token = exchange.getRequest().getQueryParams().getFirst("token");
if(token == null || "".equals(token)){
//未登入 跳轉到登入頁
log.info("----跳到登入頁面");
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
exchange.getResponse().setComplete();
}
return chain.filter(exchange);//2 全部放行
}
@Override
public int getOrder() {//3:系統呼叫該方法獲得過濾器的優先順序
return 1; //數字越小,越優先
}
}
自定義區域性過濾器
(1)使用場景:請求鑑權、異常處理、記錄呼叫時長等。
(2)步驟
- 配置
MyParam=name,address - 定義Config
- MyParamGatewayFilterFactory繼承AbstractGatewayFilterFactory
- 實現shortcutFieldOrder
- 實現apply
application.properties
spring.cloud.gateway.routes[0].filters[0]=MyParam=name,address
MyParamGatewayFilterFactory
//1:本類為區域性過濾器類
@Component
@Slf4j
public class MyParamGatewayFilterFactory extends AbstractGatewayFilterFactory<MyParamGatewayFilterFactory.Config> {
//5:將config交給父類的構造方法
public MyParamGatewayFilterFactory() {
super(Config.class);
}
@Override //4:過濾器
public GatewayFilter apply(Config config) {
GatewayFilter gatewayFilter = new GatewayFilter(){
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
//http://127.0.0.1:1001/users/3?token=333&name=jack&address=bj
String name = exchange.getRequest().getQueryParams().getFirst(config.name);
String address = exchange.getRequest().getQueryParams().getFirst(config.address);
log.info("filter ....name"+name);
log.info("filter ....address"+address);
log.info("filter ....攔截了請求");
return chain.filter(exchange);//全部放行
}
};
return gatewayFilter;//返回一個自己定義的過濾器
}
//3:定義順序
@Override
public List<String> shortcutFieldOrder() {//定義變數的順序
List<String> order = new ArrayList<>();
order.add("name");
order.add("address");
return order;
}
//name,address
//http://127.0.0.1:8001/users/1?name=jack&address=bj
@Data //2:定義config
public static class Config{
private String name;
private String address;
}
}