0


Spring Cloud Gateway

文章目录

  • 一. 概念
  • 二. 常见网关对比
  • 三. 流量网关与业务网关
  • 四. 作用
      1. 路由转发- - 1. 模拟发送Http请求- 2. 实现过程- 2. 负载均衡- 3. 统一处理跨域- - 3.1 跨域的概念- 3.2 跨域带来的问题- 3.3 解决方案-配置式- 4. 接口保护- - 4.1 限制请求- 4.2 信息脱敏- 4.3 降级(熔断)- - 1. 概念- 2. 实现方式-配置式- - 2.1 引入依赖- 2.2 熔断配置- 2.3 返回友好提示- 4.4 限流- - 1. 概念- 2. 常见限流算法- - 2.1 漏桶算法- - 2.1.1 概念- 2.1.2 核心思想- 2.1.3 不足- 2.1.4 算法描述- 2.2 令牌桶算法- - 2.2.1 概念- 2.2.2 核心思想- 2.2.3 算法描述- 2.3 令牌桶和漏桶对比- 3. 基于Redis的限流方案- - 3.1 实现思路- 3.2 操作步骤- - 1. 引入依赖- 2. 配置KeyResolver-指定限流的 Key- 3. 配置限流的过滤器信息- 4. 测试结果- 5. Redis存储内容- 4.5 超时时间-连接超时和响应超时- - 1. 概念- 2. 实现方式-配置式- - 2.1 全局配置-为所有路由设置统一的超时标准- 2.2 路由配置-为特定的路由设置不同的超时参数,以满足不同服务的特定需求- 4.6 重试(业务保护)- - 1. 概念- 2. 实现方式-配置式- 4.7 访问控制- - 1. 概念- 2. 实现方式- 2. 安全认证-自定义全局过滤器 实现GlobalFilter接口

一. 概念

API网关:指系统的统一入口,对内部系统进行封装,所有请求都先经过网关,由网关将请求路由到合适的微服务,一些与业务本身功能无关的公共逻辑可以在这里实现,诸如认证、鉴权、日志、路由转发等。

二. 常见网关对比

在这里插入图片描述

三. 流量网关与业务网关

流量网关业务网关代表NginxSpring Cloud Gateway定位主要是作为一个高性能的Web服务器和反向代理服务器,侧重于静态内容的高速分发、负载均衡、SSL终止为微服务架构设计,是API管理平台的一部分,提供更高级的API管理功能功能提供HTTP服务器功能,反向代理,负载均衡,简单的访问控制和静态内容缓存等。除了负载均衡、路由分发之外,还支持API聚合、协议转换、认证鉴权、限流熔断、监控日志等功能,特别适合微服务架构的复杂需求。配置配置基于文本的配置文件,灵活性和控制力强,但配置复杂度相对较高支持基于YAML或Java配置适用场景适用于需要高性能Web服务器、简单API路由、负载均衡的场景微服务架构中,特别是需要复杂API管理、安全控制、监控和动态路由的场景。总结Nginx作为前端的负载均衡器Gateway对后端服务进行更细粒度的API管理。

四. 作用

在这里插入图片描述

1. 路由转发

客户端或者sdk发送的http请求都是指向网关,再转发到实际的API接口。

1. 模拟发送Http请求

/**
     * 获取随机文本
     * @return
     */// 向网关服务发送请求publicStringgetRandomWork(){returnHttpRequest.get("http://localhost:8090/api/interface/random/word").addHeaders(getHeadMap("",accessKey,secretKey)).execute().body();}

2. 实现过程

在这里插入图片描述

  1. 微服务启动,将自己注册到Nacos,Nacos记录了各微服务实例的地址.
  2. 网关从Nacos读取服务列表,包括服务名称、服务地址等.
  3. 请求到达网关,网关将请求路由到具体的微服务.
  4. 通过网关配置文件中制定的路由规则
spring:application:name: api-gateway
  cloud:nacos:discovery:server-addr: 127.0.0.1:8848# 网关路由配置gateway:routes:# 路由id,自定义,唯一即可。-id: api_backend
          # 多种方式配置目标地址# uri: http:// 127.0.0.1:9001 http方式:固定地址uri: lb://api-backend #lb就是负载均衡,后面跟服务名称predicates:#路由断言,判断请求是否符合路由规则的条件- Path=/api/**# 以/api开头的请求就会被转发到api-backend服务

2. 负载均衡

在路由的基础上,将请求转发到集群A的某一台机器上,再调用机器上对应的接口
uri: lb://api-backend #lb就是负载均衡

3. 统一处理跨域

3.1 跨域的概念

如果一个请求的协议、主机或端口任意一个与当前页面的源(即协议、主机和端口)不同,则该请求就被认为是跨域请求。

3.2 跨域带来的问题

  1. AJAX请求被拒绝:浏览器会阻止在跨域请求中使用XMLHttpRequest对象进行通信。
  2. Cookie不可用:跨域请求默认不会发送源站的Cookie信息,导致无法验证用户身份。
  3. 访问被拒绝:跨域请求可能会受到服务器的访问控制策略阻止。

3.3 解决方案-配置式

spring:
    cloud:
        gateway:
            globalcors:
                corsConfigurations:'[/**]':
                        allowedOrigins:"*"
                        exposedHeaders:- content-type
                        allowedHeaders:- content-type
                        allowCredentials:true
                        allowedMethods:-GET-OPTIONS-PUT-DELETE-POST

4. 接口保护

4.1 限制请求

4.2 信息脱敏

4.3 降级(熔断)

1. 概念

熔断是一种防止故障扩散的策略。当一个服务出现故障或超时,熔断器会打开并快速失败,拒绝后续的请求,避免请求堆积和资源耗尽。熔断器会暂时屏蔽该服务,并在一段时间后尝试恢复。熔断器的状态变化可用于监控系统健康和提供告警信息。

2. 实现方式-配置式
2.1 引入依赖
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-hystrix</artifactId></dependency>
2.2 熔断配置
spring:cloud:gateway:routes:- id: your_route_id
             uri: lb://your_service_id
             filters:- name: Hystrix
                 args:name: fallback
                   fallbackUri: forward:/fallback  # 当熔断发生时转发到的本地fallback处理逻辑
             predicates:- Path=/api/** # 例如,匹配所有/api开头的路径

上面配置了一个 Hystrix 过滤器,该过滤器会使用 Hystrix 熔断与回退,原理是将请求包装成 RouteHystrixCommand 执行,RouteHystrixCommand 继承于 com.netflix.hystrix.HystrixObservableCommand。

fallbackUri 是发生熔断时回退的 URI 地址,目前只支持 forward 模式的 URI。如果服务被降级,该请求会被转发到该 URI 中。

2.3 返回友好提示
@RestController
publicclassFallbackController{
    @GetMapping("/fallback")public String fallback(){thrownewRunTimeException("请稍后再试!");}}

4.4 限流

1. 概念

API 网关作为所有请求的入口,请求量大,我们可以通过对并发访问的请求进行限速来保护系统的可用性。

2. 常见限流算法
2.1 漏桶算法
2.1.1 概念

水(请求)先进入到漏桶里,漏桶以一定的速度出水(接口有响应速率),当水流入速度过大会直接溢出(访问频率超过接口响应速率),然后就拒绝请求,可以看出漏桶算法能强行限制数据的传输速率

2.1.2 核心思想

可见这里有两个变量,一个是桶的大小,支持流量突发增多时可以存多少的水(burst),另一个是水桶漏洞的大小(rate)。

2.1.3 不足

因为漏桶的漏出速率是固定的参数,所以,即使网络中不存在资源冲突(没有发生拥塞),漏桶算法也不能使流量突发(burst)到端口速率。因此,漏桶算法对于存在突发特性的流量来说缺乏效率。
在这里插入图片描述

2.1.4 算法描述
1.  一个固定容量的漏桶,按照常量固定速率流出水滴;

2.  如果桶是空的,则不需流出水滴;

3.  可以以任意速率流入水滴到漏桶;

4. 如果流入水滴超出了桶的容量,则流入的水滴溢出了(被丢弃),而漏桶容量是不变的。
2.2 令牌桶算法
2.2.1 概念

系统会按恒定1/QPS时间间隔(如果QPS=100,则间隔是10ms)往桶里加入Token,如果桶已经满了就不再加了。新请求来临时,会各自拿走一个Token,如果没有Token可拿了就阻塞或者拒绝服务。

2.2.2 核心思想

令牌桶的核心是可以预先在令牌桶中存储一些Token,这样当流量激增的时候,可以并发处理这一批请求,而且一旦需要提高速率,则按需提高放入桶中的令牌的速率.
在这里插入图片描述

2.2.3 算法描述
  1. 假设限制2r/s,则按照500毫秒的固定速率往桶中添加令牌;
  2. 桶中最多存放b个令牌,当桶满时,新添加的令牌被丢弃或拒绝;
  3. 当一个n个字节大小的数据包到达,将从桶中删除n个令牌,接着数据包被发送到网络上;
  4. 如果桶中的令牌不足n个,则不会删除令牌,且该数据包将被限流(要么丢弃,要么缓冲区等待)。
2.3 令牌桶和漏桶对比
  1. 令牌桶是按照固定速率往桶中添加令牌,请求是否被处理需要看桶中令牌是否足够,当令牌数减为零时则拒绝新的请求;
  2. 漏桶则是按照常量固定速率流出请求,流入请求速率任意,当流入的请求数累积到漏桶容量时,则新流入的请求被拒绝;
  3. 令牌桶限制的是平均流入速率(允许突发请求,只要有令牌就可以处理,支持一次拿3个令牌,4个令牌),并允许一定程度突发流量;
  4. 漏桶限制的是常量流出速率(即流出速率是一个固定常量值,比如都是1的速率流出,而不能一次是1,下次又是2),从而平滑突发流入速率;
  5. 令牌桶允许一定程度的突发,而漏桶主要目的是平滑流入速率;
  6. 两个算法实现可以一样,但是方向是相反的,对于相同的参数得到的限流效果是一样的。
3. 基于Redis的限流方案
3.1 实现思路

spring cloud gateway默认基于redis令牌桶算法进行微服务的限流保护,采用RateLimter限流算法来实现。

3.2 操作步骤
1. 引入依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis-reactive</artifactId></dependency>
2. 配置KeyResolver-指定限流的 Key
importorg.springframework.cloud.gateway.filter.ratelimit.KeyResolver;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importorg.springframework.context.annotation.Primary;importreactor.core.publisher.Mono;/**
 * 限流配置KeyResolver——有三种写法(接口限流/ip限流/用户限流)
 */@ConfigurationpublicclassRateLimiteConfig{/**
     * 接口限流:根据请求路径限流
     * 如果不使用@Primary注解,会报错
     * @return
     */@Bean@PrimarypublicKeyResolverpathKeyResolver(){return exchange ->Mono.just(exchange.getRequest().getPath().toString());}/**
     * 根据请求IP限流
     * @return
     */@BeanpublicKeyResolveripKeyResolver(){return exchange ->Mono.just(exchange.getRequest().getRemoteAddress().getHostName());}/**
     * 根据请求参数中的userId进行限流
     * 请求地址写法:http://localhost:8801/rate/123?userId=lisi
     * @return
     */@BeanpublicKeyResolveruserKeyResolver(){return exchange ->Mono.just(exchange.getRequest().getQueryParams().getFirst("userId"));}}
3. 配置限流的过滤器信息
1. filter 名称必须是 RequestRateLimiter。
2. redis-rate-limiter.replenishRate:允许用户每秒处理多少个请求。
3. redis-rate-limiter.burstCapacity:令牌桶的容量,允许在 1s 内完成的最大请求数。
4. key-resolver:使用 SpEL 按名称引用 bean。
spring:cloud:gateway:routes:-id: rate-limit-demo
          uri: lb://mima-cloud-producer
          predicates:#访问路径:http://localhost:8801/rate/123- Path=/rate/**filters:-name: RequestRateLimiter
              args:# 令牌桶每秒填充平均速率, 允许用户每秒处理多少个请求。redis-rate-limiter.replenishRate:1# 令牌桶的容量,允许在1s内完成的最大请求数。redis-rate-limiter.burstCapacity:2# 使用SpEL表达式从Spring容器中获取Bean对象, 查看RateLimiteConfig实现类中的方法名key-resolver:"#{@pathKeyResolver}"#key-resolver: "#{@ipKeyResolver}"#key-resolver: "#{@userKeyResolver}"
4. 测试结果

多次调用请求,控制台打印结果

[开始]请求路径:/rate/123[应答]请求路径:/rate/123耗时:2ms
2024-09-0816:23:27.253DEBUG18512---[ioEventLoop-4-1] o.s.w.s.adapter.HttpWebHandlerAdapter    :[62eb90e0] Completed 429TOO_MANY_REQUESTS2024-09-0816:23:27.394DEBUG18512---[ctor-http-nio-2] o.s.w.s.adapter.HttpWebHandlerAdapter    :[62eb90e0]HTTPGET"/rate/123"
corsFilter... run
[开始]请求路径:/rate/123[应答]请求路径:/rate/123耗时:2ms
2024-09-0816:23:27.397DEBUG18512---[ioEventLoop-4-1] o.s.w.s.adapter.HttpWebHandlerAdapter    :[62eb90e0] Completed 429TOO_MANY_REQUESTS2024-09-0816:23:27.536DEBUG18512---[ctor-http-nio-2] o.s.w.s.adapter.HttpWebHandlerAdapter    :[62eb90e0]HTTPGET"/rate/123"
corsFilter... run
5. Redis存储内容
当发生限流时,会向redis中存储两个数据

127.0.0.1:6379> keys *1)"request_rate_limiter.{localhost}.timestamp"2)"request_rate_limiter.{localhost}.tokens"

大括号中就是我们的限流 Key,这里是 IP,本地的就是 localhost。

timestamp:存储的是当前时间的秒数,也就是 System.currentTimeMillis()/1000 或者 Instant.now().getEpochSecond()。

tokens:存储的是当前这秒钟对应的可用令牌数量。

4.5 超时时间-连接超时和响应超时

1. 概念

连接超时和响应超时是两种不同的超时机制,分别用于处理不同的网络通信问题。

连接超时(connect-timeout)

  1. 主要指的是在建立网络连接过程中所允许的最大等待时间。
  2. 如果在规定的时间内无法成功建立与服务端的连接,则认为连接超时。
  3. 在Spring Cloud Gateway中,连接超时用于确保在尝试与服务建立连接时,如果等待过长时间仍未成功,则放弃此次连接尝试,避免长时间占用资源。

响应超时‌(response-timeout)

  1. 是指在建立连接后,等待服务端响应的最大等待时间。
  2. 如果在规定的时间内服务端未返回响应,则认为响应超时。
  3. 这个设置用于确保在请求发送后,如果服务端在合理时间内未作出响应,网关能够及时释放资源,避免因等待过久而造成资源浪费或影响其他请求的处理。
2. 实现方式-配置式
2.1 全局配置-为所有路由设置统一的超时标准
spring:cloud:gateway:httpclient:connect-timeout:1000# 连接超时,单位是毫秒response-timeout: 5s # 响应超时,单位是秒
2.2 路由配置-为特定的路由设置不同的超时参数,以满足不同服务的特定需求
gateway:routes:# 路由id,自定义,唯一即可。-id: api_backend_route
          # 多种方式配置目标地址# uri: http:// 127.0.0.1:9001 http方式:固定地址uri: lb://api-backend #lb就是负载均衡,后面跟服务名称predicates:#路由断言,判断请求是否符合路由规则的条件- Path=/api/**# 以/api开头的请求就会被转发到api-backend服务metadata:response-timeout:5000connect-timeout:2000

4.6 重试(业务保护)

1. 概念

当网关将请求转发到内部服务时,如果内部服务调用失败,我们可以尝试重新发送请求,从而保证系统的可靠性

2. 实现方式-配置式
filters:-name: Hystrix
    args:name: fallback
      fallbackUri: forward:/fallback  # 当熔断发生时转发到的本地fallback处理逻辑-name: Retry # 配置重试过滤器args:retries:3# 重试次数,默认值是 3 次。series: SERVER_ERROR # 状态码配置(分段),符合某段状态码才会进行重试逻辑,默认值是 SERVER_ERROR,值是 5,也就是 5XX(5 开头的状态码)

4.7 访问控制

1. 概念

针对访问网关的请求进行限制;比如:特定IP才可以访问该请求-白名单;某个IP在短时间内发送大量请求,从而使得服务器资源耗尽,导致正常用户的合法请求失败-黑名单;

2. 实现方式
  1. 在网关的配置文件中添加请求的黑白名单.
request:white-list:- /api/v1/get/test
    - api/v1/get/getUserInfo
  black-list:- 127.0.0.1
  1. 通过配置类映射黑白名单信息到集合中
packagecom.monkey.gateway_template.config;importorg.springframework.boot.context.properties.ConfigurationProperties;importorg.springframework.stereotype.Component;importjava.util.List;/**
 * 请求白名单.
 *
 */@Component@ConfigurationProperties("request")publicclassRequestWhiteList{/**
     * 白名单列表
     */List<String> whiteList;publicList<String>getWhiteList(){return whiteList;}publicvoidsetWhiteList(List<String> whiteList){this.whiteList = whiteList;}}
  1. 在自定义的全局过滤器中校验黑白名单,实现请求的放行与屏蔽
@Slf4j@ComponentpublicclassLoginGlobalFilterimplementsGlobalFilter,Ordered{@OverridepublicMono<Void>filter(ServerWebExchange exchange,GatewayFilterChain chain){// 黑白名单InetSocketAddress localAddress = request.getLocalAddress();if(!"127.0.0.1".equals(localAddress.getHostString())){
           response.setStatusCode(HttpStatus.FORBIDDEN);return response.setComplete();}}}

2. 安全认证-自定义全局过滤器 实现GlobalFilter接口

登录认证以及请求接口认证的方法在filter方法中实现
过滤器链
在这里插入图片描述

@OverridepublicMono<Void>filter(ServerWebExchange exchange,GatewayFilterChain chain){// 登录认证以及请求接口认证的方法在filter方法中实现}
标签: gateway

本文转载自: https://blog.csdn.net/weixin_45119534/article/details/141334018
版权归原作者 三十六煩惱風 所有, 如有侵权,请联系我们删除。

“Spring Cloud Gateway”的评论:

还没有评论