在 Spring Boot 3 中实现限流可以采用多种方式,下面为你介绍常见的三种:

1、使用 Sentinel 实现限流

Sentinel 是阿里巴巴开源的一款流量控制组件,具备实时监控、限流、熔断等功能。

步骤

  • 添加依赖:在pom.xml里添加 Sentinel 的依赖。

    1
    2
    3
    4
    5
    
    <dependency>
       <groupId>com.alibaba.csp</groupId>
       <artifactId>sentinel-spring-boot-starter</artifactId>
       <version>1.8.6</version>
    </dependency>
    
  • 配置规则:创建一个配置类来设置限流规则。

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    
    import com.alibaba.csp.sentinel.slots.block.RuleConstant;
    import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
    import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
    import org.springframework.context.annotation.Configuration;
    
    import javax.annotation.PostConstruct;
    import java.util.ArrayList;
    import java.util.List;
    
    @Configuration
    public class SentinelConfig {
    
        @PostConstruct
        public void initFlowRules() {
            List<FlowRule> rules = new ArrayList<>();
            FlowRule rule = new FlowRule();
            rule.setResource("yourResourceName");
            rule.setCount(10); // 每秒最多允许10个请求
            rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
            rule.setLimitApp("default");
            rules.add(rule);
            FlowRuleManager.loadRules(rules);
        }
    }
    
  • 添加注解:在需要限流的方法上添加@SentinelResource注解。

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    
    import com.alibaba.csp.sentinel.annotation.SentinelResource;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    public class HelloController {
    
        @GetMapping("/hello")
        @SentinelResource(value = "yourResourceName", blockHandler = "handleBlock")
        public String hello() {
            return "Hello, World!";
        }
    
        public String handleBlock(BlockException ex) {
            return "Blocked by Sentinel: " + ex.getClass().getSimpleName();
        }
    }
    

2、使用 Resilience4j 实现限流

Resilience4j 是一个轻量级的容错库,提供了限流、熔断等功能。

步骤

  • 添加依赖:在pom.xml里添加 Resilience4j 的依赖。

    1
    2
    3
    4
    5
    
    <dependency>
    <groupId>io.github.resilience4j</groupId>
    <artifactId>resilience4j-spring-boot3</artifactId>
    <version>2.0.2</version>
    </dependency>
    
  • 配置限流:在application.yml中进行限流配置。

    1
    2
    3
    4
    5
    6
    7
    
    resilience4j:
     ratelimiter:
       instances:
         myRateLimiter:
          limitForPeriod: 10
          limitRefreshPeriod: 1s
          timeoutDuration: 0
    
  • 使用注解:在需要限流的方法上添加@RateLimiter注解。

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    
    import io.github.resilience4j.ratelimiter.annotation.RateLimiter;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    public class HelloController {
    
        @GetMapping("/hello")
        @RateLimiter(name = "myRateLimiter", fallbackMethod = "fallback")
        public String hello() {
            return "Hello, World!";
        }
    
        public String fallback(Exception e) {
            return "Rate limit exceeded";
        }
    }
    

3、使用 Spring Cloud Gateway 实现限流

如果你使用 Spring Cloud Gateway 作为 API 网关,它自带了限流过滤器。

步骤

  • 添加依赖:在pom.xml里添加 Spring Cloud Gateway 的依赖。

    1
    2
    3
    4
    
    <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
    </dependency>
    
  • 配置限流:在application.yml中配置限流规则。

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    
    spring:
      cloud:
        gateway:
          routes:
            - id: my_route
              uri: http://example.org
              predicates:
                - Path=/api/**
              filters:
                - name: RequestRateLimiter
                  args:
                    redis-rate-limiter.replenishRate: 10
                    redis-rate-limiter.burstCapacity: 20
                    key-resolver: "#{@userKeyResolver}"
    
  • 实现 KeyResolver:创建一个KeyResolver来确定限流的键。

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    
    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 userKeyResolver() {
            return new KeyResolver() {
                @Override
                public Mono<String> resolve(ServerWebExchange exchange) {
                    return Mono.just(exchange.getRequest().getRemoteAddress().getAddress().getHostAddress());
                }
            };
        }
    }
    

以上三种方法都能在 Spring Boot 3 中实现限流,你可根据具体需求来选择合适的方案。