Sentinel 实战
概述
将 Sentinel 规则管理、数据源集成、框架整合等实战能力串联起来,构建完整的限流降级体系。
text
应用层
├── @SentinelResource 注解(业务代码埋点)
└── SentinelAspect 自动切入
规则层
├── 硬编码规则(@PostConstruct 初始化)
├── Nacos 动态规则(DataSource 扩展)
├── 控制台推送(OpenAPI / Dashboard)
└── 集群规则(Token Server + Token Client)
框架集成
├── Spring Cloud Gateway(GatewaySCG适配)
├── OpenFeign(Feign 拦截器)
├── RestTemplate(拦截器扩展)
└── Web Servlet(CommonFilter)
控制层
└── Dashboard(实时监控 / 规则管理 / 机器列表)一、规则动态配置
1.1 硬编码规则
java
@Component
public class FlowRuleInit {
@PostConstruct
public void initFlowRules() {
List<FlowRule> rules = new ArrayList<>();
FlowRule rule = new FlowRule();
rule.setResource("createOrder"); // 资源名
rule.setGrade(RuleConstant.FLOW_GRADE_QPS); // 限流依据 QPS
rule.setCount(1000); // 限流阈值
rule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_DEFAULT); // 快速失败
rule.setStrategy(RuleConstant.STRATEGY_DIRECT);
rules.add(rule);
// 关联流控:下单接口 QPS > 500 时,取消接口限流
FlowRule relateRule = new FlowRule();
relateRule.setResource("cancelOrder");
relateRule.setGrade(RuleConstant.FLOW_GRADE_QPS);
relateRule.setCount(50);
relateRule.setStrategy(RuleConstant.STRATEGY_RELATE);
relateRule.setRefResource("createOrder");
rules.add(relateRule);
FlowRuleManager.loadRules(rules);
}
}1.2 注解方式
java
@Service
public class OrderService {
@SentinelResource(
value = "createOrder",
blockHandler = "blockHandlerForCreateOrder",
blockHandlerClass = GlobalBlockHandler.class,
fallback = "fallbackForCreateOrder",
fallbackClass = GlobalFallback.class
)
public Order createOrder(OrderRequest request) {
// 业务逻辑
return orderRepository.save(request.toOrder());
}
}java
// 全局 BlockHandler(限流/降级异常处理)
public class GlobalBlockHandler {
public static Order blockHandlerForCreateOrder(OrderRequest request, BlockException e) {
// BlockException 包含限流/降级类型信息
if (e instanceof DegradeException) {
log.warn("createOrder degraded: {}", e.getMessage());
// 降级:返回本地缓存或兜底数据
return OrderCache.getDefault(request.getUserId());
}
log.warn("createOrder blocked: {} qps={}", e.getRule(),
((FlowRule) e.getRule()).getCount());
throw new BusinessException("FLOW_LIMITED", "当前下单人数过多,请稍后重试");
}
}
// 全局 Fallback(业务异常处理)
public class GlobalFallback {
public static Order fallbackForCreateOrder(OrderRequest request, Throwable e) {
log.error("createOrder failed: {}", e.getMessage());
throw new BusinessException("ORDER_FAILED", "下单失败,请重试");
}
}二、Nacos 数据源动态规则
2.1 依赖
xml
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>2.2 配置
yaml
spring:
cloud:
sentinel:
datasource:
# 流控规则
flow:
nacos:
server-addr: ${nacos.server-addr}
data-id: ${spring.application.name}-flow-rules
group-id: SENTINEL_GROUP
data-type: json
rule-type: flow
# 熔断降级规则
degrade:
nacos:
server-addr: ${nacos.server-addr}
data-id: ${spring.application.name}-degrade-rules
group-id: SENTINEL_GROUP
data-type: json
rule-type: degrade
# 热点参数规则
param-flow:
nacos:
server-addr: ${nacos.server-addr}
data-id: ${spring.application.name}-param-flow-rules
group-id: SENTINEL_GROUP
data-type: json
rule-type: param-flow2.3 Nacos 配置内容
json
// dataId: order-service-flow-rules
[
{
"resource": "createOrder",
"count": 1000,
"grade": 1,
"controlBehavior": 0,
"strategy": 0
},
{
"resource": "searchProduct",
"count": 5000,
"grade": 1,
"controlBehavior": 1,
"warmUpPeriodSec": 10
}
]
// dataId: order-service-degrade-rules
[
{
"resource": "paymentService",
"count": 0.5,
"grade": 0,
"timeWindow": 10,
"minRequestAmount": 5,
"statIntervalMs": 1000
}
]2.4 自定义数据源(拉模式)
java
@Component
public class CustomDataSourceInit implements CommandLineRunner {
@Override
public void run(String... args) {
// 从数据库读取规则
List<FlowRule> flowRules = flowRuleMapper.selectAll().stream()
.map(this::convert)
.collect(Collectors.toList());
FlowRuleManager.loadRules(flowRules);
// 从 Redis 读取规则
String rules = redisTemplate.opsForValue().get("sentinel:flow:order-service");
if (rules != null) {
List<FlowRule> redisRules = JSON.parseArray(rules, FlowRule.class);
FlowRuleManager.loadRules(redisRules);
}
}
}三、框架整合
3.1 Spring Cloud Gateway 整合
xml
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
</dependency>yaml
spring:
cloud:
gateway:
routes:
- id: order-service
uri: lb://order-service
predicates:
- Path=/api/orders/**
sentinel:
filter:
enabled: true
scg:
fallback:
mode: response
response-body: '{"code":429,"message":"Too many requests"}'
response-status: 429java
// Gateway 自定义 API 分组
@Configuration
public class GatewaySentinelConfig {
@PostConstruct
public void initGatewayRules() {
// API 分组
Set<ApiDefinition> apis = new HashSet<>();
apis.add(new ApiDefinition("order_service")
.setPredicateItems(new HashSet<ApiPredicateItem>() {{
add(new ApiPathPredicateItem()
.setPattern("/api/orders/**")
.setMatchStrategy(SentinelGatewayConstants.URL_MATCH_STRATEGY_PREFIX));
}}));
GatewayApiDefinitionManager.loadApiDefinitions(apis);
// 网关流控规则
Set<GatewayFlowRule> flowRules = new HashSet<>();
flowRules.add(new GatewayFlowRule("order_service")
.setCount(1000)
.setIntervalSec(1));
GatewayRuleManager.loadRules(flowRules);
}
}3.2 OpenFeign 整合
yaml
feign:
sentinel:
enabled: truejava
@FeignClient(name = "payment-service", fallback = PaymentFallback.class)
public interface PaymentFeignClient {
@PostMapping("/api/payments")
PaymentResult pay(@RequestBody PaymentRequest request);
}
@Component
public class PaymentFallback implements PaymentFeignClient {
@Override
public PaymentResult pay(PaymentRequest request) {
// 触发 Sentinel 降级时调用 Fallback
log.warn("payment-service degraded, using fallback");
return PaymentResult.failed("支付服务暂时不可用");
}
}3.3 RestTemplate 整合
java
@Configuration
public class SentinelRestTemplateConfig {
@Bean
@SentinelRestTemplate(
blockHandler = "handleBlock",
blockHandlerClass = SentinelRestTemplateHandler.class,
fallback = "handleFallback",
fallbackClass = SentinelRestTemplateHandler.class
)
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
public class SentinelRestTemplateHandler {
// blockHandler 参数必须与 RestTemplate 返回值一致
public static ClientHttpResponse handleBlock(HttpRequest request, byte[] body,
ClientHttpRequestExecution execution,
BlockException e) {
return new SimpleClientHttpResponse(429, "{\"code\":429,\"message\":\"Blocked\"}");
}
public static ClientHttpResponse handleFallback(HttpRequest request, byte[] body,
ClientHttpRequestExecution execution,
Throwable e) {
return new SimpleClientHttpResponse(500, "{\"code\":500,\"message\":\"Fallback\"}");
}
}四、控制台监控
4.1 整合 Dashboard
yaml
spring:
cloud:
sentinel:
transport:
dashboard: localhost:8080 # Sentinel Dashboard 地址
port: 8719 # 与 Dashboard 通信的端口
eager: true # 饥饿加载(否则首次访问才初始化)4.2 自定义监控指标
java
@Component
public class SentinelMetricsExporter {
private final Counter blockedCount = Metrics.counter("sentinel.blocked.total");
private final Counter passedCount = Metrics.counter("sentinel.passed.total");
@EventListener
public void onMetricsEvent(SentinelMetricsEvent event) {
// 导出到 Prometheus / Grafana
Map<Long, MetricNode> metrics = event.getMetrics();
metrics.forEach((time, node) -> {
if (node.getBlockQps() > 0) {
blockedCount.increment(node.getBlockQps());
}
if (node.getPassQps() > 0) {
passedCount.increment(node.getPassQps());
}
});
}
}五、集群流控
5.1 Token Server 配置
yaml
# Token Server(独立部署或嵌入一个应用)
sentinel:
cluster:
server:
enable: true
port: 18730
# 命名空间隔离
namespace-set:
- order-namespace5.2 Token Client 配置
yaml
spring:
cloud:
sentinel:
datasource:
flow:
nacos:
server-addr: ${nacos.server-addr}
data-id: ${spring.application.name}-cluster-flow
group-id: SENTINEL_CLUSTER
rule-type: flow
cluster:
client:
server-host: sentinel-token-server
server-port: 18730
request-timeout: 200
connect-timeout: 30005.3 Java 配置
java
// Token Client 启动时动态指定 Server
@Component
public class ClusterClientConfig implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) {
ClusterClientConfig config = new ClusterClientConfig();
config.setServerHost("192.168.1.100");
config.setServerPort(18730);
config.setRequestTimeout(200);
ClusterClientConfigManager.applyNewConfig(config);
// 指定哪些规则使用集群模式
FlowRule rule = new FlowRule();
rule.setResource("createOrder");
rule.setClusterMode(true);
rule.setClusterConfig(new ClusterFlowConfig());
FlowRuleManager.loadRules(List.of(rule));
}
}六、实战:电商大促全链路保障
6.1 各节点配置
text
首页(home-page)
├── 接口:/api/home/banner, /api/home/hot
├── 限流:QPS 10000
└── 降级:首页兜底缓存
搜索(search)
├── 接口:/api/search
├── 限流:QPS 5000
├── 热点参数:keyword(不同关键字不同阈值)
└── 降级:返回热门搜索缓存
商品详情(product-detail)
├── 接口:/api/products/{id}
├── 限流:QPS 3000
└── 降级:返回缓存商品信息
下单(createOrder)
├── 接口:/api/orders
├── 限流:QPS 1000
├── 熔断:支付服务异常率 > 30%,熔断 10s
└── 降级:加入购物车,稍后下单
支付(payment)
├── 接口:/api/payments
├── 限流:QPS 500
├── 熔断:三方支付 API 慢调用 > 5s,熔断 30s
└── 降级:返回支付失败提示6.2 动态规则推送
java
@Service
public class DynamicRuleService {
@Autowired
private ConfigService nacosConfigService;
// 大促前动态调整阈值
public void updateForFlashSale() {
// 读取现有规则
List<FlowRule> rules = FlowRuleManager.getRules();
for (FlowRule rule : rules) {
if ("createOrder".equals(rule.getResource())) {
// 大促期间放宽限流
rule.setCount(5000);
}
}
// 推送到 Nacos(触发所有实例更新)
nacosConfigService.publishConfig(
"order-service-flow-rules",
"SENTINEL_GROUP",
JSON.toJSONString(rules)
);
// 也写入本地
FlowRuleManager.loadRules(rules);
log.info("Flash sale flow rules updated: {}", rules);
}
}6.3 下单全流程保护
java
@Service
public class OrderFlowService {
@SentinelResource(
value = "createOrder",
blockHandler = "blockHandler",
fallback = "fallback"
)
public Order createOrder(OrderRequest request) {
// 1. 校验库存(远程调用商品服务)
StockResult stock = checkStock(request.getProductId(), request.getQuantity());
// 2. 锁定库存(远程调用库存服务)
lockStock(request.getProductId(), request.getQuantity());
// 3. 创建订单
Order order = orderRepository.save(request.toOrder());
// 4. 调用支付(远程调用支付服务)
PaymentResult payment = paymentFeignClient.pay(request.toPayment());
return order;
}
// 限流降级熔断都走 blockHandler
public Order blockHandler(OrderRequest request, BlockException e) {
// 加入购物车,稍后重试
cartService.add(request.getProductId(), request.getQuantity());
return Order.pending(request);
}
// 业务异常走 fallback
public Order fallback(OrderRequest request, Throwable e) {
log.error("createOrder error: {}", e.getMessage(), e);
throw new BusinessException("ORDER_FAILED", "下单失败");
}
}七、总结
| 知识点 | 说明 |
|---|---|
| 规则管理 | 硬编码 / 注解 / Nacos 动态推送 |
| 框架整合 | Gateway / Feign / RestTemplate 一体化 |
| 控制台 | Dashboard 实时监控 / 规则管理 |
| 集群流控 | Token Server + Token Client 架构 |
| 全链路 | 首页→搜索→详情→下单→支付逐层保护 |
| 动态调整 | Nacos 推送 + 本地加载双写 |
参考链接: