当前位置:网站首页>微服務入門:Gateway網關
微服務入門:Gateway網關
2022-07-04 08:37:00 【mm天天寫bug】
文章目錄
微服務入門:Gateway網關
一、為什麼需要網關
Gateway相當於微服務中的守門員,它可以幫助我們完成:
- 身份驗證和權限校驗
- 服務路由和負載均衡
- 請求限流
在SpringCloud中網關的實現有兩種方式:
- gateway
- zuul
主要使用gateway,因為Zuul是基於Servlet實現的,屬於阻塞式編程。
而SpringCloudGateway則是基於Spring5中提供的WebFlux,屬於響應式編程的實現,具備更好的性能
二、搭建網關服務
搭建網關服務,首先我們需要創建一個Maven模塊,建議選擇一個空模塊,不要用SpringBoot模板創建,不然會出現未知的錯誤(因為我第一次就是用SpringBoot模板創建的,然後出現了依賴導入不了的Bug)
創建完一個空的Maven項目之後,在pom.xml導入以下依賴
<!--nacos服務發現依賴-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--引入gateway 網關-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
導入依賴後,手動添加GatewayApplication以及yml文件
@SpringBootApplication
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class,args);
}
}
然後在yml配置網關和路由
路由配置包括:
1.路由id:路由的唯一標示
2.路由目標(uri):路由的目標地址,http代錶固定地址,lb代錶根據服務名負載均衡
3.路由斷言(predicates):判斷路由的規則,
4.路由過濾器(filters):對請求或響應做處理
server:
port: 10010
spring:
application:
name: gateway #服務名稱
cloud:
nacos:
server-addr: localhost:8848 #nacos地址
gateway:
routes:
- id: user-service # 路由id,自定義,只要唯一即可
uri: lb://userservice # 路由的目標地址 lb就是負載均衡,後面跟服務名稱
predicates: # 路由斷言,也就是判斷請求是否符合路由規則的條件
- Path=/user/** # 這個是按照路徑匹配,只要以/user/開頭就符合要求
- id: order-service
uri: lb://orderservice
predicates:
- Path=/order/**
如果我們向添加多個服務,那麼則多寫幾個id即可
這樣就完成了網關的搭建
搭建完成的網關就會起到了守門員的作用,當我們請求/user/**這個url的時候,就會根據理由規則判斷是哪一個服務,然後進行負載均衡接著發送請求。
比如我們訪問網關http://localhost:10010/user/1,然後符合/user/**規則,請求轉發到uri:http://userservice/user/1,得到了結果:
三、路由斷言工廠
在上述的yml配置中,可以看到有一個predicates
這個predicates就是路由斷言,判斷請求是否符合規則,符合規則則轉發到路由目的地
在配置文件中寫的斷言規則只是字符串,這些字符串會被Predicate Factory讀取並處理,轉變為路由判斷的條件
例如:Path=/user/**是按照路徑匹配,這個規則是由org.springframework.cloud.gateway.handler.predicate.PathRoutePredicateFactory類來處理的
像這樣的斷言工廠在SpringCloudGateway還有十幾個
名稱 | 說明 | 示例 |
---|---|---|
After | 是某個時間點後的請求 | - After=2037-01-20T17:42:47.789-07:00[America/Denver] |
Before | 是某個時間點之前的請求 | - Before=2031-04-13T15:14:47.433+08:00[Asia/Shanghai] |
Between | 是某兩個時間點之前的請求 | - Between=2037-01-20T17:42:47.789-07:00[America/Denver], 2037-01-21T17:42:47.789-07:00[America/Denver] |
Cookie | 請求必須包含某些cookie | - Cookie=chocolate, ch.p |
Header | 請求必須包含某些header | - Header=X-Request-Id, \d+ |
Host | 請求必須是訪問某個host(域名) | - Host=.somehost.org,.anotherhost.org |
Method | 請求方式必須是指定方式 | - Method=GET,POST |
Path | 請求路徑必須符合指定規則 | - Path=/red/{segment},/blue/** |
Query | 請求參數必須包含指定參數 | - Query=name, Jack或者- Query=name |
RemoteAddr | 請求者的ip必須是指定範圍 | - RemoteAddr=192.168.1.1/24 |
Weight | 權重處理 |
四、路由過濾器
GatewayFilter是網關中提供的一種過濾器,可以對進入網關請求和微服務返回的響應做處理
Spring提供了31中不同的路由過濾工廠,這裏提供幾種展示
名稱 | 說明 |
---|---|
AddRequestHeader | 給當前請求添加一個請求頭 |
RemoveRequestHeader | 移除請求中的一個請求頭 |
AddResponseHeader | 給響應結果中添加一個響應頭 |
RemoveResponseHeader | 從響應結果中移除有一個響應頭 |
RequestRateLimiter | 限制請求的流量 |
4.1 添加過濾器GatewayFilter
在Gateway模塊的yml添加過濾器
下面的案例就是添加請求頭
server:
port: 10010
spring:
application:
name: gateway #服務名稱
cloud:
nacos:
server-addr: localhost:8848 #nacos地址
gateway:
routes:
- id: user-service # 路由id,自定義,只要唯一即可
uri: lb://userservice # 路由的目標地址 lb就是負載均衡,後面跟服務名稱
predicates: # 路由斷言,也就是判斷請求是否符合路由規則的條件
- Path=/user/** # 這個是按照路徑匹配,只要以/user/開頭就符合要求
filters: #過濾器
- AddRequestHeader=Truth,Itcast is freaking aowsome!
- id: order-service
uri: lb://orderservice
predicates:
- Path=/order/**
default-filters: # 默認過濾器,會對所有的路由請求都生效
- AddRequestHeader=Truth,Itcast is freaking aowsome!
filters是局部過濾器,如上代碼所示,其只在user-service起作用
而default-filters是默認過濾器,在路由中的所有服務都起作用
4.2 全局過濾器GlobalFilter
全局過濾器的作用也是處理一切進入網關的請求和微服務響應,與GatewayFilter的作用一樣。
區別在於GatewayFilter通過配置定義,處理邏輯是固定的。而GlobalFilter的邏輯需要自己寫代碼實現。
定義方式是實現GlobalFilter接口。
首先我們在Gateway模塊添加一個Java類
// @Order(-1)
@Component
public class AuthorizeFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
//1.獲取請求參數
ServerHttpRequest request = exchange.getRequest();
//2.獲取所有的參數
MultiValueMap<String, String> queryParams = request.getQueryParams();
//3.獲取Authorization參數
String first = queryParams.getFirst("Authorization");
//4.判斷參數是否是admin
if ("admin".equals(first)){
//5.是則放行
return chain.filter(exchange);
}
//6.設置狀態碼
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
//7.攔截請求
return exchange.getResponse().setComplete();
}
@Override
public int getOrder() {
return -1;
}
}
這個類的主要是作用是實現了GlobalFilter,對發送來的請求判斷Authorization參數是否為admin,如果是則放行,不是則設置狀態碼為401然後攔截請求
注意的是,這個攔截器需要用@Component注解給Spring托管
並且我們可以設置該攔截器的優先級(數字越小,優先級越大)
例如使用@Order(-1)設置優先級
也可以選擇實現Ordered接口的getOrder方法,返回一個數字,那個數字就是决定攔截器的優先級的
4.3 過濾器的執行順序
請求進入網關會碰到三類過濾器:當前路由的過濾器、DefaultFilter、GlobalFilter
請求路由後,會將當前路由過濾器和DefaultFilter、GlobalFilter,合並到一個過濾器鏈(集合)中,排序後依次執行每個過濾器
- 每一個過濾器都必須指定一個int類型的order值,order值越小,優先級越高,執行順序越靠前。
- GlobalFilter通過實現Ordered接口,或者添加@Order注解來指定order值,由我們自己指定
- 路由過濾器和defaultFilter的order由Spring指定,默認是按照聲明順序從1遞增。
- 當過濾器的order值一樣時,會按照 defaultFilter > 路由過濾器 > GlobalFilter的順序執行。
五、跨域問題解决
什麼是跨域問題呢?
在之前開發SpringBoot+vue的項目的時候,如果沒有進行跨域問題的解决,我用axios發送請求給後端就會報錯
這是因為前端和後端的端口號不一樣,瀏覽器禁止請求的發起者與服務端發生跨域ajax請求
所以跨域問題就是 瀏覽器禁止請求的發起者與服務端發生跨域ajax請求,請求被瀏覽器攔截的問題
除了端口不一樣會產生跨域問題之外,如果域名不一樣,也會導致跨域問題
解决方案:CORS
server:
port: 10010
spring:
application:
name: gateway #服務名稱
cloud:
nacos:
server-addr: localhost:8848 #nacos地址
gateway:
globalcors: # 全局的跨域處理
add-to-simple-url-handler-mapping: true # 解决options請求被攔截問題
corsConfigurations:
'[/**]':
allowedOrigins: # 允許哪些網站的跨域請求
- "http://127.0.0.1:5500"
- "http://www.leyou.com"
allowedMethods: # 允許的跨域ajax的請求方式
- "GET"
- "POST"
- "DELETE"
- "PUT"
- "OPTIONS"
allowedHeaders: "*" # 允許在請求中攜帶的頭信息
allowCredentials: true # 是否允許攜帶cookie
maxAge: 360000 # 這次跨域檢測的有效期
在gateway網關模塊中配置以上配置,即可解决跨域問題
边栏推荐
- C#,数值计算(Numerical Recipes in C#),线性代数方程的求解,Gauss-Jordan消去法,源代码
- DM8 uses different databases to archive and recover after multiple failures
- NewH3C——ACL
- Moher College phpmailer remote command execution vulnerability tracing
- 2022 gas examination registration and free gas examination questions
- Bishi blog (13) -- oral arithmetic test app
- FOC控制
- Four essential material websites for we media people to help you easily create popular models
- SQL statement view SQL Server 2005 version number
- Azure ad domain service (II) configure azure file share disk sharing for machines in the domain service
猜你喜欢
Common components of flask
What sparks can applet container technology collide with IOT
Bishi blog (13) -- oral arithmetic test app
1. Qt入门
Azure ad domain service (II) configure azure file share disk sharing for machines in the domain service
DM8 tablespace backup and recovery
What if the wireless network connection of the laptop is unavailable
【性能測試】一文讀懂Jmeter
ctfshow web255 web 256 web257
一文了解数据异常值检测方法
随机推荐
【Go基础】1 - Go Go Go
How to send pictures to the server in the form of file stream through the upload control of antd
09 softmax regression + loss function
Using the rate package for data mining
【性能测试】一文读懂Jmeter
Moher College phpmailer remote command execution vulnerability tracing
Mouse over to change the transparency of web page image
C # implements a queue in which everything can be sorted
The basic syntax of mermaid in typera
If the array values match each other, shuffle again - PHP
一文了解數據异常值檢測方法
没有Kubernetes怎么玩Dapr?
std::is_ union,std::is_ class,std::integral_ constant
Go zero micro service practical series (IX. ultimate optimization of seckill performance)
ES6 summary
Newh3c - routing protocol (RIP, OSPF)
A method for detecting outliers of data
[CV] Wu Enda machine learning course notes | Chapter 9
Use preg_ Match extracts the string into the array between: & | people PHP
AcWing 244. Enigmatic cow (tree array + binary search)