MST

星途 面试题库

面试题:微服务架构下Spring Cloud Alibaba如何实现服务限流

在基于Spring Cloud Alibaba的微服务架构中,通常会使用Sentinel来实现服务限流。请阐述Sentinel实现服务限流的核心原理,并且说明如何通过配置实现基于QPS的限流策略?
37.5万 热度难度
后端开发微服务架构

知识考点

AI 面试

面试题答案

一键面试

Sentinel实现服务限流的核心原理

  1. 流量统计:Sentinel 使用滑动窗口算法来统计流量。滑动窗口将时间划分为多个固定大小的时间窗口,每个窗口又分为多个更小的子窗口。当请求到达时,会落入对应的子窗口,并在该子窗口中记录请求的相关信息(如请求数量)。随着时间推移,窗口会滑动,新的子窗口进入统计范围,旧的子窗口离开,这样可以动态、准确地统计一段时间内的流量数据。
  2. 规则检查:Sentinel 会根据配置的限流规则对统计的流量数据进行检查。限流规则定义了流量的限制条件,如每秒允许通过的请求数(QPS)、并发线程数等。当请求到达时,Sentinel 会检查当前统计的流量是否超过了规则设定的阈值,如果超过则执行限流操作。
  3. 限流执行:一旦流量超过阈值,Sentinel 会执行限流操作,常见的限流策略有直接拒绝(默认策略)、Warm Up(预热模式,逐渐增加限流阈值)、排队等待(请求按照一定规则排队,在规定时间内处理)等。例如在直接拒绝策略下,超出阈值的请求会被立即拒绝,并返回限流错误信息给客户端。

通过配置实现基于QPS的限流策略

  1. 使用注解方式
    • 在 Spring Boot 项目中,首先确保引入了 Sentinel 的相关依赖。
    • 定义一个服务接口及实现类,例如:
public interface TestService {
    String test();
}

@Service
public class TestServiceImpl implements TestService {
    @Override
    @SentinelResource(value = "testResource", blockHandler = "testBlockHandler")
    public String test() {
        return "Hello, Sentinel";
    }

    public String testBlockHandler(BlockException ex) {
        return "限流了";
    }
}
- 在 `application.yml` 中配置基于 QPS 的限流规则:
spring:
  cloud:
    sentinel:
      transport:
        dashboard: localhost:8080 # Sentinel 控制台地址
      datasource:
        ds1:
          nacos:
            server-addr: localhost:8848
            dataId: ${spring.application.name}-sentinel
            groupId: DEFAULT_GROUP
            data-type: json
            rule-type: flow
- 在 Nacos 中添加限流规则数据,例如:
[
    {
        "resource": "testResource",
        "count": 2,
        "grade": 1,
        "limitApp": "default",
        "strategy": 0,
        "controlBehavior": 0
    }
]
上述配置中,`resource` 为注解中的 `value` 值,`count` 表示 QPS 阈值为 2,`grade` 为 1 表示基于 QPS 限流。

2. 使用 SPI 扩展方式: - 实现 FlowRuleManager 接口,例如:

import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRuleManager;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;

@Component
public class SentinelRuleInit {

    @PostConstruct
    public void initFlowRules() {
        List<FlowRule> rules = new ArrayList<>();
        FlowRule rule = new FlowRule();
        rule.setResource("testResource");
        rule.setCount(2);
        rule.setGrade(1);
        rule.setLimitApp("default");
        rules.add(rule);
        FlowRuleManager.loadRules(rules);
    }
}
上述代码直接在应用启动时通过代码方式设置了基于 QPS 的限流规则,`testResource` 资源的 QPS 阈值为 2。