【gateway 进阶】网关限流和流量控制


系列文章目录

【gateway 进阶】1、高级路由配置
【gateway 进阶】2、负载均衡和故障转移
【gateway 进阶】3、服务发现与集成
【gateway 进阶】4、高级安全设置:OAuth2和JWT
【gateway 进阶】5、性能优化和缓存策略
【gateway 进阶】6、自定义过滤器开发
【gateway 进阶】7、集成第三方服务和插件
【gateway 进阶】8、分布式追踪和监控
【gateway 进阶】9、网关限流和流量控制(本文)
【gateway 进阶】10、高可用性和伸缩性设计


在前面的文章中,我们探讨了分布式追踪和监控的实现。本章将深入探讨如何在Spring Cloud Gateway中实现限流和流量控制,以保护后端服务免受流量突增的影响,并确保系统的稳定性和高可用性。

限流和流量控制概述

限流和流量控制是API网关的重要功能,能够防止后端服务过载,确保系统在高并发和流量突增的情况下依然能够稳定运行。Spring Cloud Gateway提供了多种限流和流量控制策略,包括基于Redis的分布式限流。

主要功能

  1. 请求限流:限制单位时间内的请求数量,防止系统过载。
  2. 流量控制:根据预定义的规则控制流量分配,确保重要服务的稳定性。
  3. 熔断机制:在服务出现故障时快速阻断请求,防止故障扩散。
  4. 反馈控制:根据系统负载动态调整限流策略,优化性能。

使用Spring Cloud Gateway进行限流

Spring Cloud Gateway内置了基于Redis的分布式限流器,你可以通过配置Redis限流过滤器来实现请求限流。

1. 添加依赖

pom.xml 文件中添加以下依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>

2. 配置Redis限流器

application.yml 中配置Redis限流器:

spring:
  redis:
    host: localhost
    port: 6379
  cloud:
    gateway:
      routes:
        - id: user-service
          uri: lb://USER-SERVICE
          predicates:
            - Path=/users/**
          filters:
            - name: RequestRateLimiter
              args:
                redis-rate-limiter:
                  replenishRate: 10
                  burstCapacity: 20
server:
  port: 8080
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
    fetch-registry: true
    register-with-eureka: true

3. 配置限流键解析器

创建一个自定义限流键解析器 HostAddrKeyResolver.java

import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

@Configuration
public class RateLimiterConfig {

    @Bean
    public KeyResolver hostAddrKeyResolver() {
        return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getAddress().getHostAddress());
    }
}

4. 配置限流策略

application.yml 中配置限流策略:

spring:
  cloud:
    gateway:
      default-filters:
        - name: RequestRateLimiter
          args:
            key-resolver: "#{@hostAddrKeyResolver}"
            redis-rate-limiter:
              replenishRate: 10
              burstCapacity: 20

使用Resilience4j实现限流和熔断

Resilience4j是一个轻量级的故障处理库,支持限流、熔断、重试等功能。你可以通过集成Resilience4j来增强Spring Cloud Gateway的稳定性和容错能力。

1. 添加依赖

pom.xml 文件中添加以下依赖:

<dependency>
    <groupId>io.github.resilience4j</groupId>
    <artifactId>resilience4j-spring-boot2</artifactId>
</dependency>

2. 配置Resilience4j

application.yml 中配置Resilience4j:

spring:
  cloud:
    gateway:
      routes:
        - id: product-service
          uri: lb://PRODUCT-SERVICE
          predicates:
            - Path=/products/**
          filters:
            - name: CircuitBreaker
              args:
                name: myCircuitBreaker
                fallbackUri: forward:/fallback
resilience4j:
  circuitbreaker:
    instances:
      myCircuitBreaker:
        registerHealthIndicator: true
        ringBufferSizeInClosedState: 5
        ringBufferSizeInHalfOpenState: 2
        waitDurationInOpenState: 10000
        failureRateThreshold: 50
        eventConsumerBufferSize: 10

3. 创建熔断器的回退处理

创建一个回退处理控制器 FallbackController.java

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class FallbackController {

    @GetMapping("/fallback")
    public String fallback() {
        return "This is a fallback response";
    }
}

一个完整的示例

为了更好地理解上述概念,我们来看一个完整的限流和流量控制配置示例。假设我们有一个电商平台,有用户服务、订单服务和产品服务。我们需要配置Gateway来实现限流、流量控制和熔断功能。

完整的Spring Cloud Gateway配置

spring:
  application:
    name: gateway-service
  redis:
    host: localhost
    port: 6379
  cloud:
    gateway:
      routes:
        - id: user-service
          uri: lb://USER-SERVICE
          predicates:
            - Path=/users/**
          filters:
            - name: RequestRateLimiter
              args:
                redis-rate-limiter:
                  replenishRate: 10
                  burstCapacity: 20
        - id: order-service
          uri: lb://ORDER-SERVICE
          predicates:
            - Path=/orders/**
        - id: product-service
          uri: lb://PRODUCT-SERVICE
          predicates:
            - Path=/products/**
          filters:
            - name: CircuitBreaker
              args:
                name: myCircuitBreaker
                fallbackUri: forward:/fallback
      default-filters:
        - name: RequestRateLimiter
          args:
            key-resolver: "#{@hostAddrKeyResolver}"
            redis-rate-limiter:
              replenishRate: 10
              burstCapacity: 20
server:
  port: 8080
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
    fetch-registry: true
    register-with-eureka: true
resilience4j:
  circuitbreaker:
    instances:
      myCircuitBreaker:
        registerHealthIndicator: true
        ringBufferSizeInClosedState: 5
        ringBufferSizeInHalfOpenState: 2
        waitDurationInOpenState: 10000
        failureRateThreshold: 50
        eventConsumerBufferSize: 10
management:
  endpoints:
    web:
      exposure:
        include: "*"

启动和测试

  1. 启动Redis服务:
docker run -d -p 6379:6379 redis
  1. 启动Eureka服务注册中心:
# 启动Eureka服务注册中心
java -jar eureka-server.jar
  1. 启动用户服务、订单服务和产品服务:
# 启动用户服务
java -jar user-service.jar

# 启动订单服务
java -jar order-service.jar

# 启动产品服务
java -jar product-service.jar
  1. 启动Gateway服务:
java -jar gateway-service.jar
  1. 测试限流和流量控制配置:
  • 访问 http://localhost:8080/users 应该受到限流控制,每秒最多10次请求,突发请求不超过20次。
  • 访问 http://localhost:8080/products 时,如果服务故障,会触发Resilience4j熔断器并返回回退响应。

结论

通过本文的讲解,你应该已经掌握了如何在Spring Cloud Gateway中实现限流和流量控制。我们详细介绍了如何使用Redis限流器、配置限流键解析器、自定义限流策略,以及使用Resilience4j实现限流和熔断,帮助你构建一个稳定、高可用的API网关。

这些就是关于【gateway 进阶】网关限流和流量控制的详细介绍。
这里是爪磕,感谢您的到来与关注,我们将持续为您带来优质的文章。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐