【分布式利器:限流】3、微服务分布式限流:Sentinel集群限流+Resilience4j使用教程

系列导读

上一篇我们讲解了网关层限流,实现了"流量入口拦截"。但在微服务架构中,服务间的调用流量(如订单服务调用库存服务)不会经过网关,若某服务因上游调用量突增而过载,仍会导致系统雪崩。

本文将聚焦"微服务层限流",详解两大主流方案:Sentinel集群限流(微服务生态首选,支持动态配置)和Resilience4j限流(轻量级注解式实现,适配Spring Boot),帮你实现服务间调用的流量防护。

一、微服务层限流的核心意义

  1. 服务间调用防护:防止上游服务调用量突增导致下游服务过载(如秒杀订单服务调用库存服务);
  2. 精细化维度控制:支持按接口、方法、参数等维度限流(如限制/inventory/deduct方法每秒最多500次调用);
  3. 适配微服务特性:支持动态调整阈值、集群限流(跨实例共享限流状态)、与服务注册中心/配置中心联动。

二、Sentinel集群限流实战(微服务生态首选)

Sentinel是阿里开源的微服务治理组件,支持限流、熔断、降级等功能,集群限流基于"Token Server/Client"架构,通过共享令牌分配状态,实现跨实例的全局限流。

1. 核心架构

  • Token Server:中心化令牌服务器,负责计算全局限流阈值,向Token Client分配令牌;
  • Token Client:嵌入微服务实例的客户端,每接收一个请求,向Token Server申请令牌,申请成功则通过,失败则限流;
  • 通信方式:基于Netty实现Token Client与Server的通信,性能高效。

2. 前置准备

  • 服务注册中心:如Nacos/Eureka(Sentinel需通过注册中心发现Token Server);
  • Sentinel Dashboard:可视化控制台,用于配置限流规则、监控流量;
  • 依赖引入:在微服务项目中添加Sentinel集群限流依赖。

3. 步骤1:部署Token Server(中心化令牌服务器)

3.1 引入依赖(Spring Boot项目)
xml 复制代码
<!-- pom.xml -->
<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-cluster-server-default</artifactId>
    <version>1.8.6</version>
</dependency>
<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-datasource-nacos</artifactId>
    <version>1.8.6</version>
</dependency>
3.2 配置Token Server(application.yml)
yaml 复制代码
spring:
  application:
    name: sentinel-token-server
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848  # Nacos注册中心地址

sentinel:
  transport:
    port: 8719  # 与Dashboard通信端口
    dashboard: 127.0.0.1:8080  # Sentinel Dashboard地址
  cluster:
    server:
      port: 8720  # Token Server通信端口(供Client连接)
      enable: true  # 启用Token Server模式
      flow:
        default-threshold: 500  # 全局默认限流阈值(每秒500个请求)
3.3 启动Token Server

启动项目后,在Sentinel Dashboard中可看到SENTINEL-TOKEN-SERVER实例已注册。

4. 步骤2:配置Token Client(微服务实例)

4.1 引入依赖(微服务项目,如order-service)
xml 复制代码
<!-- pom.xml -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
    <version>2021.0.4.0</version>
</dependency>
<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-cluster-client-default</artifactId>
    <version>1.8.6</version>
</dependency>
4.2 配置Token Client(application.yml)
yaml 复制代码
spring:
  application:
    name: order-service
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
    sentinel:
      transport:
        port: 8719
        dashboard: 127.0.0.1:8080
      cluster:
        client:
          enable: true  # 启用Token Client模式
          server-host: 127.0.0.1  # Token Server地址
          server-port: 8720  # Token Server通信端口
      datasource:
        # 从Nacos获取限流规则(动态配置)
        ds1:
          nacos:
            server-addr: 127.0.0.1:8848
            data-id: order-service-sentinel-rules
            group-id: DEFAULT_GROUP
            rule-type: flow  # 限流规则类型

5. 步骤3:配置集群限流规则(Sentinel Dashboard)

  1. 访问Sentinel Dashboard(默认地址http://127.0.0.1:8080);
  2. 选择order-service实例,进入"簇点链路",找到需要限流的接口(如/order/create);
  3. 点击"流控",配置集群限流规则:
    • 阈值类型:QPS;
    • 单机阈值:100(单实例阈值,全局阈值=单机阈值×实例数);
    • 流控模式:集群流控;
    • 点击"新增",规则会同步到Nacos。

6. 代码中使用Sentinel限流(注解式)

java 复制代码
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/order")
public class OrderController {

    // 对create接口启用Sentinel限流,资源名=order:create
    @SentinelResource(value = "order:create", blockHandler = "handleFlowLimit")
    @PostMapping("/create")
    public String createOrder() {
        // 订单创建逻辑
        return "订单创建成功";
    }

    // 限流后的降级处理方法(参数需与原方法一致,最后加BlockException参数)
    public String handleFlowLimit(BlockException e) {
        return "当前订单创建请求过多,请稍后重试(限流提示)";
    }
}

7. 避坑点

  • Token Server高可用:生产环境需部署多个Token Server(通过注册中心集群发现),避免单点故障;
  • 阈值计算:集群限流阈值=单机阈值×实例数,需根据服务实例数动态调整;
  • 通信端口:Token Client与Server的通信端口(8720)需开放,避免防火墙拦截;
  • 规则持久化:需将限流规则持久化到Nacos/Apollo,否则Sentinel Dashboard重启后规则丢失。

三、Resilience4j限流实战(轻量级注解式)

Resilience4j是一款轻量级的微服务治理组件(替代Hystrix),支持限流、熔断、重试等功能,无侵入式设计(基于注解),适配Spring Boot生态,分布式限流需结合Redis实现。

1. 核心特性

  • 轻量级:仅依赖Slf4j和Jackson,无其他重量级依赖;
  • 注解式:通过@RateLimiter注解快速启用限流;
  • 灵活配置:支持YAML/Properties配置,可动态调整阈值;
  • 分布式支持:结合Redis存储限流状态(如滑动窗口计数器)。

2. 步骤1:引入依赖(Spring Boot项目)

xml 复制代码
<!-- pom.xml -->
<dependency>
    <groupId>io.github.resilience4j</groupId>
    <artifactId>resilience4j-spring-boot2</artifactId>
    <version>1.7.1</version>
</dependency>
<dependency>
    <groupId>io.github.resilience4j</groupId>
    <artifactId>resilience4j-ratelimiter</artifactId>
    <version>1.7.1</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

3. 步骤2:配置限流规则(application.yml)

yaml 复制代码
spring:
  redis:
    host: 127.0.0.1
    port: 6379

# Resilience4j限流配置
resilience4j:
  ratelimiter:
    instances:
      # 限流实例名:orderCreateLimiter(与注解中的name对应)
      orderCreateLimiter:
        limitForPeriod: 100  # 每个周期(默认1秒)的最大请求数
        limitRefreshPeriod: 1000  # 周期时长(毫秒)
        timeoutDuration: 0  # 请求获取令牌的超时时间(0=立即拒绝)
        # 分布式限流配置(使用Redis存储限流状态)
        registry:
          type: redis
          redis:
            redisTemplateBeanName: redisTemplate  # Spring RedisTemplate Bean名

4. 步骤3:代码中使用Resilience4j限流(注解式)

java 复制代码
import io.github.resilience4j.ratelimiter.annotation.RateLimiter;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/order")
public class OrderController {

    // 启用限流,实例名=orderCreateLimiter,fallbackMethod=限流降级方法
    @RateLimiter(name = "orderCreateLimiter", fallbackMethod = "handleFlowLimit")
    @PostMapping("/create")
    public String createOrder() {
        // 订单创建逻辑
        return "订单创建成功";
    }

    // 限流降级处理方法(参数需与原方法一致)
    public String handleFlowLimit(Exception e) {
        return "当前订单创建请求过多,请稍后重试(Resilience4j限流提示)";
    }
}

5. 自定义限流维度(如按用户ID限流)

Resilience4j默认按"限流实例名"限流,若需按用户ID等自定义维度,需实现RateLimiterRegistryKeyResolver

java 复制代码
import io.github.resilience4j.ratelimiter.RateLimiter;
import io.github.resilience4j.ratelimiter.RateLimiterRegistry;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;

@Component
public class CustomRateLimiterManager {

    private final RateLimiterRegistry rateLimiterRegistry;
    private final StringRedisTemplate redisTemplate;

    public CustomRateLimiterManager(RateLimiterRegistry rateLimiterRegistry, StringRedisTemplate redisTemplate) {
        this.rateLimiterRegistry = rateLimiterRegistry;
        this.redisTemplate = redisTemplate;
    }

    // 按用户ID获取限流实例
    public RateLimiter getRateLimiterByUserId(HttpServletRequest request) {
        String userId = request.getHeader("X-User-ID");
        String limiterName = "orderCreateLimiter:" + userId;
        // 从Registry中获取或创建限流实例
        return rateLimiterRegistry.rateLimiter(limiterName);
    }
}

6. 避坑点

  • Redis依赖:分布式场景必须引入spring-boot-starter-data-redis,否则仅支持单机限流;
  • 超时时间:timeoutDuration=0表示请求获取令牌失败时立即拒绝,若需排队等待,可设置为500ms(根据业务调整);
  • 限流实例名:注解中的name需与配置文件中的instances名称一致,否则无法加载规则;
  • 降级方法:降级方法的参数需与原方法完全一致,否则会抛出NoSuchMethodException

四、Sentinel vs Resilience4j限流对比

特性 Sentinel集群限流 Resilience4j限流
生态适配 适配Spring Cloud Alibaba生态 适配Spring Boot/Spring Cloud生态
分布式支持 原生支持集群限流(Token Server) 需结合Redis实现分布式限流
配置方式 可视化控制台+配置中心(动态调整) 配置文件+注解(支持动态调整)
功能丰富度 支持限流、熔断、降级、监控等 支持限流、熔断、重试等(功能精简)
侵入性 注解式+代码埋点(低侵入) 纯注解式(无侵入)
适用场景 中大型微服务集群(需丰富功能) 中小型微服务(追求轻量级)

五、下一篇预告

前面讲解的限流方案均适用于"同步请求场景",但分布式系统中存在大量异步场景(如秒杀订单异步通知、日志采集),需通过消息队列实现削峰填谷。

下一篇将聚焦"异步场景限流",详解消息队列(Kafka/RocketMQ)的生产者/消费者限流配置,以及动态限流(结合服务伸缩)的实现,帮你覆盖全场景限流需求!

相关推荐
梁bk19 分钟前
Redis 多级缓存架构学习笔记
redis·缓存·架构
一起学开源1 小时前
分布式基石:CAP定理与ACID的取舍艺术
分布式·微服务·架构·流程图·软件工程
雁于飞1 小时前
分布式基础
java·spring boot·分布式·spring·wpf·cloud native
语落心生2 小时前
Apache Geaflow推理框架Geaflow-infer 解析系列(一)Geaflow-Infer 模块简介
架构
语落心生2 小时前
Apache Geaflow推理框架Geaflow-infer 解析系列(三)环境初始化流程
架构
语落心生2 小时前
Apache Geaflow推理框架Geaflow-infer 解析系列(二)整体架构设计
架构
鹏北海3 小时前
多标签页登录状态同步:一个简单而有效的解决方案
前端·面试·架构
Xの哲學4 小时前
Linux 分区表深度技术剖析
linux·网络·算法·架构·边缘计算
TracyCoder1235 小时前
微服务概念理解学习笔记
学习·微服务·架构