Spring Cloud Gateway

引入:通过Eureka, Nacos解决了服务注册, 服务发现的问题, 使⽤Spring Cloud LoadBalance解决了负载均衡的问题, 使⽤OpenFeign解决了远程调⽤的问题.

但是当前所有微服务的接⼝都是直接对外暴露的, 可以直接通过外部访问. 为了保证对外服务的安全性,服务端实现的微服务接⼝通常都带有⼀定的权限校验机制. 由于使⽤了微服务, 原本⼀个应⽤的的多个模块拆分成了多个应⽤, 我们不得不实现多次校验逻辑. 当这套逻辑需要修改时, 我们需要修改多个应⽤, 加重了开发⼈员的负担.

因此就出了一个解决方案 就是使用API网关

一、什么是API 网关

API⽹关(简称⽹关)也是⼀个服务, 通常是后端服务的唯⼀⼊⼝. 它的定义类似设计模式中的Facade模式(⻔⾯模式, 也称外观模式). 它就类似整个微服务架构的⻔⾯, 所有的外部客⼾端访问, 都需要经过它来进⾏调度和过滤.

二、网关的核心功能

权限控制: 作为微服务的⼊⼝, 对⽤⼾进⾏权限校验, 如果校验失败则进⾏拦截

动态路由: ⼀切请求先经过⽹关, 但⽹关不处理业务, ⽽是根据某种规则, 把请求转发到某个微服务

负载均衡: 当路由的⽬标服务有多个时, 还需要做负载均衡

限流: 请求流量过⾼时, 按照⽹关中配置微服务能够接受的流量进⾏放⾏, 避免服务压⼒过⼤.

三、gateway项目

①创建⽹关项⽬

②引入依赖

<dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-starter-gateway</artifactId>

</dependency>

<!--基于nacos实现服务发现依赖-->

<dependency>

<groupId>com.alibaba.cloud</groupId>

<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>

</dependency>

<!--负载均衡-->

<dependency> <groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-starter-loadbalancer</artifactId>

</dependency>

③编写启动类

④添加Gateway的路由配置

1、id : ⾃定义路由ID, 保持唯⼀

2、uri: ⽬标服务地址, ⽀持普通URI 及 lb://应⽤注册服务名称 . lb表⽰负载均衡, 使⽤ lb:// ⽅

式表⽰从注册中⼼获取服务地址.

3、 predicates: 路由条件, 根据匹配结果决定是否执⾏该请求路由, 上述代码中, 我们把符合Path规则的⼀切请求, 都代理到uri参数指定的地址.

⑤测试

四、Route Predicate Factories

Route Predicate Factories (路由断⾔⼯⼚, 也称为路由谓词⼯⼚, 此处谓词表⽰⼀个函数), 在Spring

Cloud Gateway中, Predicate提供了路由规则的匹配机制.

注:

①我们在配置⽂件中写的断⾔规则只是字符串, 这些字符串会被Route Predicate Factory读取并处理, 转变为路由判断的条件.

②Spring Cloud Gateway 默认提供了很多Route Predicate Factory, 这些Predicate会分别匹配HTTP请求的不同属性, 并且多个Predicate可以通过and逻辑进⾏组合.

predicate的值:

①After:这个⼯⼚需要⼀个⽇期时间(Java的 ZonedDateTime对象), 匹配指定⽇期之后的请求(比如:predicates: - After=2017-01-20T17:42:47.789-07:00[America/Denver])

②Before:匹配指定⽇期之前的请求(比如:predicates:

  • Before=2017-01-20T17:42:47.789-07:00[America/Denver])

③Between:匹配两个指定时间之间的请求datetime2 的参数必须在datetime1 之后(比如:

predicates:

  • Between=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver])

④Cookie:请求中包含指定Cookie, 且该Cookie值符合指定的正则表达式(比如:

predicates:

  • Cookie=chocolate, ch.p)

⑤Header:请求中包含指定Header, 且该Header值符合指定的正则表达式(比如:

predicates:

  • Header=X-Request-Id, \d+)

⑥Host:请求必须是访问某个host(根据请求中的Host字段进⾏匹配)(比如:

predicates:

  • Host=**.somehost.org,**.anotherhost.org)

五、Gateway Filter Factories(⽹关过滤器⼯⼚)

Predicate决定了请求由哪⼀个路由处理, 如果在请求处理前后需要加⼀些逻辑, 这就是Filter(过滤器)的作⽤范围了.

Filter分为两种类型: Pre类型和Post类型

Pre类型过滤器: 路由处理之前执⾏(请求转发到后端服务之前执⾏), 在Pre 类型过滤器中可以做鉴权, 限流等。

Post类型过滤器: 请求执⾏完成后, 将结果返回给客⼾端之前执⾏.

Spring Cloud Gateway从作⽤范围上, 把Filter可分为GatewayFilter 和GlobalFilter.
GatewayFilter : 应⽤到单个路由或者⼀个分组的路由上.
GlobalFilter: 应⽤到所有的路由上, 也就是对所有的请求⽣效.

Spring Cloud Gateway提供了的Filter⾮常多, 下⾯列出⼀些常⻅过滤器:

①AddRequestHeader:为当前请求添加Header (比如:- AddRequestHeader=X-Request-red, blue 参数: Header的名称及值)

②AddRequestParameter:为当前请求添加请求参数(比如:- AddRequestParameter=red, blue

参数: 参数的名称及值)

③AddResponseHeader为响应结果添加Header(比如:- AddResponseHeader=X-Response-Red, Blue 参数: Header的名称及值)

④RemoveRequestHeader从当前请求删除某个Header (比如:- RemoveRequestHeader=X-Request-Foo 参数: Header的名称)

⑤RemoveResponseHeader:从响应结果删除某个Header(比如:RemoveResponseHeader=X-Response-Foo 参数: Header的名称)

⑥RequestRateLimiter为当前⽹关的所有请求执⾏限流过滤, 如果被限流, 默认会响应HTTP429-TooManyRequests默认提供了RedisRateLimiter的限流实现, 采⽤令牌桶算法实现限流功能. 此处不做具体介绍(比如:

filters:

  • name: RequestRateLimiter

args:

redis-rate-limiter.replenishRate: 10

redis-rate-limiter.burstCapacity: 20

redis-rate-limiter.requestedTokens: 1

redis-rate-limiter.replenishRate : 令牌填充速度, 即每秒钟允许多少个请求(不丢弃任何请求)

redis-rate-limiter.burstCapacity : 令牌桶容量, 即每秒⽤⼾最⼤能够执⾏的请求数量(不丢弃任何请求). 将此值设置为零将阻⽌所有请求

限流 -限制流量

限流算法

限流实现

限流算法:

1、固定窗口:(假设 流量限制:每分钟1000次)

若在第59秒的时候收到了1000次的请求,在第61秒的时候又收到1000次请求,就会导致1分钟内收到了多于1000的请求,就会导致服务器的损坏

2、滑动窗口:

3、漏铜算法:

这个算法对应激流量处理不好

4、令牌桶算法

过滤器的执行顺序:

既有GatewayFilter, ⼜有 GlobalFilter时, 执⾏的先后顺序:

请求路由后, ⽹关会把当前项⽬中的GatewayFilter和GlobalFilter合并到⼀个过滤器链(集合)中, 并进⾏排序, 依次执⾏过滤器

每⼀个过滤器都必须指定⼀个int类型的order值, 默认值为0, 表⽰该过滤的优先级. order值越⼩,优先级越⾼,执⾏顺序越靠前.

①Filter通过实现Order接⼝或者添加@Order注解来指定order值.

②Spring Cloud Gateway提供的Filter由Spring指定. ⽤⼾也可以⾃定义Filter, 由⽤⼾指定.

③当过滤器的order值⼀样时, 会按照 defaultFilter > GatewayFilter > GlobalFilter的顺序执⾏.

相关推荐
路在脚下@20 分钟前
Spring如何处理循环依赖
java·后端·spring
丁总学Java1 小时前
--spring.profiles.active=prod
java·spring
weisian1512 小时前
Redis篇--常见问题篇8--缓存一致性3(注解式缓存Spring Cache)
redis·spring·缓存
一只淡水鱼663 小时前
【mybatis】详解 # 和 $ 的区别,两者分别适用于哪种场景,使用 $ 不当会造成什么影响
sql·spring·mybatis·sql注入
荆州克莱3 小时前
Golang的性能监控指标
spring boot·spring·spring cloud·css3·技术
AI人H哥会Java4 小时前
【Spring】控制反转(IoC)与依赖注入(DI)—IoC容器在系统中的位置
java·开发语言·spring boot·后端·spring
武昌库里写JAVA4 小时前
【MySQL】MySQL 通过127.0.0.1和localhost登录的区别
spring boot·spring·毕业设计·layui·课程设计
丁总学Java4 小时前
nohup java -jar productQualification.jar --spring.profiles.active=prod $
java·spring·jar
大熊程序猿5 小时前
docker 搭建集群
spring cloud·docker·微服务
美美的海顿6 小时前
springboot基于Java的校园导航微信小程序的设计与实现
java·数据库·spring boot·后端·spring·微信小程序·毕业设计