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