前言
网关有以下几个作用:
- 统一入口:未全部为服务提供一个唯一的入口,网关起到外部和内部隔离的作用,保障了后台服务的安全性。
- 鉴权校验:识别每个请求的权限,拒绝不符合要求的请求。
- 动态路由:动态的将请求路由到不同的后端集群中。
- 减少客户端与服务端的耦合:服务可以独立发展,通过网关层来做映射。
一、什么是Spring Cloud Gateway?
- Spring Cloud 第一代网关 Zuul , Spring Cloud 第二代网关 GateWay。
- Spring Cloud Gateway 是由 WebFlux + Netty + Reactor 实现的响应式的 API 网关。
- Spring Cloud Gateway 不能在传统的 servlet 容器中工作,也不能构建成 war 包!
- Spring Cloud Gateway 为微服务架构提供一种简单且有效的 API 路由的管理方式,并基于 Filter 的方式提供网关的基本功能,例如说安全认证、监控、限流等等
注意:Spring Cloud Gateway会和spring-webmvc的依赖冲突,需要排除spring-webmvc
二、Spring Cloud Gateway核心概念
- 路由(route)
路由是网关中最基础的部分,路由信息包括一个ID、一个目的URI、一组断言工厂、一组Filter组成。如果断言为真,则说明请求的URL和配置的路由匹配。
- 断言(predicates)
Java8中的断言函数,SpringCloud Gateway中的断言函数类型是Spring5.0框架中的ServerWebExchange。断言函数允许开发者去定义匹配Http request中的任何信息,比如请求头和参数等。
- 过滤器(Filter)
SpringCloud Gateway中的filter分为Gateway FilIer和Global Filter。Filter可以对请求和响应进行处理。
三、Spring Cloud Gateway如何工作的?
四、Spring Cloud Gateway快速开始
1. 环境搭建:Maven项目子模块,pom配置。
2. 配置文件:基础配置、路由配置断言配置、过滤器配置。
3. 代码部分:自定义路由/断言/过滤器等,(无实现可无此配置)
详情参考:官网配置使用
1、环境搭建
<!-- 依赖 父工程-->
<parent>
<groupId>org.example</groupId>
<artifactId>lxnmall</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<!-- 本工程基础信息-->
<groupId>com.lxnmall</groupId>
<artifactId>gateway</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>lxnmall-gateway</name>
<dependencies>
<!-- 本工程依赖其他公共模块 要排除web mvc -->
<dependency>
<groupId>org.lxnmall</groupId>
<artifactId>lxnmall-common</artifactId>
<version>1.0-SNAPSHOT</version>
<exclusions>
<exclusion>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
</exclusion>
<exclusion>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- gateway的依赖添加-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!-- 整合其他的依赖添加-->
</dependencies>
2、 配置文件
1)基础信息
server:
port: 8888
spring:
application:
name: lixiunan-gateway
cloud:
gateway:
# 是否开启网关
enabled: true
discovery:
locator:
# 默认为false,设为true开启: 通过微服务创建路由的功能,即可以通过微服务名访问服务
lower-case-service-id: true
enabled: true
2)路由\断言\过滤器配置
server:
port: 8888
spring:
application:
name: lixiunan-gateway
cloud:
gateway:
# 是否开启网关
enabled: true
discovery:
locator:
# 默认为false,设为true开启: 通过微服务创建路由的功能,即可以通过微服务名访问服务
lower-case-service-id: true
enabled: true
# 设置路由:路由id、路由到微服务的uri、断言
routes:
# 路由ID,全局唯一
- id: lxnmall-product
# 详见【解释1】
uri: lb://lxnmall-product
# 断言配置
predicates:
# 路径配置:原路径为http://localhost:8001/order/getProduct...
- Path=/product/**
# #######以下非必需#######################
# 时间匹配:在指定的日期时间之后发生的请求才可以进网关,入参是ZonedDateTime类型
- After=2021-10-18T22:22:07.783+08:00[Asia/Shanghai]
# Cookie匹配:cookie里username为lixiunan的可以进
- Cookie=username, lixiunan
# Header匹配 请求中带有请求头名为 x-request-id,其值与 \d+ 正则表达式匹配
#- Header=X-Request-Id, \d+
#配置过滤器工厂
#filters:
# - AddRequestHeader=X-Request-color, red #添加请求头
【解释1】:目标微服务的请求地址原始 uri: http://localhost:8001;LoadBalancerClientFilter 会查看exchange的属性ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR 的值如果该值的scheme是 lb,比如:lb://lxnmall-product ,它将会使用Spring Cloud的LoadBalancerClient 来将 lxnmall-product解析成实际的host和port,并替换掉 ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR 的内容。
3、自定义路由断言工厂
自定义路由断言工厂步骤:
继承 AbstractRoutePredicateFactory 类,重写 apply 方法的逻辑。
命名需要以 RoutePredicateFactory 结尾
yml配置文件中配置
1)继承 AbstractRoutePredicateFactory 类,重写 apply 方法的逻辑
@Component
@Slf4j
public class LixiunanRoutePredicateFactory extends AbstractRoutePredicateFactory<CheckAuthRoutePredicateFactory.Config> {
public LixiunanRoutePredicateFactory() {
super(Config.class);
}
@Override
public Predicate<ServerWebExchange> apply(Config config) {
return new GatewayPredicate() {
@Override
public boolean test(ServerWebExchange serverWebExchange) {
log.info("调用LixiunanRoutePredicateFactory");
//需要实现的断言
//......
return true;
}
};
}
}
2) yml配置文件中配置
spring:
cloud:
gateway:
#设置路由:路由id、路由到微服务的uri、断言
routes:
- id: lixiunan_route #路由ID,全局唯一
uri: http://localhost:6666 #目标微服务的请求地址和端口
predicates:
# 测试:http://localhost:8888/lxn/...
- Path=/lxn/** #Path路径匹配
#自定义断言工厂
- name: Lixiunan
3-2、自定义过滤器工厂
自定义路由断言工厂步骤:
- 继承AbstractNameValueGatewayFilterFactory
- 名称必须要以GatewayFilterFactory结尾
- yml配置使用
1) 继承AbstractNameValueGatewayFilterFactory
@Component
@Slf4j
public class LixiunanGatewayFilterFactory extends AbstractNameValueGatewayFilterFactory {
@Override
public GatewayFilter apply(NameValueConfig config) {
return (exchange, chain) -> {
log.info("调用LixiunanGatewayFilterFactory");
//实现适配逻辑
//......
//加入监听链中生效
return chain.filter(exchange);
};
}
}
2)yml配置使用自定义适配器工厂
spring:
cloud:
gateway:
routes:
- id: lixiunan_route #路由ID,全局唯一
uri: http://localhost:8888 #目标微服务的请求地址和端口
#配置过滤器工厂
filters:
- Lixiunan
注:Gateway跨域配置(CORS Configuration)
spring:
cloud:
gateway:
globalcors:
cors-configurations:
'[/**]':
allowedOrigins: "*"
allowedMethods:
- GET
- POST
- 。。。