點選上方藍色字型,選擇“标星公衆号”
優質文章,第一時間送達
一、定義
外部請求通過gateWay轉發到後端微服務,網關一般提供如下功能
- 統一接入,路由轉發
- 安全審查,校驗鑒權
- 熔斷降級,資料緩存
- 統一日志,全局監控
總的來說,gateway提供了一個入口來管控所有的微服務,基于這個特點可以靈活使用。
網關解決方案對比
nginx+lua 高性能反向代理伺服器,一般作為負載均衡入口
Zuul是第一代網關,spring
cloud是第二代網關,基于Netty\Reactor\WebFLux建構
- 性能強勁,zuul1.6倍
- 功能強大,内置轉發,監控,限流等功能
缺點
- 不能再servlet容器下功能,不能使用war包
基礎說明
- spring cloud gateway基于springBoot2.x系列,webflux,reactor等技術,傳統的同步庫都是不能使用的
- gateway底層依賴netty,不接受servlet容器或者war包
二、核心術語
Route路由
基礎的轉發規則,包含下面幾部分,當predicate滿足時則代表比對
- id
- 目标url
- predicate集合:滿足條件才轉發
- filter集合:滿足條件則過濾(改變請求)
Predicate謂詞、斷言
java.util.funcation.Predicate實作路由比對條件,通過
ServletWebExchange
(封裝了HTTP請求和相應)作為入參,來對request的各種屬性(參考predicate的各種規則)做比對。
Filter過濾器
修改請求及響應
gateway已經為了我們準備了各種過濾器工廠,我們也可以通過自定義過濾器
三、簡單原理
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsISPrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdsATOfd3bkFGazxCMx8VesATMfhHLlN3XnxCMwEzX0xiRGZkRGZ0Xy9GbvNGLpZTY1EmMZVDUSFTU4VFRR9Fd4VGdsYTMfVmepNHLrJXYtJXZ0F2dvwVZnFWbp1zczV2YvJHctM3cv1Ce-cmbw5CNhNzMjBDOyMTZwYGMjRzYxkzMhBDMxMmN3YDZ3kjZz8CXyAzLcdDMxIDMy8CXn9Gbi9CXzV2Zh1WavwVbvNmLvR3YxUjL2M3Lc9CX6MHc0RHaiojIsJye.png)
- client發送請求給gateway,handlermapping判斷請求路徑是否比對路由配置
- 如果比對成功web handler會讀取路由配置過濾器,把請求交給過濾器處理
- 過濾器如圖是鍊式結構,分為pre和post處理
四、概念講解
Route Predcate Factories
符合Predicate的條件,就使用該路由的配置,否則就不管。
https://www.imooc.com/article/290804
配置形式
模糊比對和精确比對
路由到指定URL
spring:
cloud:
gateway:
routes:
- id: {唯一辨別}
uri: http://www.itmuch.com
表示通路 GATEWAY_URL/** 會轉發到 http://www.itmuch.com/**
需要和predicate配合使用,滿足條件則轉發
spring:
cloud:
gateway:
routes:
- id: {唯一辨別}
uri: http://www.itmuch.com/spring-cloud/spring-cloud-stream-pan-ta/
表示通路 GATEWAY_URL/spring-cloud/spring-cloud-stream-pan-ta/ 會轉發到 http://www.itmuch.com/spring-cloud/spring-cloud-stream-pan-ta/
路由轉發到微服務
路由到服務發現元件上的微服務
routes:
- id: user_route
uri: lb://user-center
predicates:
- Path=/users/**
浏覽器通路 網關url時,
http://localhost:8040/users/1
會自動轉發到user-center服務的接口,等同于通路
http://localhost:9099/users/1
自定義predicate工廠
xxxxRoutePredicateFactory必須以這種形式結尾
routes:
- id: after_route
uri: lb://user-center
predicates:
# 當且僅當請求時的時間After配置的時間時,才會轉發到使用者微服務
# 目前配置不會進該路由配置,是以傳回404
# 将時間改成 < now的時間,則通路localhost:8040/** -> user-center/**
# eg. 通路http://localhost:8040/users/1 -> user-center/users/1
- After=2010-01-20T17:42:47.789-07:00[America/Denver]
- TimeBetween=00:00:00,12:44:13
@Data
public class TimeBetweenBean {
private String start;
private String end;
}
@Component
public class TimeBetweenRoutePredicateFactory
extends AbstractRoutePredicateFactory <TimeBetweenBean>{
public TimeBetweenRoutePredicateFactory() {
super(TimeBetweenBean.class);
}
/**
* 謂詞工廠的核心方法,控制路由的判斷人條件
* @param config
* @return
*/
@Override
public Predicate<ServerWebExchange> apply(TimeBetweenBean config) {
String start = config.getStart();
String end = config.getEnd();
return serverWebExchange ->{
LocalTime now = LocalTime.now();
System.out.println(now.isAfter(LocalTime.parse(start)));
return now.isAfter(LocalTime.parse(start)) && now.isBefore(LocalTime.parse(end));
};
}
/**
* 控制配置類和配置檔案映射關系,和配置檔案順序一緻
* @return
*/
@Override
public List<String> shortcutFieldOrder() {
return Arrays.asList("start","end");
}
}
動态路由-服務名稱轉發
面向服務的路由,支援整合EUREKA或者NACOS注冊中心,根據serviceId自動從注冊中心擷取服務位址并轉發請求。不需要給每個微服務都配置路由規則
discovery:
locator:
enabled: true # 開啟從注冊中心動态建立路由
例子:
http://localhost:8001/payment/get/1?uname=123
http://localhost:9527/cloud-payment-service/payment/get/1?uname=123
五、Filter
生命周期
- Pre:轉發請求之前
- post:轉發請求之後
gateway自帶過濾器講解
1. RewritePath 請求位址重定向
按照正則比對上的路徑重寫為逗号後面的位址
pring:
cloud:
gateway:
routes:
- id: rewritepath_route
uri: https://example.org
predicates:
- Path=/red/**
filters:
- RewritePath=/red/?(?<segment>.*), /$\{segment}
注:效果是去掉/red
2. PrefixPath 添加字首
給請求路徑添加字首
spring:
cloud:
gateway:
routes:
- id: prefixpath_route
uri: https://example.org
filters:
- PrefixPath=/mypath
3. StripPrefix 删除字首
删除請求的指定個數字首後添加到服務末尾
spring:
cloud:
gateway:
routes:
- id: nameRoot
uri: https://nameservice
predicates:
- Path=/name/**
filters:
- StripPrefix=2
例如:請求路徑/name/blue/red,實際效果 nameservice/red
全局過濾器GlobalFilter
無需配置檔案作用在所有的路由,最終通過gatewayfilterAdapter包裝為過濾器
自定義過濾器工廠
- 繼承AbstractGateWayFilterFactory
-
繼承AbstractNameValueGatewayFilterFactory
第一種方式的簡化方式
自定義網關過濾器
@Component
@Slf4j
public class MyLogGateWayFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
log.info("**** com int mylogglbalfiltert{}",new Date());
String uname = exchange.getRequest().getQueryParams().getFirst("uname");
if(uname==null){
log.info("非法使用者");
exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE); //傳回狀态碼
return exchange.getResponse().setComplete();
}
return chain.filter(exchange);
}
@Override
public int getOrder() {
return 0;
}
}
注冊過濾器
@Configuration
public class GateWayConfig {
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder routeLocatorBuilder){
RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();
routes.route("path_route_kouryoushine",
r->r.path("guonei").
uri("http://news.baidu.com/guonei")).build();
return routes.build() ;
}
}
全局過濾器
無需注冊操作,預設直接生效
核心API
- exchange.getRequest().mutate().xxx 修改request
- exchange.mutate.xxx 修改exchange
- chain.filter(exchange) 傳遞給下一個過濾器
- exchange.getResponse() 擷取響應
配置檔案
filters:
- AddRequestHeader=X-Request-Foo,Bar
- PreLog=a,b
@Slf4j
@Component
public class PreLogGatewayFilterFactory extends AbstractNameValueGatewayFilterFactory {
@Override
public GatewayFilter apply(NameValueConfig config) {
log.info("請求建立了{}{}",config.getName(),config.getValue());
return (exchagne,chain)->{
log.info("請求建立了{}{}",config.getName(),config.getValue());
ServerHttpRequest request = exchagne.getRequest()
.mutate()
.build();
ServerWebExchange exchange = exchagne.mutate()
.request(request)
.build();
return chain.filter(exchange);
};
}
}
order越小有效執行
局部過濾器按照配置順序執行
如果想自行控制order,傳回OrderedGateFilter
全局監控
檢視全局過濾器
http://localhost:8040/actuator/gateway/globalfilters
- routes展示路由清單
其他監控包括動态增加路由都可以百度
版權聲明:本文為部落客原創文章,遵循 CC 4.0 BY-SA 版權協定,轉載請附上原文出處連結和本聲明。
本文連結:
https://blog.csdn.net/kouryoushine/article/details/117048823
-
76套java從入門到精通實戰課程分享
-
50份優秀Java求職者履歷
-
新款SpringBoot線上教育平台開源了
-
2020年全網最全BAT筆試面試題打包分享