概述简介
官网
是什么
Cloud全家桶中有个很重要的组件就是网关,在1.x版本中都是采用的ZuuI网关;
但在2.x版本中,zuul的升级一直跳票, Spring Cloudi最后自己研发了一个网关替代Zuul
那就是 Spring Cloud Gateway一句话: gateway是原zuul1.x版的替代
概述
Gateway;是在 Spring生态系统之上构建的API网关服务,基于 Spring5, Spring Boot2和 Project Reactors等技术
Gateway旨在提珙一种简单而有效的方式来对API进行路由,以及提供一些虽大的过滤器功能,例如:熔断、限流、重试等
Spring Cloud Gateway 是 Spring Cloud 的一个全新项目,该项目是基于 Spring 5.0,Spring Boot 2.0 和 Project Reactor 等技术开发的网关,它旨在为微服务架构提供一种简单有效的统一的 API 路由管理方式。
Spring Cloud Gateway是基于Spring Boot 2.x, Spring WebFlux和Project Reactor 构建的。因此,在使用Spring Cloud Gateway时,许多不熟悉的同步库(例如,Spring Data和Spring Security)和模式可能不适用。如果您对这些项目不熟悉,建议您在使用Spring Cloud Gateway之前先阅读它们的文档,以熟悉一些新概念。
Spring Cloud Gateway需要Spring Boot和Spring Webflux提供的Netty运行时。它不能在传统的Servlet容器中或作为WAR构建。
Spring Cloud Gateway 作为 Spring Cloud 生态系统中的网关,目标是替代 Netflix Zuul,其不仅提供统一的路由方式,并且基于 Filter 链的方式提供了网关基本的功能,例如:安全,监控/指标,和限流。
一句话
Spring Cloud Gateway使用的 Webfluxt中的 reactor- netty响应式编程组件,底层使用了Nett通讯框架。
能干嘛
反向代理
鉴权
流量控制
熔断
日志监控
微服务架构中网关在哪里
企业架构
有Zuul了怎么又出来gateway
我们我什么选择gateway
neflix不太靠谱,zuul2.0-直跳票,迟迟不发布
一方面因为Zuul1.0已经进入了维护阶段,而且 Gateway是 Spring Cloude团队研发的,是亲儿子产品,值得信赖。
而且很多功能Zuul都没有用起来也非常的简单便捷
Gateway是基于异步非阻塞模型上进行开发的,性能方面不需要担心、虽然 Netflix早就发布了最新的Zuul2.x,但 Spring Cloud貌似没有整合计划。而且Netfix相关组件都宣布进入维护期;不知前景如何?
多方面综合考虑 Gateway是很理想的网关选择。
Spring Cloud Gateway具有如下特性
基于 Spring Framework5, Project Reactor和 Spring Boot2.0进行构建
动态路由:能够匹配任何请求属性;
可以对路由指定 Predicate(断言)和 Filter(过滤器);
集成 Hystrix的断路器功能;
集成 Spring Cloud服务发现功能;
易于编写的 Predicate(断言)和 Filter(过滤器);
请求限流功能;
支持路径重写。
Spring Cloud Gateway与zuul的区别
在 Spring Cloud Finchley正式版之前, Spring Cloud推荐的网关是 Netflix提供的Zuul:
1、Zuu1.x,是一个基于阻塞O的 API Gateway
2、Zuu1.x基于 Servlet2.5使用阻塞架构它不支持任何长连接(如 Websocket)Zuul的设计模式和 Nginx较像,每次IO操作都是从工作线程中选择一个执行,请求线程被阻塞到工作线程完成,但是差別是 Nginx用C++实现,Zuul用Java实现,而JVM本身会有第1次加载较慢的情况,使得Zuul的性能相对较差。
3、Zuul2.x理念更先进,想基于Netty非阻塞和支持长连接,但 Spring Cloud目前还没有整合。Zuu2.x的性能较Zuul1.x有较大提升。在性能方面,根据官方提供的基准测试, Spring Cloud Gateway的RPS(每秒请求数)是Zull的1.6倍。
4、 Spring Cloud Gateway建立在 Spring Framework5、 Project Reactor和 Spring Boot2之上,使用非阻塞API.
5、 Spring Cloud Gateway还支持 Websocket,并且与 Spring紧密集成拥有更好的开发体验
zuul模型
Springcloud中所集成的zuul版本,采用的是Tomcat容器,使用的是传统的 Servlet IO处理模型
学过尚硅谷web中期课程都知道一个题目,Servlet的生命周期? servlet由 servlet container进行生命周期管理
- container启动时构造 servlet对象并调用 servlet init进行初始化;
- container运行时接受请求,并为每个请求分配个线程(一般从线程池中获取空闲线程)然后调用 service()
- container关闭时调用 servlet destory0销毁 servlet;
上述模式的缺点:
servlet是一个简单的网络IO模型,当请求进入 servlet container时, servlet container就会为其绑定一个线程,在并发不高的场景下这种模型是适用的。但是一旦高并发(比如抽风用 jemeter压测),线程数量就会上涨,而线程资源代价是昂贵的(上下文切换,内存消耗大)严重影响请求的处理时间。
在一些简单业务场景下,不希望为每个 request分配个线程,只需要1个或几个线程就能应对极大并发的请求,这种业务场景下 servlet模型没有优势
所以zuul1.X是基于 servlet之上的一个阻塞式处理模型,即 spring实现了处理所有 request请求的一个 servlet( Dispatcherservlet)并由该 servlet阻塞式处理处理。所以 Springcloud Zuul无法摆脱 servlet模型的弊端
gateway模型
传统的Web框架,比如说: struts2, springmvc等都是基于 Servlet API与 Servlet容器基础之上运行的。
但是
在 Servlet3.1之后有了异步非阻塞的支持。而 Webflux是一个典型非阻塞异步的框架,它的核心是基于 Reactor的相关API实现的。相对于传统的web框架来说,它可以运行在诸如 Netty, Undertow及支持 Servlet3.1的容器上。非阻塞式+函数式编程( Spring5必须让你使用Java8)
Spring Webflux是 Spring5.0引入的新的响应式框架,区別于 Spring MVC,它不需要依赖 Servlet API,它是完全异步非阻塞的,并且基于 Reactor来实现响应式流规范。
三大核心概念
Route(路由):这是网关的基本构建块。它由一个 ID,一个目标 URI,一组断言和一组过滤器定义。如果断言为真,则路由匹配。
Predicate(断言):这是一个 Java 8 的 Predicate。输入类型是一个 ServerWebExchange。我们可以使用它来匹配来自 HTTP 请求的任何内容,例如 headers 或参数。
Filter(过滤器):这是org.springframework.cloud.gateway.filter.GatewayFilter的实例,我们可以使用它修改请求和响应。
web请求,通过一些匹配条件,定位到真正的服务节点。并在这个转发过程的前后,进行一些精细化控制
predicate就是我们的匹配条件;而 filter,就可以理解为一个无所不能的拦截器。有了这两个元素,再加上目标uri,就可以实现一个具体的路由了
GateWay工作流程
客户端向 Spring Cloud Gateway 发出请求。如果 Gateway Handler Mapping 中找到与请求相匹配的路由,将其发送到 Gateway Web Handler。Handler 再通过指定的过滤器链来将请求发送到我们实际的服务执行业务逻辑,然后返回。 过滤器之间用虚线分开是因为过滤器可能会在发送代理请求之前(“pre”)或之后(“post”)执行业务逻辑。
Filter在”pre”类型的过滤器可以做参数校验、权限校验、流量监控、日志输出、协议转换等,
在”post”类型的过滤器中可以做响应内容、响应头的修改,日志的输出,流量监控等有着非常重要的作用
Spring Cloud Gateway 的特征:
1. 基于 Spring Framework 5,Project Reactor 和 Spring Boot 0
2. 动态路由
3. Predicates 和 Filters 作用于特定路由
4. 集成 Hystrix 断路器
5. 集成 Spring Cloud DiscoveryClient
6. 易于编写的 Predicates 和 Filters
7. 限流
8. 路径重写
核心逻辑:路由转发+执行过滤链
GateWay9527搭建
创建cloud-gateway-gateway9527
- 创建module
- 改pom
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>false</optional>
</dependency>
<!--eureka client-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-gateway -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
注意,这里有个坑,spring cloud gateway使用的web框架为webflux,和springMVC不兼容。所以不要引入(修正:只有gateway服务不用引入springMVC,其他需要引入)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
- 改yml
server:
port: 9527
spring:
application:
name: cloud-gateway
eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url:
# defaultZone: http://eureka7002.com:7002/eureka,http://eureka7001.com:7001/eureka/ #集群版
defaultZone: http://eureka7001.com:7001/eureka/
instance:
instance-id: gateway9527
prefer-ip-address: true #访问路径可以显示ip地址
# Eureka客户端向服务端发送心跳的时间间隔,单位为秒(默认是30秒)
lease-renewal-interval-in-seconds: 1
#Eureka服务端在收到最后一次心跳后等待时间上限,单位为秒(默认是90秒),超时将剔除服务
lease-expiration-duration-in-seconds: 2
- 业务类(只做网关,没有业务类)
- 主启动类
@SpringBootApplication
@EnableEurekaClient
public class GateWayMain9527 {
public static void main(String[] args) {
SpringApplication.run(GateWayMain9527.class,args);
}
}
GateWay9527如何做路由映射的
看看cloud-provider-hystrix-payment8090的controller访问地址
我们目前不想暴露8090端口,希望8090外面套一层9527
YML新增网关配置
spring:
application:
name: cloud-gateway
cloud:
gateway:
routes:
- id: payment_routh #payment_routh #路由的ID,没有固定规则但要求唯一,简易配合服务名
uri: http://localhost:8090 #匹配后提供服务的路由地址
predicates:
- Path=/payment/circuit/breaker/** #断言,路径相匹配的进行路由
- id: payment_routh2 #payment_routh #路由的ID,没有固定规则但要求唯一,简易配合服务名
uri: http://localhost:8090 #匹配后提供服务的路由地址
predicates:
- Path=/payment/hystrix/timeout/** #断言,路径相匹配的进行路由
测试
添加网关前访问:http://localhost:8090/payment/circuit/breaker/31
添加网关后访问:http://localhost:9527/payment/circuit/breaker/31
GateWay配置路由的两种方式
- 在配置文件中进行配置
- 代码注入的方式配置RouteLocator的Bean
业务需求:通过9527访问外网http://news.baidu.com/guonei
@Configuration
public class GateWayConfig {
@Bean
public RouteLocator customizeRouteLocator(RouteLocatorBuilder routeLocatorBuilder) {
RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();
// http://news.baidu.com/guonei
routes.route("payment-router1",r -> r.path("/guonei").uri("http://news.baidu.com")).build();
return routes.build();
}
}
浏览器访问:http://127.0.0.1:9527/guonei
GateWay配置动态路由
默认情況下 Gateway会根据洼册中心注册的服务列表,
以注册中心上微服务名为路径创建动态路由进行转发,从而实现动态路由的功能
pom
<!--eureka client-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-gateway -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
yml
server:
port: 9527
spring:
application:
name: cloud-gateway
cloud:
gateway:
discovery:
locator:
enabled: true # 开启从注册中心动态创建路由的功能,利用微服务名进行路由
routes:
- id: payment_routh #payment_routh #路由的ID,没有固定规则但要求唯一,简易配合服务名
# uri: http://localhost:8090 #匹配后提供服务的路由地址
uri: lb://cloud-payment-server #匹配后提供服务的路由地址
predicates:
- Path=/payment/save #断言,路径相匹配的进行路由
- id: payment_routh2 #payment_routh #路由的ID,没有固定规则但要求唯一,简易配合服务名
# uri: http://localhost:8090 #匹配后提供服务的路由地址
uri: lb://cloud-payment-server #匹配后提供服务的路由地址
predicates:
- Path=/payment/find/** #断言,路径相匹配的进行路由
eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url:
# defaultZone: http://eureka7002.com:7002/eureka,http://eureka7001.com:7001/eureka/ #集群版
defaultZone: http://eureka7001.com:7001/eureka/
instance:
instance-id: gateway9527
prefer-ip-address: true #访问路径可以显示ip地址
# Eureka客户端向服务端发送心跳的时间间隔,单位为秒(默认是30秒)
lease-renewal-interval-in-seconds: 1
#Eureka服务端在收到最后一次心跳后等待时间上限,单位为秒(默认是90秒),超时将剔除服务
lease-expiration-duration-in-seconds: 2
主启动类
@SpringBootApplication
@EnableEurekaClient
public class GateWayMain9527 {
public static void main(String[] args) {
SpringApplication.run(GateWayMain9527.class,args);
}
}
启动并测试
启动eurka服务注册中心,然后启动8090和8091服务提供者微服务
浏览器访问: http://localhost:9527/payment/find/31
可以看到轮训调用 8090 和 8091
predicate的使用
Route Predicate Factories这个是什么东东?
Spring Cloud Gateway将路由匹配作为 Spring Webflux HandlerMapping基础架构的一部分。
Spring Cloud Gateway包括许多内置的 Route Predicate工厂。所有这些 Predicate都与HTP请求的不同属性匹配。多个 Route
Predicate工厂可以进行组合
Spring Cloud Gateway创建 Route对象时,使用 Route Predicatefactory创建 Predicate对象, Predicate对象可以赋值给
Route
Spring Cloud Gateway包含许多内置的 Route Predicate Factories
所有这些谓词都匹配HTTP请求的不同属性。多种谓词工厂可以组合,并通过逻辑and。
ZonedDateTime获取时区
public class Test {
public static void main(String[] args) {
ZonedDateTime zonedDateTime = ZonedDateTime.now(); // 默认时区
// zonedDateTime = 2020-07-25T07:56:07.582+08:00[Asia/Shanghai]
System.out.println("zonedDateTime = " + zonedDateTime);
}
}
常用predicate
After Route Predicate
如图是官网的使用说明,但是这个时间串串该如何获取呢?
yml配置
spring:
application:
name: cloud-gateway
cloud:
gateway:
discovery:
locator:
enabled: true # 开启从注册中心动态创建路由的功能,利用微服务名进行路由
routes:
- id: payment_routh2 #payment_routh #路由的ID,没有固定规则但要求唯一,简易配合服务名
# uri: http://localhost:8090 #匹配后提供服务的路由地址
uri: lb://cloud-payment-server #匹配后提供服务的路由地址
predicates:
- Path=/payment/find/** #断言,路径相匹配的进行路由
- After=2020-07-25T08:00:07.582+08:00[Asia/Shanghai]
没有达到指定时间就访问,会出现如下界面
Before Route Predicate
Before:请求必须在指定时间之前访问
spring:
application:
name: cloud-gateway
cloud:
gateway:
discovery:
locator:
enabled: true # 开启从注册中心动态创建路由的功能,利用微服务名进行路由
routes:
- id: payment_routh #payment_routh #路由的ID,没有固定规则但要求唯一,简易配合服务名
# uri: http://localhost:8090 #匹配后提供服务的路由地址
uri: lb://cloud-payment-server #匹配后提供服务的路由地址
predicates:
- Path=/payment/save #断言,路径相匹配的进行路由
- After=2020-07-25T08:00:07.582+08:00[Asia/Shanghai]
- id: payment_routh2 #payment_routh #路由的ID,没有固定规则但要求唯一,简易配合服务名
# uri: http://localhost:8090 #匹配后提供服务的路由地址
uri: lb://cloud-payment-server #匹配后提供服务的路由地址
predicates:
- Path=/payment/find/** #断言,路径相匹配的进行路由
- After=2020-07-25T08:00:07.582+08:00[Asia/Shanghai] # 请求必须在指定时间之后访问
- Before=2020-07-25T09:07:04.582+08:00[Asia/Shanghai] # 请求必须在指定时间之前访问
Between Route Predicate
Between :2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver]
表示在 2017-01-20 17:42:47.789 时间之后 2017-01-21 17:42:47.789之前,请求有效
spring:
application:
name: cloud-gateway
cloud:
gateway:
discovery:
locator:
enabled: true # 开启从注册中心动态创建路由的功能,利用微服务名进行路由
routes:
- id: payment_routh2 #payment_routh #路由的ID,没有固定规则但要求唯一,简易配合服务名
# uri: http://localhost:8090 #匹配后提供服务的路由地址
uri: lb://cloud-payment-server #匹配后提供服务的路由地址
predicates:
- Path=/payment/find/** #断言,路径相匹配的进行路由
# - After=2020-07-25T08:00:07.582+08:00[Asia/Shanghai] # 请求必须在指定时间之后访问
- Between=2020-07-25T08:00:07.582+08:00[Asia/Shanghai],2020-07-25T09:55:04.582+08:00[Asia/Shanghai] # 在该时间段内请求有效
Cookie Route Predicate
yml配置
spring:
application:
name: cloud-gateway
cloud:
gateway:
discovery:
locator:
enabled: true # 开启从注册中心动态创建路由的功能,利用微服务名进行路由
routes:
- id: payment_routh #payment_routh #路由的ID,没有固定规则但要求唯一,简易配合服务名
# uri: http://localhost:8090 #匹配后提供服务的路由地址
uri: lb://cloud-payment-server #匹配后提供服务的路由地址
predicates:
- Path=/payment/save #断言,路径相匹配的进行路由
- After=2020-07-25T08:00:07.582+08:00[Asia/Shanghai]
- id: payment_routh2 #payment_routh #路由的ID,没有固定规则但要求唯一,简易配合服务名
# uri: http://localhost:8090 #匹配后提供服务的路由地址
uri: lb://cloud-payment-server #匹配后提供服务的路由地址
predicates:
- Path=/payment/find/** #断言,路径相匹配的进行路由
# - After=2020-07-25T08:00:07.582+08:00[Asia/Shanghai] # 请求必须在指定时间之后访问
- Between=2020-07-25T08:00:07.582+08:00[Asia/Shanghai],2020-07-25T09:55:04.582+08:00[Asia/Shanghai] # 在该时间段内请求有效
- Cookie=username,zhangshan # 请求必须携带Cookie并且k = username,v = zhangshan
Cookie Route Predicate需要两个参数,一个是 Cookie name,个是正则表达式(也可以为确定的值)
路由规则会通过获取对应的 Cookie name值和正则表达式去匹配,如果匹配上就会执行路由,如果没有匹配上则不执行
使用curl命令,发送不带cookie的请求curl http://localhost/payment/find/31
使用curl命令,发送带cookie的请求curl http://localhost/payment/find/31 --cookie "username=zhangshan"
Header Route Predicate
两个参数:一个是属性名称和一个正则表达式,这个属性值和正则表达式匹配则执行
yml配置文件
spring:
application:
name: cloud-gateway
cloud:
gateway:
discovery:
locator:
enabled: true # 开启从注册中心动态创建路由的功能,利用微服务名进行路由
routes:
- id: payment_routh #payment_routh #路由的ID,没有固定规则但要求唯一,简易配合服务名
# uri: http://localhost:8090 #匹配后提供服务的路由地址
uri: lb://cloud-payment-server #匹配后提供服务的路由地址
predicates:
- Path=/payment/save #断言,路径相匹配的进行路由
- After=2020-07-25T08:00:07.582+08:00[Asia/Shanghai]
- id: payment_routh2 #payment_routh #路由的ID,没有固定规则但要求唯一,简易配合服务名
# uri: http://localhost:8090 #匹配后提供服务的路由地址
uri: lb://cloud-payment-server #匹配后提供服务的路由地址
predicates:
- Path=/payment/find/** #断言,路径相匹配的进行路由
# - After=2020-07-25T08:00:07.582+08:00[Asia/Shanghai] # 请求必须在指定时间之后访问
- Between=2020-07-25T08:00:07.582+08:00[Asia/Shanghai],2020-07-25T12:55:04.582+08:00[Asia/Shanghai] # 在该时间段内请求有效
# - Cookie=username,zhangshan
- Header=X-Request-Id, \d+ # 请求头中要有X-Request-Id并且值为整数的正则表达式
使用curl请求,网关curl http://localhost/payment/find/31 -H "X-Request-Id:123"
Host Route Predicate
Host Route Predicate接收一组参数,一组匹配的域名列表,这个模板是一个ant分隔的模板,用 , 号作为分隔符。
它通过参数中的主机地址作为匹配规则。
yml配置文件
spring:
application:
name: cloud-gateway
cloud:
gateway:
discovery:
locator:
enabled: true # 开启从注册中心动态创建路由的功能,利用微服务名进行路由
routes:
- id: payment_routh #payment_routh #路由的ID,没有固定规则但要求唯一,简易配合服务名
# uri: http://localhost:8090 #匹配后提供服务的路由地址
uri: lb://cloud-payment-server #匹配后提供服务的路由地址
predicates:
- Path=/payment/save #断言,路径相匹配的进行路由
- After=2020-07-25T08:00:07.582+08:00[Asia/Shanghai]
- id: payment_routh2 #payment_routh #路由的ID,没有固定规则但要求唯一,简易配合服务名
# uri: http://localhost:8090 #匹配后提供服务的路由地址
uri: lb://cloud-payment-server #匹配后提供服务的路由地址
predicates:
- Path=/payment/find/** #断言,路径相匹配的进行路由
# - After=2020-07-25T08:00:07.582+08:00[Asia/Shanghai] # 请求必须在指定时间之后访问
- Between=2020-07-25T08:00:07.582+08:00[Asia/Shanghai],2020-07-25T12:55:04.582+08:00[Asia/Shanghai] # 在该时间段内请求有效
# - Cookie=username,zhangshan
# - Header=X-Request-Id, \d+ # 请求头中要有X-Request-Id并且值为整数的正则表达式
- Host=**.sgy.com
使用curl请求:curl http://localhost/payment/find/31 -H "Host:www.sgy.com"
Method Route Predicate
指定请求方式
spring:
application:
name: cloud-gateway
cloud:
gateway:
discovery:
locator:
enabled: true # 开启从注册中心动态创建路由的功能,利用微服务名进行路由
routes:
- id: payment_routh #payment_routh #路由的ID,没有固定规则但要求唯一,简易配合服务名
# uri: http://localhost:8090 #匹配后提供服务的路由地址
uri: lb://cloud-payment-server #匹配后提供服务的路由地址
predicates:
- Path=/payment/save #断言,路径相匹配的进行路由
- After=2020-07-25T08:00:07.582+08:00[Asia/Shanghai]
- id: payment_routh2 #payment_routh #路由的ID,没有固定规则但要求唯一,简易配合服务名
# uri: http://localhost:8090 #匹配后提供服务的路由地址
uri: lb://cloud-payment-server #匹配后提供服务的路由地址
predicates:
- Path=/payment/find/** #断言,路径相匹配的进行路由
# - After=2020-07-25T08:00:07.582+08:00[Asia/Shanghai] # 请求必须在指定时间之后访问
- Between=2020-07-25T08:00:07.582+08:00[Asia/Shanghai],2020-07-25T12:55:04.582+08:00[Asia/Shanghai] # 在该时间段内请求有效
# - Cookie=username,zhangshan
# - Header=X-Request-Id, \d+ # 请求头中要有X-Request-Id并且值为整数的正则表达式
- Host=**.sgy.com
- Method=GET
Path Route Predicate
predicates:
- Path=/payment/find/** #断言,路径相匹配的进行路由
Query Route Predicate
yml配置文件
spring:
application:
name: cloud-gateway
cloud:
gateway:
discovery:
locator:
enabled: true # 开启从注册中心动态创建路由的功能,利用微服务名进行路由
routes:
- id: payment_routh #payment_routh #路由的ID,没有固定规则但要求唯一,简易配合服务名
# uri: http://localhost:8090 #匹配后提供服务的路由地址
uri: lb://cloud-payment-server #匹配后提供服务的路由地址
predicates:
- Path=/payment/save #断言,路径相匹配的进行路由
- After=2020-07-25T08:00:07.582+08:00[Asia/Shanghai]
- id: payment_routh2 #payment_routh #路由的ID,没有固定规则但要求唯一,简易配合服务名
# uri: http://localhost:8090 #匹配后提供服务的路由地址
uri: lb://cloud-payment-server #匹配后提供服务的路由地址
predicates:
- Path=/payment/find/** #断言,路径相匹配的进行路由
# - After=2020-07-25T08:00:07.582+08:00[Asia/Shanghai] # 请求必须在指定时间之后访问
- Between=2020-07-25T08:00:07.582+08:00[Asia/Shanghai],2020-07-25T12:55:04.582+08:00[Asia/Shanghai] # 在该时间段内请求有效
# - Cookie=username,zhangshan
# - Header=X-Request-Id, \d+ # 请求头中要有X-Request-Id并且值为整数的正则表达式
# - Host=**.sgy.com
- Method=GET
- Query=id, \d+ # 要有参数名为id,且值为整数
curl http://localhost/payment/find/31?id=1231
总结
说白了,Predicate就是为了实现一组匹配规则,让请求过来找到对应的Route进行处理
spring:
application:
name: cloud-gateway
cloud:
gateway:
discovery:
locator:
enabled: true # 开启从注册中心动态创建路由的功能,利用微服务名进行路由
routes:
- id: payment_routh #payment_routh #路由的ID,没有固定规则但要求唯一,简易配合服务名
# uri: http://localhost:8090 #匹配后提供服务的路由地址
uri: lb://cloud-payment-server #匹配后提供服务的路由地址
predicates:
- Path=/payment/save #断言,路径相匹配的进行路由
- After=2020-07-25T08:00:07.582+08:00[Asia/Shanghai]
- id: payment_routh2 #payment_routh #路由的ID,没有固定规则但要求唯一,简易配合服务名
# uri: http://localhost:8090 #匹配后提供服务的路由地址
uri: lb://cloud-payment-server #匹配后提供服务的路由地址
predicates:
- Path=/payment/find/** #断言,路径相匹配的进行路由
# - After=2020-07-25T08:00:07.582+08:00[Asia/Shanghai] # 请求必须在指定时间之后访问
- Between=2020-07-25T08:00:07.582+08:00[Asia/Shanghai],2020-07-25T12:55:04.582+08:00[Asia/Shanghai] # 在该时间段内请求有效
# - Cookie=username,zhangshan
# - Header=X-Request-Id, \d+ # 请求头中要有X-Request-Id并且值为整数的正则表达式
# - Host=**.sgy.com
- Method=GET
- Query=id, \d+ # 要有参数名为id,且值为整数
GateWay的Filter
生命周期,Only Two
pre:在业务逻辑之前
post:在业务逻辑之后
种类,Only Two
GatewayFilter:单一
GlobalFilter:全局
常用的GateWay Filter
AddRequestParameter:
yml配置文件
spring:
application:
name: cloud-gateway
cloud:
gateway:
discovery:
locator:
enabled: true # 开启从注册中心动态创建路由的功能,利用微服务名进行路由
routes:
- id: payment_routh #payment_routh #路由的ID,没有固定规则但要求唯一,简易配合服务名
# uri: http://localhost:8090 #匹配后提供服务的路由地址
uri: lb://cloud-payment-server #匹配后提供服务的路由地址
predicates:
- Path=/payment/save #断言,路径相匹配的进行路由
- After=2020-07-25T08:00:07.582+08:00[Asia/Shanghai]
- id: payment_routh2 #payment_routh #路由的ID,没有固定规则但要求唯一,简易配合服务名
# uri: http://localhost:8090 #匹配后提供服务的路由地址
uri: lb://cloud-payment-server #匹配后提供服务的路由地址
predicates:
- Path=/payment/find/** #断言,路径相匹配的进行路由
# - After=2020-07-25T08:00:07.582+08:00[Asia/Shanghai] # 请求必须在指定时间之后访问
- Between=2020-07-25T08:00:07.582+08:00[Asia/Shanghai],2020-07-25T12:55:04.582+08:00[Asia/Shanghai] # 在该时间段内请求有效
# - Cookie=username,zhangshan
# - Header=X-Request-Id, \d+ # 请求头中要有X-Request-Id并且值为整数的正则表达式
# - Host=**.sgy.com
- Method=GET
- Query=id, \d+ # 要有参数名为id,且值为整数
filters:
- AddRequestHeader=X-Request-red, blue # 过滤器会在匹配的请求头中加入一对请求头,名称为X-Request-red,值为blue
自定义过滤器(全局GlobalFilter)
要实现两个主要接口
impiemerts GlobalFilter ,Ordered
能干嘛
全局日志记录
统一网关鉴权
。。。。
案例代码
package com.sgy.springcloud.filter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.net.URI;
/**
* 全局过滤器
* Created by AaronShen on 2020/7/25
*/
@Component
public class GateWayFilter implements GlobalFilter, Ordered {
private static final Logger log = LoggerFactory.getLogger(GateWayFilter.class);
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
log.info("******* come in GateWayFilter");
String username = exchange.getRequest().getQueryParams().getFirst("username");
String uri = exchange.getRequest().getURI().toString();
log.info("请求url : {}",uri);
if (username == null || username.equals("")) {
log.info("********** 非法参数");
exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
// 响应
return exchange.getResponse().setComplete();
}
// 执行下一个过滤器
return chain.filter(exchange);
}
/**
* 过滤器执行顺序,越小越靠前
* @return
*/
@Override
public int getOrder() {
return 0;
}
}