Sentinel的流量统计核心基于滑动时间窗口算法,这是实现精准流量控制的关键。我们先从一个生活场景理解:假设你开了一家网红奶茶店,为了防止顾客过多挤爆店面,你决定每分钟只接待10位顾客。但简单计数会遇到临界值问题——比如在59秒突然涌入10人,下一秒又进来10人,实际上2秒内接待了20人。滑动窗口就像把1分钟拆成6个10秒的格子,始终统计最近6个格子的总数,这样就能平滑控制流量。
Sentinel的具体实现通过LeapArray类管理多个WindowWrap窗口,每个窗口包含:
java复制// 窗口数据结构示例
public class WindowWrap {
private long windowStart; // 窗口开始时间戳
private MetricBucket counter; // 统计指标
private long windowLength; // 窗口长度(毫秒)
}
当请求进入时,会通过当前时间戳计算所属窗口位置:
java复制// 计算当前时间对应的窗口索引
long timeId = timestamp / windowLength;
int idx = (int)(timeId % array.length());
这种设计带来两大优势:
Sentinel的处理流程像工厂流水线,每个环节(Slot)各司其职。想象快递分拣中心:
java复制// 典型插槽链执行流程
public void entry() throws BlockException {
// 1. 构建调用链节点
nodeSelectorSlot.entry();
// 2. 初始化集群统计节点
clusterBuilderSlot.entry();
// 3. 实时数据统计
statisticSlot.entry();
// 4. 流量控制判断
flowSlot.entry();
}
这种责任链模式的优势在于:
电商秒杀需要解决两大问题:
最佳实践配置:
java复制// 秒杀接口限流规则
List<FlowRule> rules = new ArrayList<>();
FlowRule rule = new FlowRule();
rule.setResource("seckill_" + itemId);
rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
rule.setCount(500); // 单机QPS阈值
rule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER); // 匀速排队
rule.setMaxQueueingTimeMs(1000); // 最大等待时间
rules.add(rule);
FlowRuleManager.loadRules(rules);
关键配置项说明:
| 参数 | 建议值 | 作用 |
|---|---|---|
| grade | QPS | 按请求量限流 |
| count | 根据压测结果 | 单机承载能力 |
| behavior | RATE_LIMITER | 平滑流量曲线 |
| maxQueueingTimeMs | 1000ms | 用户可接受等待时间 |
面对消息队列消费场景,推荐组合策略:
java复制rule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER);
rule.setMaxQueueingTimeMs(500);
java复制rule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_WARM_UP);
rule.setWarmUpPeriodSec(30); // 30秒预热期
实测案例:某物流系统通过以下配置将峰值10万QPS平滑为持续2小时的平稳消费:
针对商品详情页的热门SKU,需要特殊限流策略:
java复制ParamFlowRule rule = new ParamFlowRule("getProductDetail")
.setParamIdx(0) // 第一个参数是商品ID
.setCount(50); // 默认阈值
// 为爆款商品设置更高阈值
ParamFlowItem item = new ParamFlowItem()
.setObject("10086") // 商品ID
.setClassType(int.class.getName())
.setCount(200); // 特殊阈值
rule.setParamFlowItemList(Collections.singletonList(item));
服务依赖的熔断需要多维判断:
java复制DegradeRule rule = new DegradeRule();
rule.setResource("queryUserInfo");
// 异常比例模式
rule.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_RATIO);
rule.setCount(0.5); // 50%异常
rule.setTimeWindow(10); // 熔断10秒
rule.setMinRequestAmount(20); // 最小触发样本
熔断策略对比:
| 策略类型 | 适用场景 | 优缺点 |
|---|---|---|
| 异常比例 | 依赖服务不稳定 | 能应对偶发异常 |
| 慢调用比例 | 数据库查询 | 防止慢查询堆积 |
| 异常数 | 弱依赖服务 | 简单但不够精准 |
推荐使用Nacos作为规则配置中心:
yaml复制# Spring Cloud Alibaba配置示例
spring:
cloud:
sentinel:
datasource:
ds1:
nacos:
server-addr: localhost:8848
dataId: sentinel-rules
ruleType: flow
通过改造MetricLogTask实现自定义监控:
java复制public class CustomMetricExporter extends MetricWriter {
@Override
public void write(Map<String, MetricNode> metrics) {
metrics.forEach((resource, node) -> {
// 转换格式发送到Prometheus
prometheusClient.gauge("qps", node.getPassQps(), "resource", resource);
});
}
}
常见监控指标:
我在实际项目中遇到过因未配置系统保护规则导致CPU被打满的情况。后来增加了以下配置后稳定运行:
java复制SystemRule systemRule = new SystemRule();
systemRule.setHighestSystemLoad(4.0); // 当load1 > 4时触发
systemRule.setHighestCpuUsage(0.8); // CPU使用率阈值
SystemRuleManager.loadRules(Collections.singletonList(systemRule));