2026/4/11 23:27:23
网站建设
项目流程
太原微网站建设,西安市做网站的公司,网站服务器好,做技术分享网站有哪些Sentinel从入门到实战#xff1a;流量卫兵守护你的微服务
一、为什么需要限流组件#xff1f;
在分布式系统和微服务架构日益普及的今天#xff0c;流量控制已经成为保障系统稳定性的核心手段。让我们先看一个真实的生产案例#xff1a;
1.1 真实案例#xff1a;某电商…Sentinel从入门到实战流量卫兵守护你的微服务一、为什么需要限流组件在分布式系统和微服务架构日益普及的今天流量控制已经成为保障系统稳定性的核心手段。让我们先看一个真实的生产案例1.1 真实案例某电商平台崩溃事故2023年双11大促期间某中型电商平台在秒杀活动开启后5分钟内系统全面崩溃。事后分析发现流量峰值正常QPS约500秒杀开始瞬间飙升至50000系统表现所有服务实例CPU 100%内存溢出数据库连接池耗尽影响范围不仅秒杀服务崩溃连带影响首页、浏览、下单等所有核心功能直接损失约300万交易额无法完成品牌声誉受损无限流保护的系统图1无限流保护的系统架构 - 流量冲击场景如上图所示没有限流保护的系统面临多重问题① 资源耗尽问题当突发流量到来时系统会按照先来先服务的原则处理请求。流量超出系统承载能力后CPU持续高负载上下文切换频繁内存快速分配导致GC压力增大最终OOM数据库连接池被占满新请求无法获取连接② 雪崩效应微服务架构中服务间存在依赖关系。当下游服务因流量过大而响应缓慢或失败时上游服务持有的连接/线程无法释放资源逐渐耗尽故障会沿着调用链向上传播最终导致整个系统崩溃一个服务的故障可能影响整个业务链路③ 用户体验恶化正常用户的请求无法得到及时响应页面长时间加载或直接报错用户流失信任度下降1.2 传统解决方案的局限性面对流量冲击传统方案通常包括方案优点缺点垂直扩容简单直接成本高有上限无法应对瞬时流量缓存减轻数据库压力缓存击穿/穿透/雪崩问题热点数据难以处理消息队列削峰填谷增加系统复杂度实时性下降人工限流灵活性高响应慢无法精确控制容易误操作这些方案要么成本过高要么效果有限要么需要大量人力投入。我们需要一个更加智能化、自动化的流量控制解决方案。二、Sentinel简介2.1 Sentinel是什么Sentinel是阿里巴巴开源的一款面向分布式服务架构的流量控制组件主要以流量为切入点从流量控制、熔断降级、系统负载保护等多个维度来帮助您保障微服务的稳定性。Sentinel系统架构2.2 核心特性① 丰富的应用场景秒杀系统瞬间大流量限流消息削峰平滑处理突发流量熔断降级保护核心服务不被拖垮实时监控全方位流量监控大盘② 完备的实时监控Sentinel提供实时的监控功能可以监控QPS每秒查询数RT响应时间成功率拒绝数③ 广泛的开源生态Sentinel提供与主流框架的整合Spring Cloud / Spring BootDubbogRPCRocketMQ④ 完善的SPI扩展点Sentinel提供简单易用、完善的SPI扩展接口可以通过实现扩展接口来快速定制逻辑。三、Sentinel核心原理3.1 责任链模式设计Sentinel的核心工作原理基于责任链模式通过一系列的Slot槽位串联成一个处理链。Sentinel核心原理图3Sentinel核心工作原理当请求进入时会依次经过以下Slot① NodeSelectorSlot负责收集资源的调用路径构建树状结构的调用链路为每个资源创建DefaultNode② ClusterBuilderSlot构建ClusterNode统计集群维度某个资源的调用情况用于存储聚合后的统计信息③ LogSlot记录异常日志便于问题排查和定位④ StatisticSlot实时统计指标的Slot记录秒级、分钟级的指标数据为后续的规则判断提供数据支撑⑤ AuthoritySlot黑白名单控制基于来源的流量控制⑥ FlowSlot流量控制Slot根据配置的限流规则进行判断超出阈值则抛出FlowException⑦ DegradeSlot熔断降级Slot根据熔断规则判断是否需要熔断触发熔断则抛出DegradeException3.2 核心概念① 资源Resource资源是Sentinel的核心概念可以是Java代码中的一段代码一个接口一个方法// 定义资源方式一使用SentinelResource注解 SentinelResource(value getUserInfo, blockHandler handleBlock) public User getUserInfo(Long id) { return userService.getUser(id); } // 定义资源方式二使用try-catch try (Entry entry SphU.entry(getUserInfo)) { return userService.getUser(id); } catch (BlockException e) { return handleBlock(e); }② 规则RuleSentinel支持多种规则类型规则类型说明配置参数FlowRule流量控制规则resource, limitApp, grade, count, strategy, controlBehaviorDegradeRule熔断降级规则resource, grade, count, timeWindow, minRequestAmountAuthorityRule访问控制规则resource, limitApp, strategyParamFlowRule热点参数规则resource, paramIdx, grade, count, durationInSec③ 上下文ContextContext保存了调用链路的元数据包括入口节点EntranceNode当前节点CurrentNode调用来源Origin四、流量控制详解4.1 限流流程Sentinel的限流处理流程如下图所示限流流程图4Sentinel限流处理流程4.2 限流维度① QPS限流每秒查询数限流适用于API接口限流防止接口被刷保护下游服务// QPS限流配置 ListFlowRule rules new ArrayList(); FlowRule rule new FlowRule(); rule.setResource(getUserInfo); rule.setGrade(RuleConstant.FLOW_GRADE_QPS); // QPS维度 rule.setCount(100); // 每秒最多100个请求 rule.setStrategy(RuleConstant.STRATEGY_DIRECT); // 直接拒绝 rule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_DEFAULT); // 默认行为 rules.add(rule); FlowRuleManager.loadRules(rules);② 线程数限流并发线程数限流适用于业务处理时间长需要限制并发量的场景// 线程数限流配置 FlowRule rule new FlowRule(); rule.setResource(processOrder); rule.setGrade(RuleConstant.FLOW_GRADE_THREAD); // 线程数维度 rule.setCount(10); // 最多10个线程并发处理4.3 限流策略① 直接拒绝Default默认策略超出阈值直接拒绝请求rule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_DEFAULT); // 抛出FlowException: Blocked by Sentinel (flow limiting)② Warm Up预热从初始阈值缓慢上升到最大阈值rule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_WARM_UP); rule.setCount(100); // 最大阈值 rule.setWarmUpPeriodSec(10); // 预热时长10秒 // 实际效果前10秒从 100/3 ≈ 33 逐渐增加到100适用于秒杀系统预热缓存预热系统启动阶段流量控制③ 排队等待Throttling请求在队列中排队超时则拒绝rule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER); rule.setCount(100); // 每秒100个请求 rule.setMaxQueueingTimeMs(500); // 最大排队等待时间500ms适用于消息削峰填谷请求可以适当延迟处理的场景4.4 关联限流当关联的资源达到阈值时对当前资源限流// 当userLogin资源QPS超过50时限制getUserInfo rule.setStrategy(RuleConstant.STRATEGY_RELATE); rule.setRefResource(userLogin); rule.setCount(50);适用场景登录接口压力大时限制其他非核心接口支付接口压力大时限制下单接口五、熔断降级详解5.1 熔断机制熔断器模式Circuit Breaker Pattern是一种保护性设计模式Sentinel实现了完整的熔断降级机制。熔断机制降级机制图5Sentinel熔断降级机制熔断器有三种状态① Closed关闭状态正常状态请求正常通过监控失败率和响应时间异常达到阈值时转换为Open状态② Open开启状态熔断状态直接拒绝所有请求持续熔断时长timeWindow结束后进入Half-Open状态③ Half-Open半开状态探测状态允许部分请求通过如果请求成功说明服务已恢复转为Closed状态如果请求失败说明服务仍未恢复转回Open状态5.2 熔断策略① 慢调用比例SLOW_REQUEST_RATIO当资源的响应时间超过最大RT时被标记为慢调用。慢调用比例超过阈值时触发熔断ListDegradeRule rules new ArrayList(); DegradeRule rule new DegradeRule(); rule.setResource(orderService); rule.setGrade(RuleConstant.DEGRADE_GRADE_SLOW_REQUEST_RATIO); rule.setCount(500); // 慢调用阈值RT 500ms rule.setSlowRatioThreshold(0.5); // 慢调用比例阈值50% rule.setTimeWindow(10); // 熔断时长10秒 rule.setMinRequestAmount(5); // 最小请求数5 rule.setStatIntervalMs(1000); // 统计时长1秒 rules.add(rule); DegradeRuleManager.loadRules(rules);② 异常比例EXCEPTION_RATIO当资源的异常比例超过阈值时触发熔断DegradeRule rule new DegradeRule(); rule.setResource(paymentService); rule.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_RATIO); rule.setCount(0.5); // 异常比例阈值50% rule.setTimeWindow(10); // 熔断时长10秒 rule.setMinRequestAmount(5); // 最小请求数5③ 异常数EXCEPTION_COUNT当资源的异常数超过阈值时触发熔断DegradeRule rule new DegradeRule(); rule.setResource(smsService); rule.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_COUNT); rule.setCount(10); // 异常数阈值10个 rule.setTimeWindow(10); // 熔断时长10秒 rule.setMinRequestAmount(5); // 最小请求数55.3 降级处理当请求被限流或熔断时需要进行降级处理SentinelResource( value getUserInfo, blockHandler handleBlock, // 限流/熔断时的处理 fallback handleFallback // 异常时的处理 ) public User getUserInfo(Long id) { return userService.getUser(id); } // 限流/熔断处理 public User handleBlock(Long id, BlockException e) { // 返回默认值或缓存数据 return User.getDefaultUser(); } // 异常处理 public User handleFallback(Long id, Throwable e) { log.error(获取用户信息异常, e); return User.getDefaultUser(); }六、生产实战案例6.1 电商秒杀系统以下是一个电商秒杀系统使用Sentinel的完整案例生产实战案例图6生产实战电商秒杀系统Sentinel应用架构场景描述正常流量约2000 QPS秒杀流量峰值可达50000 QPS核心需求保护库存服务不被击垮配置方案Configuration public class SentinelConfig { PostConstruct public void initRules() { initSeckillFlowRules(); initOrderDegradeRules(); initStockFlowRules(); } /** * 秒杀接口限流规则 */ private void initSeckillFlowRules() { ListFlowRule rules new ArrayList(); // 用户维度限流 FlowRule userRule new FlowRule(); userRule.setResource(seckill:userId); userRule.setGrade(RuleConstant.FLOW_GRADE_QPS); userRule.setCount(5); // 单用户每秒最多5次请求 userRule.setParamIdx(0); // 第一个参数作为userId rules.add(userRule); // 接口维度限流 FlowRule apiRule new FlowRule(); apiRule.setResource(/api/seckill/doSeckill); apiRule.setGrade(RuleConstant.FLOW_GRADE_QPS); apiRule.setCount(10000); // 接口整体限制10000 QPS apiRule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_WARM_UP); apiRule.setWarmUpPeriodSec(10); // 10秒预热 rules.add(apiRule); FlowRuleManager.loadRules(rules); } /** * 订单服务熔断规则 */ private void initOrderDegradeRules() { ListDegradeRule rules new ArrayList(); DegradeRule rule new DegradeRule(); rule.setResource(orderService:createOrder); rule.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_RATIO); rule.setCount(0.3); // 异常比例30% rule.setTimeWindow(10); // 熔断10秒 rule.setMinRequestAmount(10); rules.add(rule); DegradeRuleManager.loadRules(rules); } /** * 库存服务限流规则 */ private void initStockFlowRules() { ListFlowRule rules new ArrayList(); // 线程数限流保护数据库 FlowRule rule new FlowRule(); rule.setResource(stockService:decreaseStock); rule.setGrade(RuleConstant.FLOW_GRADE_THREAD); rule.setCount(100); // 最多100个线程同时操作 rules.add(rule); FlowRuleManager.loadRules(rules); } }核心接口实现RestController RequestMapping(/api/seckill) public class SeckillController { Autowired private SeckillService seckillService; /** * 秒杀接口 */ PostMapping(/doSeckill) SentinelResource( value seckill:doSeckill, blockHandler handleBlock, fallback handleFallback ) public Result doSeckill(RequestParam Long userId, RequestParam Long goodsId) { try { boolean success seckillService.doSeckill(userId, goodsId); return success ? Result.success(秒杀成功) : Result.error(秒杀失败); } catch (Exception e) { log.error(秒杀异常, e); return Result.error(系统繁忙请稍后重试); } } /** * 限流处理 */ public Result handleBlock(Long userId, Long goodsId, BlockException e) { if (e instanceof FlowException) { return Result.error(当前请求过多请稍后再试); } else if (e instanceof DegradeException) { return Result.error(服务暂时不可用请稍后再试); } return Result.error(系统繁忙); } /** * 异常处理 */ public Result handleFallback(Long userId, Long goodsId, Throwable e) { log.error(秒杀异常: userId{}, goodsId{}, userId, goodsId, e); return Result.error(系统异常请稍后重试); } } Service public class SeckillServiceImpl implements SeckillService { Autowired private RedisTemplate redisTemplate; Autowired private StockService stockService; Autowired private OrderService orderService; Override SentinelResource( value seckill:doSeckill:inner, blockHandler handleBlock ) public boolean doSeckill(Long userId, Long goodsId) { // 1. 校验用户是否重复购买 String key seckill:user: userId :goods: goodsId; Boolean isBought redisTemplate.hasKey(key); if (Boolean.TRUE.equals(isBought)) { throw new BusinessException(您已经参与过此秒杀活动); } // 2. 预扣减库存 Long stock redisTemplate.opsForValue().decrement(seckill:stock: goodsId); if (stock null || stock 0) { redisTemplate.opsForValue().increment(seckill:stock: goodsId); throw new BusinessException(库存不足); } // 3. 创建订单可能触发熔断 try { Order order orderService.createOrder(userId, goodsId); // 标记用户已购买 redisTemplate.opsForValue().set(key, 1, 24, TimeUnit.HOURS); return true; } catch (DegradeException e) { // 订单服务熔断回滚库存 redisTemplate.opsForValue().increment(seckill:stock: goodsId); return false; } } public boolean handleBlock(Long userId, Long goodsId, BlockException e) { log.warn(秒杀请求被限流: userId{}, goodsId{}, userId, goodsId); return false; } }监控效果接口QPS被控制在10000左右库存服务线程数不超过100订单服务异常时自动熔断不影响其他服务系统整体可用性达到99.95%6.2 第三方API调用保护调用外部接口时使用Sentinel进行保护Service public class ThirdPartyServiceImpl { /** * 调用第三方支付接口 */ SentinelResource( value thirdParty:payment, blockHandler handleBlock, fallback handleFallback, fallbackClass ThirdPartyFallback.class ) public PaymentResult payment(PaymentRequest request) { try { // 调用第三方支付接口 return thirdPartyClient.payment(request); } catch (Exception e) { throw new ThirdPartyException(支付接口调用失败, e); } } public PaymentResult handleBlock(PaymentRequest request, BlockException e) { // 返回默认结果后续异步重试 return PaymentResult.pending(); } } /** * 降级处理类 */ public class ThirdPartyFallback { public static PaymentResult handleFallback(PaymentRequest request, Throwable e) { log.error(支付接口异常使用降级逻辑, e); // 返回降级结果走人工处理流程 return PaymentResult.manual(); } } Configuration public class ThirdPartySentinelConfig { PostConstruct public void initRules() { // 慢调用熔断 DegradeRule slowRule new DegradeRule(); slowRule.setResource(thirdParty:payment); slowRule.setGrade(RuleConstant.DEGRADE_GRADE_SLOW_REQUEST_RATIO); slowRule.setCount(1000); // RT 1秒 slowRule.setSlowRatioThreshold(0.5); // 50%慢调用 slowRule.setTimeWindow(30); // 熔断30秒 slowRule.setMinRequestAmount(5); // 异常比例熔断 DegradeRule exceptionRule new DegradeRule(); exceptionRule.setResource(thirdParty:payment); exceptionRule.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_RATIO); exceptionRule.setCount(0.3); // 30%异常 exceptionRule.setTimeWindow(30); exceptionRule.setMinRequestAmount(5); DegradeRuleManager.loadRules(Arrays.asList(slowRule, exceptionRule)); } }6.3 系统自适应保护Sentinel提供了系统自适应保护规则根据系统的负载情况自动调整Configuration public class SystemProtectConfig { PostConstruct public void initSystemRules() { ListSystemRule rules new ArrayList(); // CPU使用率保护 SystemRule cpuRule new SystemRule(); cpuRule.setHighestSystemLoad(0.8); // CPU使用率超过80%时触发 rules.add(cpuRule); // 平均RT保护 SystemRule rtRule new SystemRule(); rtRule.setAvgRt(1000); // 平均RT超过1000ms时触发 rules.add(rtRule); // 并发线程数保护 SystemRule threadRule new SystemRule(); threadRule.setMaxThread(500); // 并发线程超过500时触发 rules.add(threadRule); // 入口QPS保护 SystemRule qpsRule new SystemRule(); qpsRule.setQps(10000); // QPS超过10000时触发 rules.add(qpsRule); SystemRuleManager.loadRules(rules); } }七、Sentinel Dashboard使用7.1 Dashboard部署# 下载Dashboard wget https://github.com/alibaba/Sentinel/releases/download/1.8.6/sentinel-dashboard-1.8.6.jar # 启动Dashboard java -Dserver.port8080 -Dcsp.sentinel.dashboard.serverlocalhost:8080 \ -Dproject.namesentinel-dashboard \ -jar sentinel-dashboard-1.8.6.jar7.2 客户端配置# application.yml spring: application: name: sentinel-demo cloud: sentinel: transport: dashboard: localhost:8080 port: 8719 eager: true datasource: flow: type: file file: classpath:sentinel-flow.json degrade: type: file file: classpath:sentinel-degrade.json7.3 Dashboard功能Dashboard提供了以下功能实时监控查看QPS、RT、成功率等指标规则配置动态配置流控规则、熔断规则等集群流控配置集群限流机器列表查看连接到Dashboard的所有机器八、总结Sentinel作为一款成熟的流量控制组件在微服务架构中发挥着重要作用核心价值流量整形平滑处理突发流量服务保障保护核心服务稳定实时监控全方位流量监控快速失败避免资源耗尽适用场景秒杀/抢购场景第三方API调用微服务链路保护系统自适应保护通过合理使用Sentinel可以有效提升系统的稳定性和可用性让微服务架构更加健壮。