什么是“链路模式”
链路模式(也叫关联模式或入口限流)是指根据资源调用链路进行限流,只针对从某个入口进入的请求进行限流,而不是对所有请求进行限流。
问题背景
- 默认行为:Sentinel默认只将Controller中的方法标记为资源
- context整合:Sentinel默认会将所有Controller方法整合到同一个调用上下文中
- 问题:这导致无法区分同一个资源被不同入口调用的情况
示例场景说明
假设:
- 资源A:商品查询方法
- 入口1:用户直接访问商品详情页面
- 入口2:从订单页面跳转到商品详情
如果没有链路模式:
- 无论是从哪个入口来的请求,都会计入同一个资源统计
- 无法实现“只限制从订单页面来的商品查询,而不限制直接访问”
配置解析
1. 标记非Controller资源
@RestControllerpublicclassGoodsController{// 使用@SentinelResource注解标记资源@SentinelResource("queryGoods")publicvoidqueryGoods(){System.err.println("查询商品");}}2. 关闭context整合
spring:cloud:sentinel:web-context-unify:false# 关键配置3. Sentinel控制台设置
在控制台中配置流控规则时:
- 选择“链路模式”
- 指定资源名(如:queryGoods)
- 指定入口资源(如:/order/detail)
工作流程
- 用户通过入口A访问 → 触发链路A → 应用对应的流控规则
- 用户通过入口B访问 → 触发链路B → 应用另一套流控规则
- 相同的资源(queryGoods)在不同链路上有独立的流控统计
实际应用场景
- 优先级控制:VIP用户入口不限流,普通用户入口限流
- 来源区分:内部系统调用不限流,外部API调用限流
- 业务隔离:促销活动入口独立限流,不影响正常业务流程
优势
- 更细粒度的流量控制
- 避免“一刀切”的限流策略
- 提升系统资源的合理分配
- 增强系统的稳定性
这就是Sentinel链路模式的核心价值:让同一个资源在不同调用链路上可以有不同的流控策略。
不过,关闭context整合并不会导致所有Controller接口都需要手动加注解才能限流。这点我澄清一下:
实际情况分析
1.关闭context整合的作用
spring:cloud:sentinel:web-context-unify:false# 只是关闭调用链路的整合这个配置只影响链路模式的正常工作,不会影响普通限流。
2.Controller接口的默认行为
即使关闭了context整合:
- Controller中的接口仍然会被Sentinel自动监控
- 不需要加
@SentinelResource注解也能进行常规限流 - 常规的QPS/线程数限流仍然有效
3.什么情况下需要加@SentinelResource?
| 场景 | 是否需要注解 | 说明 |
|---|---|---|
| 常规限流 | ❌ 不需要 | Controller方法自动被Sentinel识别 |
| 链路模式限流 | ✅ 需要 | 需要明确标记资源名称 |
| 降级规则 | ✅ 需要 | 需要明确标记资源进行熔断降级 |
| 热点参数限流 | ✅ 需要 | 需要明确标记资源 |
| 系统规则 | ❌ 不需要 | 系统级别的,不依赖具体资源 |
4.实际配置示例
@RestControllerpublicclassGoodsController{// 场景1:常规限流 - 不需要注解@GetMapping("/goods/{id}")publicGoodsgetGoods(@PathVariableLongid){// 这个方法会自动被Sentinel监控// 可以在控制台配置对这个接口的QPS限流returngoodsService.getById(id);}// 场景2:链路模式 - 需要注解@SentinelResource("queryGoodsInfo")// 明确标记资源名publicGoodsDetailqueryGoodsDetail(Longid){// 这个方法被标记后,可以配置链路限流// 例如:从订单入口调用限流100,从搜索入口调用不限流returngoodsService.getDetail(id);}}5.Sentinel的自动资源发现机制
Spring Cloud Sentinel自动发现以下资源:
- ✅所有
@RequestMapping注解的方法 - ✅所有
@GetMapping、@PostMapping等方法 - ✅所有Controller中的public方法
6.验证方法
你可以在Sentinel控制台看到:
关闭context整合后:
- 资源列表仍然显示所有Controller接口
- 可以对它们配置常规流控规则
链路模式配置时:
- 只有用
@SentinelResource标记的资源才能配置"关联"或"链路"模式 - 需要指定"入口资源"和"资源名"
- 只有用
总结
关闭web-context-unify: false的唯一影响是:
- 让链路模式能够正常工作
- Controller接口的常规限流完全不受影响
- 只有当你需要使用链路模式这种特定流控时,才需要加
@SentinelResource注解
一句话,即使关闭了context整合,Controller接口仍然会被Sentinel自动监控和保护!