Java之SpringCloud Alibaba【一】【Nacos一篇文章精通系列】 | 跳轉 |
---|---|
Java之SpringCloud Alibaba【二】【微服務調用組件Feign】 | 跳轉 |
Java之SpringCloud Alibaba【三】【微服務Nacos-config配置中心】 | 跳轉 |
Java之SpringCloud Alibaba【四】【微服務 Sentinel服務熔斷】 | 跳轉 |
Java之SpringCloud Alibaba【五】【微服務 Sentinel整合openfeign進行降級】 | 跳轉 |
Java之SpringCloud Alibaba【六】【Alibaba微服務分布式事務組件—Seata】 | 跳轉 |
Java之SpringCloud Alibaba【七】【Spring Cloud微服務網(wǎng)關Gateway組件】 | 跳轉 |
Java之SpringCloud Alibaba【八】【Spring Cloud微服務Gateway整合sentinel限流】 | 跳轉 |
Java之SpringCloud Alibaba【九】【Spring Cloud微服務Skywalking】 | 跳轉 |
一、網(wǎng)關簡介
大家都都知道在微服務架構中,一個系統(tǒng)會被拆分為很多個微服務。那么作為客戶端要如何去調用這么多的微服務呢?如果沒有網(wǎng)關的存在,我們只能在客戶端記錄每個微服務的地址,然后分別去用。
這樣的架構,會存在著諸多的問題:
- 每個業(yè)務都會需要鑒權、限流、權限校驗、跨域等邏輯,如果每個業(yè)務都各自為戰(zhàn)。自己造輪子實現(xiàn)一遍,會很蛋疼,完全可以抽出來,放到一個統(tǒng)一的地方去做。
- 如果業(yè)務量比較簡單的話,這種方式前期不會有什么問題,但隨著業(yè)務越來越復雜,比如淘寶、亞馬遜打開一個頁面可能會涉及到數(shù)百個微服務協(xié)同工作,如果每一個微辰務都分配一個域名的話,一方面客戶端代碼會很難維護,涉及到數(shù)百個域名,另一方面是連接數(shù)的瓶頸想象一下你打開一個APP,通過抓包發(fā)現(xiàn)涉及到了數(shù)百個遠程調用,這在移動端下會顯得非常低效。
- 后期如果需要對微服務進行重構的話,也會變的非常麻煩,需要客戶端配合你一起進行改造,比如商品服務,隨著業(yè)務變的越來越復雜,后期需要進行拆分成多個微服務這個時候對外提供的服務也需要拆分成多個,同時需要客戶端配合你進行改造,非常蛋疼。
上面的這些問題可以借助API網(wǎng)關來解決。
所謂的API網(wǎng)關,就是指系統(tǒng)的統(tǒng)一入口,它封裝了應用程序的內部結構,為客戶說提供統(tǒng)一服務,一些與業(yè)務本身功能天關的公共邏輯可以在這里實現(xiàn)。諸如認證、鑒權、監(jiān)控、路由轉發(fā)等等,添加上API網(wǎng)關之后,系統(tǒng)的架構圖變成了如下所示:
1、什么是Spring Cloud Gateway
網(wǎng)關作為流量的入口,常用的功能包括路由轉發(fā),權限校驗,限流等。
Sping Cloud cGateway是Sping Clou官方推出的第二代網(wǎng)關框架,定位于取代NeificZul。
相比Zul來說,Spring Cloud Gateway提供更優(yōu)秀的性能,更強大的有功能。
Spring Cloud Gateway是由WebFlux + Netty + Reactor實現(xiàn)的響應式的API網(wǎng)關。它不能在傳統(tǒng)的servlet容器中工作,也不能構建成war包。
Sping Cloud Gateway旨在為微服務架構提供一種簡單且有效的API路由的管理方式,并基于Fiter的方式提供網(wǎng)關的基本功能,例如說安全認證、監(jiān)控、限流等等。官網(wǎng)文檔: https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gateway-request-predicates-factories
Spring Cloud Gateway 功能特征
- 基于Spring Framework 5, Project Reactor和 Spring Boot 2.0進行構建;
- 動態(tài)路由:能夠匹配任何請求屬性;
- 支持路徑重寫;
- 集成 Spring Cloud 服務發(fā)現(xiàn)功能(Nacos、Eruka) ;
- 可集成流控降級功能(Sentinel、Hystrix) ;
- 可以對路由指定易于編寫的Predicate(斷言)和Filter (過濾器);
2、核心概念
-
路由(route)
路由是網(wǎng)關中最基礎的部分,路由信息包括一個ID、一個目的URI、一組斷言工廠、一組Filter組成。如果斷言為真,則說明請求的URL和配置的路由匹配。 -
斷言(predicates)
Java3中的斷言函數(shù),SpringCloud Gateway中的斷言函數(shù)類型是Sping5.0框架中的SeverieExctange。斷言函數(shù)允許開發(fā)者去定義匹酷t(yī) request中的任何信息,比加如請求頭和參數(shù)等。 -
過濾器(Filter)
SpringCloud Gateway中的filter分為Gateway Filler和Global Filter。Filter可以對請求和響應進行處理
3、工作原理
Spring Cloud Gateway的工作原理跟Zuul的差不多,最大的區(qū)別就是Gateway的Filter只有pre和post 兩種。
客戶端向Spring Cloud Gateway發(fā)出請求,如果請求與網(wǎng)關程序定義的路由匹配,則該請求就會被發(fā)送到網(wǎng)關Web處理程序,此時處理程序運行特定的請求過濾器鏈。過濾器之間用虛線分開的原因是過濾器可能會在發(fā)送代理請求的前后執(zhí)行邏輯。所有pre過濾器邏輯先執(zhí)行,然后執(zhí)行代理請求;代理請求完成后,執(zhí)行post過濾器邏輯。
二、Spring Cloud Gateway快速開始
1、環(huán)境搭建【基本環(huán)境搭建-實現(xiàn)路由】
注意:會和spring-webmvc的依賴沖突,需要排除spring-webmvc
<dependencies>
<!--gateway的依賴 springcloud 開發(fā)-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
</dependencies>
設置配置文件
server:
port: 8088
spring:
application:
name: api-gateway
# gateway的配置
cloud:
gateway:
routes:
- id: order_route #路由的唯一標識,路由到order
uri: http://localhost:8020 #需要轉發(fā)的地址
#斷言規(guī)則 用于路由規(guī)則的匹配
predicates:
- Path=//
# http://localhost:8088/order-serve/order/add 路由到↓
# http://localhost:8020/order-serve/order/add
filters:
- StripPrefix=1 # 轉發(fā)之前,去掉第一次的路徑
# http://localhost:8020/order/add
#- id: stock_route
訪問:http://localhost:8088/order-serve/order/add
2、集成Nacos
<!-- nacos服務注冊與發(fā)現(xiàn) -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
server:
port: 8088
spring:
application:
name: api-gateway
# gateway的配置
cloud:
gateway:
routes:
- id: order_route #路由的唯一標識,路由到order
uri: lb://order-service # 需要轉發(fā)的地址 lb指的是從nacos中按照名稱獲取微服務,并遵循負載均衡策略 order-service服務名
#斷言規(guī)則 用于路由規(guī)則的匹配
predicates:
- Path=/order-serve/**
# http://localhost:8088/order-serve/order/add 路由到↓
# http://localhost:8020/order-serve/order/add
filters:
- StripPrefix=1 # 轉發(fā)之前,去掉第一次的路徑
# http://localhost:8020/order/add
#- id: stock_route
# 配置Nacos
nacos:
discovery:
server-addr: 127.0.0.1:8848
username: nacos
password: nacos
重新運行并訪問:
http://localhost:8088/order-service/order/add
設置約定集成nacos
server:
port: 8088
spring:
application:
name: api-gateway
cloud:
# gateway的配置
gateway:
discovery:
locator:
enabled: true #是否啟動自動識別nacos服務
#配置Nacos
nacos:
discovery:
server-addr: 127.0.0.1:8848
username: nacos
password: nacos
重新啟動項目
訪問服務名對應的地址:http://localhost:8088/order-service/order/add
重新啟動項目
訪問:http://localhost:8088/order/add
調整時間
重新運行項目
http://localhost:8088/order/add
3、路由斷言工廠(Route Predicate Factories)配置
https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gateway-request-predicates-factories
作用:當請求gateway的時候, 使用斷言對請求進行匹配, 如果匹配成功就路由轉發(fā),如果匹配失敗就返回404
類型:內置,自定義
SpringCloud Gateway包括許多內置的斷言工廠,所有這些斷言都與HTTP請求的不同屬性匹配。具體如下:
- 基于Datetime類型的斷工廠
此類型的斷言根據(jù)時間做判斷,主要有三個:
AfterRoutePredicateFactory:接收一個日期參數(shù), 判斷請求日期是否晚于指定日期
BeforeRoutePredicateFactory:接收- 個日期參數(shù),判斷請求日期是否早于指定日期
BetweenRoutePredicateFactory:接收兩個日期參數(shù),判斷請求日期是否在指定時間段內
- After=2023-10-19T09:07:00.660+08:00[Asia/Shanghai]
-
基于遠程地址的斷言工廠
RemoteAddrRoutePredicateFactory:接收一個IP地址段,判斷請求主機地址是否在地址段中
- RemoteAddr=192.168.1.1/24
-
基于Cookie的斷言工廠
CookieRoutePredicateFactory:接收兩個參數(shù), cookie 名字和一個正則表達式。判斷請求cookie是否具有給定名稱且值與正則表達式匹配。
-Cookie=chocolate, ch.
- 基于Header的斷言工廠
HeaderRoutePredicateFactory:接收兩個參數(shù),標題名稱和正則表達式。判斷請求Header是否具有給定名稱且值與正則表達式匹配。
- Header=X-Request-Id, \d+
重新啟動項目
利用API工具發(fā)送請求
把Headers當中的請求參數(shù)取消重新發(fā)起請求,會報錯
- 基于Host的斷言工廠
HostRoutePredicateFactory:接收一個參數(shù), 主機名模式。判斷請求的Host是否滿足匹配規(guī)則。
-Host=**.testhost.org
- 基于Method請求方法的斷言工廠
MethodRoutePredicateFactory:接收一個參數(shù), 判斷請求類型是否跟指定的類型匹配。
重新啟動測試
通過GET發(fā)送請求
通過POST發(fā)起請求
-
基于Query請求參數(shù)的斷言工廠
設置必須傳遞參數(shù)為name的參數(shù)
- Query=name
重新啟動發(fā)起請求,沒有設置name參數(shù)報錯
設置name參數(shù)
設置指定參數(shù)
- Query=name,xushu|zhuge
設置name的參數(shù)只能是xushu或者zhuge否則斷言失敗
發(fā)送請求報錯
將參數(shù)改為xushu請求成功,改為zhuge也請求成功
- 基于路由權重的斷言工廠
WeightRoutePredicateFactory:接收-個[組名 權重],然后對于同-一個組內的路由按照權重轉發(fā)
routes:
-id: weight_ route1
uri: host1
predicates:
-Path=/ product/**
-Weight=group3,1
-id: weight_ route2
uri: host2
predicates:
- Path=/ product/**
-Weight= group3, 9
4、自定義路由斷言工廠
自定義路由斷言工廠需要繼承AbstractRoutePredicateFactory類,重寫apply方法的邏輯。
在apply方法中可以通過exchange. getRequest()倒ServerHttpRequest對象,從而可以獲取到請求的參數(shù)、請求方式、請求頭等信息。
1、必須是Spring組件bean
2、類必須加上RoutePredicateFactory作為結尾
3、必須繼承AbstractRoutePredicateFactory
4、必須聲明靜態(tài)的內部類 聲明屬性來接受配置文件當中配置的斷言信息
5、需要結合shortcutFieldOrder進行綁定
6、通過apply方法進行邏輯判斷 true 就是匹配成功 false就是匹配失敗
注意:命名需要以RoutePredicateFactory結尾
@Component
public class CheckAuthRoutePredicateFactory
extends AbstractRoutePredicateFactory<CheckAuthRoutePredicateFactory.Config> {
public CheckAuthRoutePredicateFactory() {
super(CheckAuthRoutePredicateFactory.Config.class);
}
@Override
public List<String> shortcutFieldOrder() {
return Arrays.asList("name");
}
@Override
public Predicate<ServerWebExchange> apply(CheckAuthRoutePredicateFactory.Config config) {
return new GatewayPredicate() {
@Override
public boolean test(ServerWebExchange exchange) {
if(config.getName().equals("xushu")){
return true;
}
return false;
}
};
}
// 用于接收配置文件中 斷言的信息
@Validated
public static class Config {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
}
重新啟動項目
訪問:http://localhost:8088/order/add
修改對應的斷言名稱
查詢啟動
http://localhost:8088/order/add
5、過濾器工廠( GatewayFilter Factories)配置
https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gatewayilter-factories
5.1、添加請求頭參數(shù)
filters:
- AddRequestHeader=X-Request-color,red
@RequestMapping("/header")
public String header(@RequestHeader("X-Request-color") String color){
return color;
}
重新啟動兩個項目
http://localhost:8088/order/header
5.2、添加請求參數(shù)
- AddRequestParameter=color,blue
@RequestMapping("/parameter")
public String parameter(@RequestParam("color") String color){
return color;
}
http://localhost:8088/order/parameter
5.3、為匹配的路由統(tǒng)一添加前綴
servlet:
context-path: /mall-order
- PrefixPath=/mall-order #添加前綴對應微服務需要配置context-path
重新啟動兩個項目
訪問:http://localhost:8088/order/add
現(xiàn)在訪問:http://localhost:8020/mall-order/order/add
然而訪問8082必須攜帶前綴
http://localhost:8020/mall-order/order/add
5.4、配置重定向
- RedirectTo=302, https://www.baidu.com
訪問:http://localhost:8088/order/add
重定向到了百度
5.5、自定義狀態(tài)碼
- SetStatus= 404
訪問:http://localhost:8088/order/add
雖然訪問成功了,但是返回的狀態(tài)碼為404
6、自定義過濾器工廠
繼承AbstractNameValueGatewayFilterFactory且我們的自定義名稱必須要以GatewayFilterFactory結尾并交給spring管理。
創(chuàng)建CheckAuthGatewayFilterFactory
/***
*/
@Component
public class CheckAuthGatewayFilterFactory
extends AbstractGatewayFilterFactory<CheckAuthGatewayFilterFactory.Config> {
public CheckAuthGatewayFilterFactory() {
super(Config.class);
}
@Override
public List<String> shortcutFieldOrder() {
return Arrays.asList("value");
}
@Override
public GatewayFilter apply(Config config) {
return new GatewayFilter() {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
String name=exchange.getRequest().getQueryParams().getFirst("name");
if(StringUtils.isNotBlank(name)){
if(config.getValue().equals(name)){
return chain.filter(exchange);
}
else {
// 返回404
exchange.getResponse().setStatusCode(HttpStatus.NOT_FOUND);
return exchange.getResponse().setComplete();
}
}
// 正常請求
return chain.filter(exchange);
}
};
}
public static class Config {
private String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
}
- CheckAuth=xushu
7、全局過濾器(Global Filters)
局部過濾器和全局過濾器的區(qū)別
局部:針對某個路由,需要在路由中進行配置
全局:針對所有路由請求,一旦定義就會投入使用
GlobalFilter接口和GatewayFilter有一樣的接口定義, 只不過,GlobalFilter 會作用于所有路由。
@Component
public class LogFilter implements GlobalFilter {
Logger log= LoggerFactory.getLogger(this.getClass());
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
log.info(exchange.getRequest().getPath().value());
return chain.filter(exchange);
}
}
重新啟動:http://localhost:8088/order/add?name=xushu
8、Reactor Netty訪問日志
要啟用Reactor Netty訪問日志,請設置
-Dreactor.netty.http.server.accessLogEnabled=true
它必須是Java系統(tǒng)屬性,而不是Spring Boot屬性。
您可以將日志記錄系統(tǒng)配置為具有單獨的訪問日志文件。以下示例創(chuàng)建一個Logback配置:
<appender name=" accessLog" class="ch.qos.logback.core.FileAppender">
<file>access_log.log</file>
<encoder>
<pattern>%msg%n</pattern>
</encoder>
</appender>
<appender name=" async" class="ch.qos.logback.classic.AsyncAppender">
<appender-ref ref="accessLog" />
</appender>
<logger name="reactor.netty.http.server.AccessLog" level="INFO" additivity="false">
<appender-ref ref=" async"/>
</logger>
8.1、Gateway跨域配置(CORS Configuration)
通過ym|配置的方式
https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#cors-configuration
globalcors:
cors-configurations:
'[/**]': # 允許跨域訪問的資源
allowedOrigins: "*" #跨域允許的來源 例如:www.smsm.com
allowedMethods:
- GET
- POST
- PUT
模擬跨域請求,設置發(fā)起請求的頁面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="http://apps.bdimg.com/libs/jquery/1.9.1/jquery.min.js"></script>
</head>
<body>
<div >
<table border="1">
<thead>
<tr>
<th>id</th>
<th>username</th>
<th>age</th>
</tr>
</thead>
<tbody id="userlist">
</tbody>
</table>
</div>
<input type="button" value="用戶列表" onclick="getData()">
<script>
function getData() {
$.get('http://localhost:8088/order/add',function(data){
alert(data)
});
}
</script>
</body>
</html>
訪問網(wǎng)頁
allowedOrigins: "localhost:8088" #跨域允許的來源 例如:www.smsm.com
再次訪問訪問網(wǎng)頁(拋出跨域異常)
設置*運行所有的來源訪問
Spring自帶的跨域方式文章來源:http://www.zghlxwxcb.cn/news/detail-739292.html
@Configuration
public class CorsConfig {
@Bean
public CorsWebFilter corsFilter() {
CorsConfiguration config = new CorsConfiguration();
config.addAllowedMethod("*"); //允許運行method
config.addAllowedOrigin("*"); //允許的來源
config.addAllowedHeader("*"); //允許的請求頭參數(shù)
// 允許訪問的資源
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(new PathPatternParser());
source.registerCorsConfiguration("/**",config);
return new CorsWebFilter(source);
}
}
文章來源地址http://www.zghlxwxcb.cn/news/detail-739292.html
Java之SpringCloud Alibaba【一】【Nacos一篇文章精通系列】 | 跳轉 |
---|---|
Java之SpringCloud Alibaba【二】【微服務調用組件Feign】 | 跳轉 |
Java之SpringCloud Alibaba【三】【微服務Nacos-config配置中心】 | 跳轉 |
Java之SpringCloud Alibaba【四】【微服務 Sentinel服務熔斷】 | 跳轉 |
Java之SpringCloud Alibaba【五】【微服務 Sentinel整合openfeign進行降級】 | 跳轉 |
Java之SpringCloud Alibaba【六】【Alibaba微服務分布式事務組件—Seata】 | 跳轉 |
Java之SpringCloud Alibaba【七】【Spring Cloud微服務網(wǎng)關Gateway組件】 | 跳轉 |
Java之SpringCloud Alibaba【八】【Spring Cloud微服務Gateway整合sentinel限流】 | 跳轉 |
Java之SpringCloud Alibaba【九】【Spring Cloud微服務Skywalking】 | 跳轉 |
到了這里,關于Java之SpringCloud Alibaba【七】【Spring Cloud微服務網(wǎng)關Gateway組件】的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!