目录
[一 网关介绍](#一 网关介绍)
[二 GateWay的使用](#二 GateWay的使用)
[三 predicates配置详解](#三 predicates配置详解)
[2.Route Predicate Factories(路由断言工厂)](#2.Route Predicate Factories(路由断言工厂))
[四 GateWay Filter Factories(网关过滤工厂)](#四 GateWay Filter Factories(网关过滤工厂))
[五 自定义过滤器](#五 自定义过滤器)
[1.自定义Gateway Filter](#1.自定义Gateway Filter)
[六 服务部署](#六 服务部署)
一 网关介绍
1.问题
当前应用的所有接口都是暴露在外面的,所有的应用都可以访问到,不安全,之前单体架构,我会对其进行权限校验,但是目前有多套服务,权限校验就得进行多次,维护起来会很麻烦
例如:一个公司里一开始只有一个部门,刚开始只需要校验一次就可以进行办理业务(单体架构),后面衍生出了多个部门(微服务架构),一个人去不同部门办理业务都需要校验一次,这样就增多了工作流程和降低效率
因此就产生了前台,由前台进行校验,再带去对应的部门进行业务办理,这样就只需要校验一次
此处的前台就为该公司的统一入口,API网关就相当于这个前台,是服务的唯一入口,所有的请求都先通过网关,校验后再去调用的应用服务
2.功能
(1)权限控制--对当前请求进行权限校验,校验通过了才能到达微服务
(2)动态路由--会根据当前用户的请求,将其转发到某一个服务
(3)负载均衡--需要转发到某个服务,但是这个服务有多个实例时,根据负载均衡看将其转发到哪个实例
(4)限流--流量限制
3.常见网关实现
(1)Zuul
(2)SpringCloudGateWay
下面介绍的是SpringCloudGateWay的相关内容
二 GateWay的使用
1.基础使用
(1)创建新项目(网关与其他服务一样,都是一个单独的项目)
(2)添加GateWay相关依赖
①网关相关依赖
XML
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
②动态路由,需要获取服务的地址,需要使用服务发现,此时我们使用Nacos注册中心
XML
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
③网关实现负载均衡,需要引入对应的依赖
XML
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
(3)写启动类
(4)写配置文件
XML
server:
port: 10030 # ⽹关端⼝
spring:
application:
name: gateway # 服务名称
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
gateway:
routes: # ⽹关路由配置
- id: product-service #路由ID, ⾃定义, 唯⼀即可
uri: lb://product-service #⽬标服务地址
predicates: #路由条件
- Path=/product/** #满足该路径就转发到目标服务地址
- id: order-service
uri: lb://order-service
predicates:
- Path=/order/**
(5)测试
三 predicates配置详解
1.Predicate
(1)介绍:
是一个函数式编程接口,它接收一个参数并返回一个布尔值,用于条件过滤,请求参数的校验
(2)写法:
①类进行继承
②匿名类
③lambda表达式
具体:继承该接口后重写test方法来进行条件过滤和参数校验
(3)其他方法
and:当前参数同时满足两个Predicate的校验规则
or:当前参数满足其中一个Predicate的校验规则
negate:对当前参数校验规则进行取反
2.Route Predicate Factories(路由断言工厂)
(1)常见路由断言类型:
-After,-Before,-Between:表示时间必须在这之前/之后/之内
如何获取这种格式的时间:
java
ZonedDateTime.now()
-Header,-Cookie,-Host:要有的对应的参数和值(第二个可能是值也可能表示正则表达式)
-Method:必须为指定的方法
-Path:指定路径
-Query:指定参数,若有第二个表示值或必须满足对应的正则表达式
(2)规则:
当predicates存在多个路由断言时,彼此是and的关系
四 GateWay Filter Factories(网关过滤工厂)
1.作用
Route Predicates Factories解决的是当满足某些条件时就将请求转发到某个路由
GateWay Filter Factories解决我们在请求前后需要进行一些处理的需求
2.类型
(1)从作用时间上分:
Pre类型
Post类型
(2)从作用范围上分
GateWayFilter:作用于一组或者单个路由器
GlobalFilter:作用于全局的过滤器
3.GatewayFilter
(1)使用(配置):
其作用于一组服务或一个服务,因此也是在单个服务上进行配置,在filters里进行配置
bash
server:
port: 10030 # ⽹关端⼝
spring:
application:
name: gateway # 服务名称
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
namespace: 1f2ba2db-a865-442a-904b-1d33efab76e1
gateway:
routes: # ⽹关路由配置
- id: product-service #路由ID, ⾃定义, 唯⼀即可
uri: lb://product-service #⽬标服务地址
predicates: #路由条件
- Path=/product/** #满足该路径就转发到目标服务地址
- After=2026-04-26T22:45:33.181755800+08:00[Asia/Shanghai]
filters:
- AddRequestParameter=userName, zhku
(2)常见GateWayFilter
①Retry:超时进行重试过滤器
配置:
bash
filters:
- name: Retry
args:
retries: 3
statuses: BAD_REQUEST
参数说明:
retries:重试次数
statuses;HTTP请求返回的什么样的状态码进行重试
②RequestSize:限制接收请求包的大小
配置:
bash
filters:
- name: RequestSize
args:
maxSize: 5000000
(3)Default Filter:
上面的过滤器是只对当前路由生效,default Filter是针对所有路由生效
bash
spring:
cloud:
gateway:
default-filters:
- AddResponseHeader=X-Response-Default-Red, Default-Blue
- PrefixPath=/httpbin
(4)过滤器配置方式
①简写版:直接过滤器名=key,value
例如:
bash
- AddResponseHeader=X-Response-Default-Red, Default-Blue
②完整写法:
分别配置name和args,使用于多参情况
例如:
bash
- name: RequestSize
args:
maxSize: 5000000
4.限流
(1)限流算法(思想)
①固定窗口:让流量在每分钟内计时,超过多少次就停止接收流量
例如:每分钟1000次,0-1分钟开始计时,如果超过1000次就停止接收流量
存在问题:若当前流量是59秒-60秒间来了1000个请求,而在60-61秒间来了1000个请求,则也满足这个条件,但此时累计2000个请求,就不满足我们的规定范围了,可能导致服务器出问题
②滑动窗口:
计算一段时间内的请求次数,超过就无法继续访问
与固定窗口的区别:不是固定的几秒到几秒,而是计算当前多少时间内的请求次数
③漏桶算法
以一定的速率漏(不能处理紧急大量的请求),无论什么情况都是这个速率
④令牌桶算法
每秒钟固定速率放令牌,即使没有请求,也照样放,一个请求一个令牌,有分到令牌的就进行处理,没分到的就代表拒绝和等待(可以应对应急的情况)
(2)限流实现--RequestRateLimiter(使用令牌桶算法)
bash
filters:
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 10
redis-rate-limiter.burstCapacity: 20
redis-rate-limiter.requestedTokens: 1
参数说明:
replenishRate:令牌的投放速率(每秒/个)
burstCapacity:令牌桶的容量
requestedTokens:每个请求消耗多少个令牌
5.GlobalFilter--全局过滤器
(1)作用:
作用于全局的路由,用于实现安全性,性能监控和日志记录等相关的全局功能
(2)常见全局过滤器:
①LoadBalancer Client Filter:针对下游服务,实现负载均衡
如何使用:在配置的uri里使用lb://应用名,其就会自动对这个应用实现负载均衡,分配对应的服务
bash
spring:
application:
name: gateway # 服务名称
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
namespace: 1f2ba2db-a865-442a-904b-1d33efab76e1
gateway:
routes: # ⽹关路由配置
- id: product-service #路由ID, ⾃定义, 唯⼀即可
uri: lb://product-service #⽬标服务地址
predicates: #路由条件
- Path=/product/** #满足该路径就转发到目标服务地址
- After=2026-04-26T22:45:33.181755800+08:00[Asia/Shanghai]
filters:
- AddRequestParameter=userName, zhku
②Gateway Metrics Filter:网关监控
如何使用:
(Ⅰ)在网关项目里引入依赖
XML
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
(Ⅱ)增加对应的配置(设置为true+配置功能),此处功能配置仅供参考,具体看个人需求
XML
spring:
cloud:
gateway:
metrics:
enabled: true
management:
endpoints:
web:
exposure:
include: "*"
endpoint:
health:
show-details: always
shutdown:
enabled: true
查看:http://127.0.0.1:10030/actuator
注:要方便查看,可安装官方建议的Grafana dashboard,可视化面板
6.过滤器的执行顺序
网关会把所有的规律器放到一个集合中,类似于链表的结构
每一个过滤器都需要指定执行顺序,order越小,顺序越前
SpringCloud已经帮我们指定了默认顺序,但是我们也可以手动指定--自定义过滤器
如果未手动指定,那么执行顺序为
default Filter>Gateway Filter>Global Filter
执行顺序类似于拦截器
五 自定义过滤器
1.自定义GatewayFilterFactory
(1)继承AbtractGateWayFilterFactory类,由于需要指定顺序,还需要实现Ordered接口,需要将该类对像交给Spring管理,加上@Component注解
(2)AbtractGateWayFilterFactory<T>需要指定泛型,这个泛型就为其配置过滤器时需要配置的参数
(3)重写方法apply和order
filter方法说明:
①ServerWebExchange:HTTP请求-响应契约,提供了对HTTP请求和响应内容的访问
②GateWayFilterChain:过滤器链
③Mono:Reactor的核心类,数据流发布者,Mono最多只能触发一个事件,可以把Mono用在异步完成时,发出的通知
④chain.filter.(exchange):执行请求
⑤Mono.fromRunnable():创建Runnable数据流
⑥过滤器执行顺序:
Pre类型--chain.filter()--Post类型
Pre类型过滤器代码:写在chain.filter()之前
执行请求:chain.filter()
Post类型过滤器代码:chain.filter().then(Mono.fromRunnable(()->{
))
(4)如何配置自定义GatewayFilter:
bash
spring:
application:
name: gateway
cloud:
gateway:
routes:
- id: order-service #路由规则id, 随便起, 不重复即可
uri: lb://order-service/ #目标服务地址
predicates: #路由条件
- Path=/order/**,/feign/**
- After=2024-03-20T00:00:22.370856700+08:00[Asia/Shanghai]
filters:
- name: Custom #过滤器名称
args:
name: test_custom
java
@Data
public class CustomConfig {
private String name;
}
参数说明:
-name:自定义过滤器的名称为GatewayFilterFactory的前面部分,例如CustomGatewayFilterFactory的名称为Custom(与过滤器的类名保持一致)
args:以key:value的形式来写,与配置类(CustomConfig)的属性保持一致
2.自定义GlobalFilter
(1)实现:写一个类实现GlobalFilter,实现Ordered接口,实现对应的方法,无须配置,直接启动即可
六 服务部署
1.步骤
(1)确认配置
(2)打包,上传到服务器
(3)启动项目
(4)开放端口号
(5)测试