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的使用介绍完毕