第30集SpringCloudAlibaba全网最全讲解之Sentinel | 字数总计: 4.9k | 阅读时长: 22分钟 | 阅读量:
引言 在微服务架构中,服务间的调用关系复杂,一个服务的异常可能会影响整个系统的稳定性。流量控制、熔断降级是保障微服务系统稳定性的重要手段。SpringCloudAlibaba Sentinel作为阿里巴巴开源的流量控制和熔断降级组件,提供了完整的微服务保护解决方案。
Sentinel以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性,具有实时监控、规则配置、动态推送等特性,是微服务架构中不可或缺的组件。
本文将深入讲解Sentinel的核心概念、配置方式、规则管理以及实际应用场景,帮助开发者掌握微服务流量控制和熔断降级的设计与实现。
Sentinel核心概念 1. 什么是流量控制 流量控制是微服务保护的重要手段,通过限制请求的速率和数量,防止系统因流量过大而崩溃。Sentinel的流量控制具有以下特点:
实时监控 :实时统计请求的QPS、响应时间等指标
动态规则 :支持动态配置和推送流量控制规则
多种策略 :支持QPS限流、并发线程数限流、系统负载限流
精确控制 :支持基于调用来源、接口、参数等维度的精确限流
2. 什么是熔断降级 熔断降级是当服务出现异常时,快速失败并返回预设的降级结果,避免级联故障。Sentinel的熔断降级具有以下特点:
异常检测 :自动检测服务异常和响应时间
快速失败 :异常时立即返回降级结果
自动恢复 :异常恢复后自动恢复正常调用
多种策略 :支持异常比例、异常数量、响应时间等熔断策略
3. Sentinel架构特点 1 2 3 4 5 6 7 8 9 10 11 12 13 graph TB A[客户端请求] --> B[Sentinel Core] B --> C{流量控制} C -->|通过| D[业务逻辑] C -->|限流| E[限流处理] D --> F{熔断检测} F -->|正常| G[正常响应] F -->|异常| H[熔断降级] I[Sentinel Dashboard] --> B J[规则配置] --> I K[监控数据] --> I
核心特性:
轻量级:核心库无额外依赖
实时监控:提供实时监控和告警
规则管理:支持动态规则配置和推送
多种场景:支持Web、RPC、消息等多种场景
生态集成:与Spring Cloud、Dubbo等框架深度集成
Sentinel Dashboard安装与配置 1. 环境准备 系统要求:
JDK 1.8+
内存:1GB+
网络:需要访问Nacos等注册中心
下载Sentinel Dashboard:
1 2 3 4 5 wget https://github.com/alibaba/Sentinel/releases/download/1.8.6/sentinel-dashboard-1.8.6.jar docker pull bladex/sentinel-dashboard:latest
2. 启动Sentinel Dashboard 方式1:直接启动
1 2 3 4 5 6 7 8 9 java -jar sentinel-dashboard-1.8.6.jar java -jar sentinel-dashboard-1.8.6.jar \ --server.port=8080 \ --nacos.server-addr=localhost:8848 \ --nacos.namespace=sentinel \ --nacos.group-id=SENTINEL_GROUP
方式2:Docker启动
1 2 3 4 5 6 7 8 9 docker run -d -p 8080:8080 bladex/sentinel-dashboard:latest docker run -d -p 8080:8080 \ -e NACOS_SERVER_ADDR=localhost:8848 \ -e NACOS_NAMESPACE=sentinel \ -e NACOS_GROUP_ID=SENTINEL_GROUP \ bladex/sentinel-dashboard:latest
3. 访问控制台 访问地址:
主要功能:
实时监控:查看应用实时QPS、响应时间等指标
规则管理:配置流量控制、熔断降级规则
集群管理:管理集群限流规则
系统保护:配置系统负载保护规则
Spring Boot集成Sentinel 1. 项目依赖配置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 <dependencies > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-web</artifactId > </dependency > <dependency > <groupId > com.alibaba.cloud</groupId > <artifactId > spring-cloud-starter-alibaba-sentinel</artifactId > </dependency > <dependency > <groupId > com.alibaba.csp</groupId > <artifactId > sentinel-transport-simple-http</artifactId > </dependency > <dependency > <groupId > com.alibaba.cloud</groupId > <artifactId > spring-cloud-starter-alibaba-nacos-discovery</artifactId > </dependency > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-actuator</artifactId > </dependency > </dependencies > <dependencyManagement > <dependencies > <dependency > <groupId > com.alibaba.cloud</groupId > <artifactId > spring-cloud-alibaba-dependencies</artifactId > <version > 2022.0.0.0</version > <type > pom</type > <scope > import</scope > </dependency > </dependencies > </dependencyManagement >
2. 配置文件设置 application.yml:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 server: port: 8080 spring: application: name: sentinel-demo-service cloud: nacos: discovery: server-addr: localhost:8848 namespace: dev group: DEFAULT_GROUP sentinel: transport: dashboard: localhost:8080 port: 8719 datasource: flow: nacos: server-addr: localhost:8848 dataId: ${spring.application.name}-flow-rules groupId: SENTINEL_GROUP rule-type: flow degrade: nacos: server-addr: localhost:8848 dataId: ${spring.application.name}-degrade-rules groupId: SENTINEL_GROUP rule-type: degrade param-flow: nacos: server-addr: localhost:8848 dataId: ${spring.application.name}-param-flow-rules groupId: SENTINEL_GROUP rule-type: param-flow system: nacos: server-addr: localhost:8848 dataId: ${spring.application.name}-system-rules groupId: SENTINEL_GROUP rule-type: system authority: nacos: server-addr: localhost:8848 dataId: ${spring.application.name}-authority-rules groupId: SENTINEL_GROUP rule-type: authority logging: level: com.alibaba.csp.sentinel: DEBUG
3. 启动类配置 1 2 3 4 5 6 7 @SpringBootApplication @EnableDiscoveryClient public class SentinelDemoApplication { public static void main (String[] args) { SpringApplication.run(SentinelDemoApplication.class, args); } }
流量控制功能 1. QPS限流 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 @RestController @RequestMapping("/api") @Slf4j public class UserController { @Autowired private UserService userService; @GetMapping("/user/{id}") @SentinelResource( value = "getUserById", blockHandler = "handleBlock", fallback = "handleFallback" ) public ResponseEntity<User> getUser (@PathVariable Long id) { log.info("获取用户信息,用户ID: {}" , id); User user = userService.findById(id); return ResponseEntity.ok(user); } public ResponseEntity<User> handleBlock (Long id, BlockException ex) { log.warn("用户服务限流,用户ID: {}, 异常: {}" , id, ex.getMessage()); User fallbackUser = new User (); fallbackUser.setId(id); fallbackUser.setName("限流用户" ); fallbackUser.setMessage("服务繁忙,请稍后重试" ); return ResponseEntity.ok(fallbackUser); } public ResponseEntity<User> handleFallback (Long id, Throwable ex) { log.error("用户服务异常,用户ID: {}, 异常: {}" , id, ex.getMessage()); User fallbackUser = new User (); fallbackUser.setId(id); fallbackUser.setName("降级用户" ); fallbackUser.setMessage("服务暂时不可用" ); return ResponseEntity.ok(fallbackUser); } }
2. 并发线程数限流 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 @Service @Slf4j public class OrderService { @SentinelResource( value = "createOrder", blockHandler = "handleCreateOrderBlock", fallback = "handleCreateOrderFallback" ) public Order createOrder (Order order) { log.info("创建订单: {}" , order.getOrderNo()); try { Thread.sleep(1000 ); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } order.setId(System.currentTimeMillis()); order.setStatus("CREATED" ); return order; } public Order handleCreateOrderBlock (Order order, BlockException ex) { log.warn("创建订单限流: {}, 异常: {}" , order.getOrderNo(), ex.getMessage()); Order fallbackOrder = new Order (); fallbackOrder.setOrderNo(order.getOrderNo()); fallbackOrder.setStatus("BLOCKED" ); fallbackOrder.setMessage("系统繁忙,请稍后重试" ); return fallbackOrder; } public Order handleCreateOrderFallback (Order order, Throwable ex) { log.error("创建订单异常: {}, 异常: {}" , order.getOrderNo(), ex.getMessage()); Order fallbackOrder = new Order (); fallbackOrder.setOrderNo(order.getOrderNo()); fallbackOrder.setStatus("FAILED" ); fallbackOrder.setMessage("订单创建失败" ); return fallbackOrder; } }
3. 热点参数限流 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 @RestController @RequestMapping("/api/product") @Slf4j public class ProductController { @Autowired private ProductService productService; @GetMapping("/detail/{productId}") @SentinelResource( value = "getProductDetail", blockHandler = "handleGetProductDetailBlock", fallback = "handleGetProductDetailFallback" ) public ResponseEntity<Product> getProductDetail ( @PathVariable Long productId, @RequestParam(required = false) String userId) { log.info("获取商品详情,商品ID: {}, 用户ID: {}" , productId, userId); Product product = productService.getProductDetail(productId, userId); return ResponseEntity.ok(product); } public ResponseEntity<Product> handleGetProductDetailBlock ( Long productId, String userId, BlockException ex) { log.warn("商品详情限流,商品ID: {}, 用户ID: {}, 异常: {}" , productId, userId, ex.getMessage()); Product fallbackProduct = new Product (); fallbackProduct.setId(productId); fallbackProduct.setName("限流商品" ); fallbackProduct.setMessage("商品详情服务繁忙,请稍后重试" ); return ResponseEntity.ok(fallbackProduct); } public ResponseEntity<Product> handleGetProductDetailFallback ( Long productId, String userId, Throwable ex) { log.error("商品详情异常,商品ID: {}, 用户ID: {}, 异常: {}" , productId, userId, ex.getMessage()); Product fallbackProduct = new Product (); fallbackProduct.setId(productId); fallbackProduct.setName("降级商品" ); fallbackProduct.setMessage("商品详情服务暂时不可用" ); return ResponseEntity.ok(fallbackProduct); } }
熔断降级功能 1. 异常比例熔断 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 @Service @Slf4j public class PaymentService { @SentinelResource( value = "processPayment", blockHandler = "handleProcessPaymentBlock", fallback = "handleProcessPaymentFallback" ) public PaymentResult processPayment (PaymentRequest request) { log.info("处理支付请求: {}" , request.getOrderNo()); if (Math.random() < 0.3 ) { throw new RuntimeException ("支付处理失败" ); } PaymentResult result = new PaymentResult (); result.setOrderNo(request.getOrderNo()); result.setStatus("SUCCESS" ); result.setAmount(request.getAmount()); result.setTransactionId("TXN" + System.currentTimeMillis()); return result; } public PaymentResult handleProcessPaymentBlock ( PaymentRequest request, BlockException ex) { log.warn("支付处理限流: {}, 异常: {}" , request.getOrderNo(), ex.getMessage()); PaymentResult result = new PaymentResult (); result.setOrderNo(request.getOrderNo()); result.setStatus("BLOCKED" ); result.setMessage("支付服务繁忙,请稍后重试" ); return result; } public PaymentResult handleProcessPaymentFallback ( PaymentRequest request, Throwable ex) { log.error("支付处理异常: {}, 异常: {}" , request.getOrderNo(), ex.getMessage()); PaymentResult result = new PaymentResult (); result.setOrderNo(request.getOrderNo()); result.setStatus("FAILED" ); result.setMessage("支付处理失败" ); return result; } }
2. 异常数量熔断 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 @Service @Slf4j public class InventoryService { @SentinelResource( value = "checkInventory", blockHandler = "handleCheckInventoryBlock", fallback = "handleCheckInventoryFallback" ) public InventoryResult checkInventory (Long productId, Integer quantity) { log.info("检查库存,商品ID: {}, 数量: {}" , productId, quantity); if (Math.random() < 0.2 ) { throw new RuntimeException ("库存检查失败" ); } InventoryResult result = new InventoryResult (); result.setProductId(productId); result.setRequestedQuantity(quantity); result.setAvailableQuantity(100 ); result.setSufficient(quantity <= 100 ); return result; } public InventoryResult handleCheckInventoryBlock ( Long productId, Integer quantity, BlockException ex) { log.warn("库存检查限流,商品ID: {}, 数量: {}, 异常: {}" , productId, quantity, ex.getMessage()); InventoryResult result = new InventoryResult (); result.setProductId(productId); result.setRequestedQuantity(quantity); result.setSufficient(false ); result.setMessage("库存服务繁忙,请稍后重试" ); return result; } public InventoryResult handleCheckInventoryFallback ( Long productId, Integer quantity, Throwable ex) { log.error("库存检查异常,商品ID: {}, 数量: {}, 异常: {}" , productId, quantity, ex.getMessage()); InventoryResult result = new InventoryResult (); result.setProductId(productId); result.setRequestedQuantity(quantity); result.setSufficient(false ); result.setMessage("库存服务暂时不可用" ); return result; } }
3. 响应时间熔断 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 @Service @Slf4j public class NotificationService { @SentinelResource( value = "sendNotification", blockHandler = "handleSendNotificationBlock", fallback = "handleSendNotificationFallback" ) public NotificationResult sendNotification (NotificationRequest request) { log.info("发送通知: {}" , request.getType()); try { int delay = (int ) (Math.random() * 3000 ) + 500 ; Thread.sleep(delay); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } NotificationResult result = new NotificationResult (); result.setRequestId(request.getRequestId()); result.setType(request.getType()); result.setStatus("SENT" ); result.setMessage("通知发送成功" ); return result; } public NotificationResult handleSendNotificationBlock ( NotificationRequest request, BlockException ex) { log.warn("通知发送限流: {}, 异常: {}" , request.getType(), ex.getMessage()); NotificationResult result = new NotificationResult (); result.setRequestId(request.getRequestId()); result.setType(request.getType()); result.setStatus("BLOCKED" ); result.setMessage("通知服务繁忙,请稍后重试" ); return result; } public NotificationResult handleSendNotificationFallback ( NotificationRequest request, Throwable ex) { log.error("通知发送异常: {}, 异常: {}" , request.getType(), ex.getMessage()); NotificationResult result = new NotificationResult (); result.setRequestId(request.getRequestId()); result.setType(request.getType()); result.setStatus("FAILED" ); result.setMessage("通知发送失败" ); return result; } }
系统负载保护 1. 系统规则配置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 @Configuration public class SentinelSystemConfig { @PostConstruct public void initSystemRules () { List<SystemRule> rules = new ArrayList <>(); SystemRule cpuRule = new SystemRule (); cpuRule.setMetricType(SystemRule.CPU_USAGE); cpuRule.setCount(0.8 ); rules.add(cpuRule); SystemRule rtRule = new SystemRule (); rtRule.setMetricType(SystemRule.AVG_RT); rtRule.setCount(200 ); rules.add(rtRule); SystemRule threadRule = new SystemRule (); threadRule.setMetricType(SystemRule.CONCURRENT_THREAD); threadRule.setCount(100 ); rules.add(threadRule); SystemRule qpsRule = new SystemRule (); qpsRule.setMetricType(SystemRule.QPS); qpsRule.setCount(1000 ); rules.add(qpsRule); SystemRule loadRule = new SystemRule (); loadRule.setMetricType(SystemRule.SYSTEM_LOAD); loadRule.setCount(2.0 ); rules.add(loadRule); SystemRuleManager.loadRules(rules); } }
2. 系统保护处理 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 @Component @Slf4j public class SystemProtectionHandler { @EventListener public void handleSystemBlock (SystemBlockException ex) { log.warn("系统保护触发: {}" , ex.getMessage()); recordSystemProtectionEvent(ex); sendSystemProtectionAlert(ex); } private void recordSystemProtectionEvent (SystemBlockException ex) { log.info("系统保护事件记录: {}" , ex.getRule()); } private void sendSystemProtectionAlert (SystemBlockException ex) { log.warn("发送系统保护告警: {}" , ex.getMessage()); } }
规则管理 1. 动态规则配置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 @RestController @RequestMapping("/api/sentinel") @Slf4j public class SentinelRuleController { @Autowired private FlowRuleManager flowRuleManager; @Autowired private DegradeRuleManager degradeRuleManager; @PostMapping("/flow-rule") public ResponseEntity<String> addFlowRule (@RequestBody FlowRuleRequest request) { try { FlowRule rule = new FlowRule (); rule.setResource(request.getResource()); rule.setGrade(request.getGrade()); rule.setCount(request.getCount()); rule.setStrategy(request.getStrategy()); rule.setControlBehavior(request.getControlBehavior()); rule.setWarmUpPeriodSec(request.getWarmUpPeriodSec()); rule.setMaxQueueingTimeMs(request.getMaxQueueingTimeMs()); List<FlowRule> rules = new ArrayList <>(); rules.add(rule); FlowRuleManager.loadRules(rules); log.info("流量控制规则配置成功: {}" , rule); return ResponseEntity.ok("流量控制规则配置成功" ); } catch (Exception e) { log.error("流量控制规则配置失败" , e); return ResponseEntity.status(500 ).body("配置失败: " + e.getMessage()); } } @PostMapping("/degrade-rule") public ResponseEntity<String> addDegradeRule (@RequestBody DegradeRuleRequest request) { try { DegradeRule rule = new DegradeRule (); rule.setResource(request.getResource()); rule.setGrade(request.getGrade()); rule.setCount(request.getCount()); rule.setTimeWindow(request.getTimeWindow()); rule.setMinRequestAmount(request.getMinRequestAmount()); rule.setSlowRatioThreshold(request.getSlowRatioThreshold()); List<DegradeRule> rules = new ArrayList <>(); rules.add(rule); DegradeRuleManager.loadRules(rules); log.info("熔断降级规则配置成功: {}" , rule); return ResponseEntity.ok("熔断降级规则配置成功" ); } catch (Exception e) { log.error("熔断降级规则配置失败" , e); return ResponseEntity.status(500 ).body("配置失败: " + e.getMessage()); } } @GetMapping("/rules") public ResponseEntity<Map<String, Object>> getRules () { Map<String, Object> rules = new HashMap <>(); rules.put("flowRules" , FlowRuleManager.getRules()); rules.put("degradeRules" , DegradeRuleManager.getRules()); rules.put("systemRules" , SystemRuleManager.getRules()); return ResponseEntity.ok(rules); } }
2. 规则数据源配置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 @Configuration public class SentinelDataSourceConfig { @Autowired private NacosConfigService nacosConfigService; @PostConstruct public void initDataSource () { ReadableDataSource<String, List<FlowRule>> flowRuleDataSource = new NacosDataSource <>( nacosConfigService, "sentinel-demo-service-flow-rules" , "SENTINEL_GROUP" , source -> JSON.parseObject(source, new TypeReference <List<FlowRule>>() {}) ); FlowRuleManager.register2Property(flowRuleDataSource.getProperty()); ReadableDataSource<String, List<DegradeRule>> degradeRuleDataSource = new NacosDataSource <>( nacosConfigService, "sentinel-demo-service-degrade-rules" , "SENTINEL_GROUP" , source -> JSON.parseObject(source, new TypeReference <List<DegradeRule>>() {}) ); DegradeRuleManager.register2Property(degradeRuleDataSource.getProperty()); } }
监控与告警 1. 实时监控 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 @Component @Slf4j public class SentinelMonitor { private final MeterRegistry meterRegistry; private final Counter blockCounter; private final Timer responseTimer; public SentinelMonitor (MeterRegistry meterRegistry) { this .meterRegistry = meterRegistry; this .blockCounter = Counter.builder("sentinel.blocks.total" ) .description("Total number of blocked requests" ) .register(meterRegistry); this .responseTimer = Timer.builder("sentinel.response.duration" ) .description("Response duration" ) .register(meterRegistry); } @EventListener public void handleBlockEvent (BlockException ex) { blockCounter.increment( Tags.of( "resource" , ex.getRule().getResource(), "rule" , ex.getRule().getClass().getSimpleName() ) ); } public void recordResponseTime (String resource, Duration duration) { responseTimer.record(duration, Tags.of("resource" , resource)); } }
2. 健康检查 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 @Component public class SentinelHealthIndicator implements HealthIndicator { @Override public Health health () { try { boolean isEnabled = SentinelConfig.getConfig().isEnabled(); if (isEnabled) { return Health.up() .withDetail("sentinel" , "enabled" ) .withDetail("flowRules" , FlowRuleManager.getRules().size()) .withDetail("degradeRules" , DegradeRuleManager.getRules().size()) .build(); } else { return Health.down() .withDetail("sentinel" , "disabled" ) .build(); } } catch (Exception e) { return Health.down() .withDetail("sentinel" , "error" ) .withDetail("error" , e.getMessage()) .build(); } } }
3. 告警配置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 @Component @Slf4j public class SentinelAlertService { @EventListener public void handleBlockEvent (BlockException ex) { if (ex.getRule() instanceof FlowRule) { sendFlowBlockAlert((FlowRule) ex.getRule()); } if (ex.getRule() instanceof DegradeRule) { sendDegradeBlockAlert((DegradeRule) ex.getRule()); } if (ex.getRule() instanceof SystemRule) { sendSystemBlockAlert((SystemRule) ex.getRule()); } } private void sendFlowBlockAlert (FlowRule rule) { log.warn("流量控制告警: 资源 {} 触发限流,QPS: {}" , rule.getResource(), rule.getCount()); sendAlert("流量控制告警" , String.format("资源 %s 触发限流,QPS: %d" , rule.getResource(), rule.getCount())); } private void sendDegradeBlockAlert (DegradeRule rule) { log.warn("熔断降级告警: 资源 {} 触发熔断" , rule.getResource()); sendAlert("熔断降级告警" , String.format("资源 %s 触发熔断" , rule.getResource())); } private void sendSystemBlockAlert (SystemRule rule) { log.warn("系统保护告警: 系统负载过高,指标: {}" , rule.getMetricType()); sendAlert("系统保护告警" , String.format("系统负载过高,指标: %d" , rule.getMetricType())); } private void sendAlert (String title, String message) { log.info("发送告警: {} - {}" , title, message); } }
常见问题与解决方案 1. 规则不生效 问题描述: 配置的Sentinel规则没有生效
解决方案:
1 2 3 4 5 6 7 8 spring: cloud: sentinel: enabled: true transport: dashboard: localhost:8080 port: 8719
1 2 3 4 5 @SentinelResource(value = "getUserById") public User getUser (Long id) { }
2. 降级不生效 问题描述: 配置的降级规则没有生效
解决方案:
1 2 3 4 5 6 7 8 9 10 11 12 13 @SentinelResource( value = "getUserById", fallback = "handleFallback" // 方法名要正确 ) public User getUser (Long id) { } public User handleFallback (Long id, Throwable ex) { }
3. 规则配置丢失 问题描述: 重启后规则配置丢失
解决方案:
1 2 3 4 5 6 7 8 9 10 11 spring: cloud: sentinel: datasource: flow: nacos: server-addr: localhost:8848 dataId: ${spring.application.name}-flow-rules groupId: SENTINEL_GROUP rule-type: flow
4. 性能影响 问题描述: 启用Sentinel后系统性能下降
解决方案:
1 2 3 4 5 6 7 spring: cloud: sentinel: sampler: type: adaptive count: 1000
最佳实践总结 1. 规则设计原则
合理阈值 :根据系统实际能力设置合理的限流阈值
分级保护 :对不同重要性的接口设置不同的保护策略
动态调整 :根据系统负载动态调整规则参数
监控告警 :建立完善的监控和告警机制
2. 降级策略
快速失败 :异常时快速返回降级结果
用户体验 :降级结果要保证良好的用户体验
数据一致性 :降级操作要保证数据的一致性
自动恢复 :系统恢复后要能自动恢复正常调用
3. 监控运维
实时监控 :监控关键指标和异常情况
趋势分析 :分析系统性能趋势和瓶颈
告警机制 :建立完善的告警体系
容量规划 :基于监控数据进行容量规划
总结 SpringCloudAlibaba Sentinel为微服务架构提供了完整的流量控制和熔断降级解决方案。通过本文的详细讲解,我们了解了:
核心概念 :流量控制、熔断降级的基本原理和作用
安装配置 :Sentinel Dashboard的安装和配置方法
集成使用 :Spring Boot与Sentinel的集成配置
流量控制 :QPS限流、并发线程数限流、热点参数限流
熔断降级 :异常比例、异常数量、响应时间熔断
系统保护 :系统负载保护规则和配置
规则管理 :动态规则配置和数据源管理
监控告警 :实时监控、健康检查、告警配置
问题解决 :常见问题的排查和解决方案
最佳实践 :规则设计、降级策略、监控运维
在实际应用中,建议:
根据系统特点合理设计流量控制和熔断降级规则
建立完善的监控和告警机制
定期分析监控数据,优化系统性能
注意规则配置的持久化和动态更新
通过掌握这些知识和技能,开发者可以构建稳定、可靠的微服务系统,有效应对高并发和异常情况。
参考资料
Sentinel官方文档
SpringCloudAlibaba官方文档
Sentinel Dashboard使用指南
微服务流量控制最佳实践
Sentinel示例代码