1.什么是服務網關
1.說明
-
網關統一服務入口,可方便實作對平臺眾多服務介面進行管控,對訪問服務的身份認證、防報文重放與防資料篡改、功能呼叫的業務鑒權、回應資料的脫敏、流量與并發控制,甚至基于API呼叫的計量或者計費等等,
-
網關 = 路由轉發 + 過濾器
路由轉發:接收一切外界請求,轉發到后端的微服務上去;在服務網關中可以完成一系列的橫切功能,例如權限校驗、限流以及監控等,這些都可以通過過濾器完成
2.為什么需要網關
- 1.網關可以實作服務的統一管理
- 2.網關可以解決微服務中通用代碼的冗余問題(如權限控制,流量監控,限流等)
3.網關組件在微服務中架構

2.服務網關組件
1.zuul
Zuul is the front door for all requests from devices and web sites to the backend of the Netflix streaming application. As an edge service application, Zuul is built to enable dynamic routing, monitoring, resiliency and security.
-
原文翻譯
- https://github.com/Netflix/zuul/wiki
- zul是從設備和網站到Netflix流媒體應用程式后端的所有請求的前門,作為一個邊緣服務應用程式,zul被構建為支持動態路由、監視、彈性和安全性,
-
zuul版本說明
- 目前zuul組件已經從1.0更新到2.0,但是作為springcloud官方不再推薦使用zuul2.0,但是依然支持zuul2.
-
springcloud 官方集成zuul檔案
- https://cloud.spring.io/spring-cloud-netflix/2.2.x/reference/html/#netflix-zuul-starter
2.gateway
This project provides a library for building an API Gateway on top of Spring MVC. Spring Cloud Gateway aims to provide a simple, yet effective way to route to APIs and provide cross cutting concerns to them such as: security, monitoring/metrics, and resiliency.
-
原文翻譯
- https://spring.io/projects/spring-cloud-gateway
- 這個專案提供了一個在springmvc之上構建API網關的庫,springcloudgateway旨在提供一種簡單而有效的方法來路由到api,并為api提供橫切關注點,比如:安全性、監控/度量和彈性,
-
特性
- 基于springboot2.x 和 spring webFlux 和 Reactor 構建 回應式異步非阻塞IO模型
- 動態路由
- 請求過濾
創建一個新的專案,根據之前寫的環境搭建方式
3.開發網關動態路由
- 網關配置有兩種方式一種是快捷方式,一種是完全展開方式
1.創建專案引入網關依賴
<!--引入gateway網關依賴-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
完整的pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.md</groupId>
<artifactId>05-gateway8989</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>05-gateway8989</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.SR6</spring-cloud.version>
</properties>
<dependencies>
<!--使用網關的時候web包需要移除掉-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--引入gateway網關依賴-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!--引入consul依賴-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
<!-- 這個包是用做健康度監控的-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
<!--全域管理springcloud版本,并不會引入具體依賴-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
快捷方式配置路由
2.撰寫網關配置
spring:
application:
name: gateway
cloud:
consul:
host: localhost
port: 8500
discovery:
service-name: ${spring.application.name}
gateway:
routes:
- id: user_route # 指定路由的唯一標識
uri: http://localhost:9999/ # 指定路由服務的地址
predicates: # 指定路由的規則
- Path=/user/**
- id: product_route
uri: http://localhost:9998/
predicates:
- Path=/product/**
server:
port: 8989
3.啟動gateway網關專案
-
直接啟動報錯:

-
在啟動日志中發現,gateway為了效率使用webflux進行異步非阻塞模型的實作,因此和原來的web包沖突,去掉原來的web即可

- 再次啟動成功啟動

4.測驗網關路由轉發
使用之前寫的寫的,可以看前面幾篇文章
- 測驗通過網關訪問用戶服務: http://localhost:8989/user/findOne?productId=10001
- 測驗通過網關訪問商品服務: http://localhost:8989/product/findOne?productId=10002

java方式配置路由(了解)
環境還是和上面的一樣
@Configuration
public class GatewayConfig {
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route("order_route", r -> r.path("/order/**")
.uri("http://localhost:9997/"))
.build();
}
}
4.查看網關路由規則串列
1.說明
- gateway提供路由訪問規則串列的web界面,但是默認是關閉的,如果想要查看服務路由規則可以在組態檔中開啟
management:
endpoints:
web:
exposure:
include: "*" #開啟所有web端點暴露
訪問路由管理串列地址
- http://localhost:8989/actuator/gateway/routes

3.配置路由服務負載均衡
1.說明
- 現有路由配置方式,都是基于服務地址寫死的路由轉發,能不能根據服務名稱進行路由轉發同時實作負載均衡的呢?
2.動態路由以及負載均衡轉發配置
spring:
application:
name: gateway
cloud:
consul:
host: localhost
port: 8500
discovery:
service-name: ${spring.application.name}
gateway:
routes:
- id: user_route # 指定路由的唯一標識
# uri: http://localhost:9999/ # 指定路由服務的地址
# lb代表轉發后臺服務使用負載均衡,users代表服務注冊中心上的服務名
uri: lb://users
predicates: # 指定路由的規則
- Path=/user/**
- id: product_route
# uri: http://localhost:9998/
# lb代表負載均衡轉發路由,products代表服務注冊中心上的服務名
uri: lb://products
predicates:
- Path=/product/**
# 開啟根據服務名動態獲取路由地址
discovery:
locator:
enabled: true
server:
port: 8989
#開啟所有web端點暴露
management:
endpoints:
web:
exposure:
include: "*"

此時訪問就實作了負載均衡的效果
4.常用路由predicate(斷言,驗證)
1.Gateway支持多種方式的predicate

After、Before、Between用于商城活動的時候指定日期才能訪問
-
After=2020-12-21T11:33:33.993+08:00[Asia/Shanghai] `指定日期之后的請求進行路由
-
Before=2020-12-21T11:33:33.993+08:00[Asia/Shanghai] `指定日期之前的請求進行路由
-
Between=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver]
-
Cookie=username,pony `基于指定cookie的請求進行路由
-
Cookie=username,[A-Za-z0-9]+
基于指定cookie的請求進行路由curl http://localhost:8989/user/findAll --cookie "username=zhangsan" -
Header=X-Request-Id, \d+ ``基于請求頭中的指定屬性的正則匹配路由(這里全是整數)
`curl http://localhost:8989/user/findAll -H "X-Request-Id:11" -
Method=GET,POST `基于指定的請求方式請求進行路由
-
官方更多: https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.3.RELEASE/reference/html/#the-cookie-route-predicate-factory
2.使用predicate
spring:
application:
name: gateway
cloud:
consul:
host: localhost
port: 8500
gateway:
routes:
- id: user_route
#uri: http://localhost:9999/
uri: lb://users
predicates:
- Path=/user/**
- After=2020-12-21T11:39:33.993+08:00[Asia/Shanghai]
- Cookie=username,[A-Za-z0-9]+
- Header=X-Request-Id, \d+

5.常用的Filter以及自定義filter
-
官網:
https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.3.RELEASE/reference/html/#gatewayfilter-factories -
路由過濾器允許以某種方式修改傳入的HTTP請求或傳出的HTTP回應,路由篩選器的作用域是特定路由,springcloudgateway包括許多內置的GatewayFilter工廠,
1.作用
- 當我們有很多個服務時,比如下圖中的user-service、order-service、product-service等服務,客戶端請求各個服務的Api時,每個服務都需要做相同的事情,比如鑒權、限流、日志輸出等,


2.使用內置過濾器

-
更多參加官網:https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.3.RELEASE/reference/html/#gatewayfilter-factories
-
使用方式如下:
spring:
application:
name: gateway
cloud:
gateway:
routes:
- id: product_route
#uri: http://localhost:9998/
uri: lb://products # lb: 使用負載均衡策略 products代表注冊中心的具體服務名
predicates:
- Path=/product/**
#- After=2020-07-30T09:45:49.078+08:00[Asia/Shanghai]
filters:
# 為每個請求添加引數id=12
- AddRequestParameter=id,12
# 增加回應頭
- AddResponseHeader=username,chenyn
3.使用自定義filter
@Configuration
@Slf4j
public class CustomGlobalFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
log.info("進入自定義的filter");
if(exchange.getRequest().getQueryParams().get("username")!=null){
log.info("用戶身份資訊合法,放行請求繼續執行!!!");
return chain.filter(exchange);
}
log.info("非法用戶,拒絕訪問!!!");
return exchange.getResponse().setComplete();
}
@Override
public int getOrder() { //filter 數字越小filter越先執行
return -1; //-1 最先執行
}
}
自定義全域filter

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/235269.html
標籤:其他
上一篇:田忌賽馬 貪心演算法
