Gateway是什么?
springCloud GateWay是基于WebFlux框架实现的,底层是Netty。
SpringCloud GatewWay提供统一路由方式 基于Filter的方式提供了网关的基本功能。例如安全,性能,监控等。
Zuul是基于Sevelet2.5阻塞模型,GateWay是非阻塞模型
属于spring家族,能更好的与springCloud进行整合
路由三大核心概念 路由 断言 过滤器
路由 由id 目标url 一系列断言和过滤器组成,断言为true则路由匹配
断言 开发人员可以匹配HTTP请求中的所有内容(请求头,请求参数等),断言匹配则进行路由
过滤器 指的是spring框架中GateWayFilter实例,可以在请求路由之前或者之后队请求进行修改
过滤器 preFilter可以做参数校验 流量控制 权限校验 日志输出 协议转换等
postFilter可以做响应内容,响应头的修改,流量监控等
下面进入编码
新建 CloudGateWay9527模块
POM
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>cloud2021</artifactId> <groupId>com.liuxu</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>cloud-gateway-9527</artifactId> <dependencies> <!--引入comm工程--> <dependency> <groupId>com.liuxu</groupId> <artifactId>cloud-commons</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <!--eurekaClient--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency> <!--<!–springboot 必须有的 –> gateWay项目 不需要引入web相关 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!–图像化显示相关–> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>--> <!--热启动--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> </dependency> </dependencies> </project>
主启动类
package com.liuxu; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; /** * @author liuxu * @date 2021/11/1 21:31 */ @EnableEurekaClient @EnableDiscoveryClient @SpringBootApplication public class GateWay9527 { public static void main(String[] args) { SpringApplication.run(GateWay9527.class,args); } }
配置yml
server: port: 9527 #端口号 spring: application: name: cloud-gateway #服务名 cloud: gateway: routes: - id: payment_routh #不指定,但是要求唯一 uri: http://localhost:8001 #匹配后提供服务的地址 predicates: - Path=/provider/** 断言 以/provider/开头的请求路径的所有请求 eureka: client: # 是否从Eureka抓取注册信息 单节点情况下无用 集群情况下才能配合robbion使用负载均衡 fetch-registry: true # 注册如Eureka 用 true register-with-eureka: true service-url: # 设置与eureka server交互的地址查询和注册服务都需要这个地址 向注册中心注册 defaultZone: http://localhost:7001/eureka/
启动注册中心 7001 网关 9527 服务提供方 8001
访问http://localhost:9527/provider/ok
可以通过网关访问到8001
上面是通过网关访问8001 的真实地址
还可以通过服务名进行动态路由
在启动服务提供方8002
配置开启动态路由
server: port: 9527 #端口号 spring: application: name: cloud-gateway #服务名 cloud: gateway: discovery: locator: enabled: true # 开启动态路由 routes: - id: payment_routh1 #不指定,但是要求唯一 uri: http://localhost:8001 #匹配后提供服务的地址 固定路由 predicates: - Path=/provider/** - id: payment_routh2 #不指定,但是要求唯一 uri: lb://cloud-provider #匹配后提供服务的地址 动态路由 predicates: - Path=/provider/** eureka: client: # 是否从Eureka抓取注册信息 单节点情况下无用 集群情况下才能配合robbion使用负载均衡 fetch-registry: true # 注册如Eureka 用 true register-with-eureka: true service-url: # 设置与eureka server交互的地址查询和注册服务都需要这个地址 向注册中心注册 defaultZone: http://localhost:7001/eureka/
重启9527
发现访问http://localhost:9527/provider/port返回值一直是8001
因为上面配置相同的路由规则 ,优先访问最靠前 最精确的路由
修改配置如下
server: port: 9527 #端口号 spring: application: name: cloud-gateway #服务名 cloud: gateway: discovery: locator: enabled: true # 开启动态路由 routes: #- id: payment_routh1 #不指定,但是要求唯一 #uri: http://localhost:8001 #匹配后提供服务的地址 固定路由 #predicates: #- Path=/provider/** - id: payment_routh2 #不指定,但是要求唯一 uri: lb://cloud-provider #匹配后提供服务的地址 动态路由 predicates: - Path=/provider/** eureka: client: # 是否从Eureka抓取注册信息 单节点情况下无用 集群情况下才能配合robbion使用负载均衡 fetch-registry: true # 注册如Eureka 用 true register-with-eureka: true service-url: # 设置与eureka server交互的地址查询和注册服务都需要这个地址 向注册中心注册 defaultZone: http://localhost:7001/eureka/
http://localhost:9527/provider/port可以轮询访问8001 8002
下面介绍常用断言
常用断言有以下几种
下面演示CookieRoutePredicate
server: port: 9527 #端口号 spring: application: name: cloud-gateway #服务名 cloud: gateway: discovery: locator: enabled: true # 开启动态路由 routes: #- id: payment_routh1 #不指定,但是要求唯一 #uri: http://localhost:8001 #匹配后提供服务的地址 固定路由 #predicates: #- Path=/provider/** - id: payment_routh2 #不指定,但是要求唯一 uri: lb://cloud-provider #匹配后提供服务的地址 动态路由 predicates: - Path=/provider/** - Cookie=username,zhangsan #cookie断言 eureka: client: # 是否从Eureka抓取注册信息 单节点情况下无用 集群情况下才能配合robbion使用负载均衡 fetch-registry: true # 注册如Eureka 用 true register-with-eureka: true service-url: # 设置与eureka server交互的地址查询和注册服务都需要这个地址 向注册中心注册 defaultZone: http://localhost:7001/eureka/
这时候访问port端口会报错
带上cookie会正常返回
GateWay的过滤器按生命周期可以分为两种 pre 和post
按照类型分GlobaFilter 和 GateWayFilter
可以在配置文件中配置
也可以实现 GlobaFilter 进行自定义规则(常用
首先去除Cookie断言,然后编写全局权限校验
package com.liuxu.filter; 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.http.server.PathContainer; import org.springframework.http.server.RequestPath; import org.springframework.http.server.reactive.ServerHttpResponse; import org.springframework.stereotype.Component; import org.springframework.web.server.ServerWebExchange; import reactor.core.publisher.Mono; /** * @author liuxu * @date 2020/7/8 14:19 */ @Component public class MyLogGateWayFilter implements GlobalFilter, Ordered { /** * 全局过滤器过滤器接口 * @param exchange * @param chain * @return */ @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { System.out.println(exchange); String username = exchange.getRequest().getQueryParams().getFirst("username"); if(username==null){ System.out.println("*****************用户名非法"); exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE); ServerHttpResponse response = exchange.getResponse(); return exchange.getResponse().setComplete(); } //通过 return chain.filter(exchange); } /** * 过滤器顺序 * @return */ @Override public int getOrder() { return 0; } }
重启9527
访问http://localhost:9527/provider/port
发现系统不可用被校验
带上用户http://localhost:9527/provider/port?username=13发现通过
GateWay的使用介绍完毕