Sentinel[超详细讲解]-4
🚓 主要讲解流控模式的 三种方式中的两种: 直接、链路🚀
1️⃣ 直接模式
🚎 直接模式:对资源本身进行限流,例如对某个接口进行限流,当该接口的访问频率超过设定的阈值时,直接拒绝新的请求。
接口限流➡️ :对某个接口进行限流,例如对订单创建接口进行限流,当该接口的访问频率超过设定的阈值时,直接拒绝新的请求。
实现步骤:
1️⃣ 引入依赖:在项目中引入 Sentinel 相关依赖如com.alibaba.csp.sentinel.annotation.SentinelResource 等
2️⃣ 定义资源:指定要限流的资源名称,像示例中的 createOrder。
3️⃣ 配置规则:
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
@Service
public class OrderService {private static final String RESOURCE_NAME = "createOrder";@PostConstructprivate void initFlowRules() {List<FlowRule> rules = new ArrayList<>();FlowRule rule = new FlowRule();rule.setResource(RESOURCE_NAME);rule.setGrade(RuleConstant.FLOW_GRADE_QPS);rule.setCount(10);rule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_DEFAULT);rule.setLimitApp("default");rules.add(rule);FlowRuleManager.loadRules(rules);}@SentinelResource(value = RESOURCE_NAME, blockHandler = "createOrderBlockHandler")public String createOrder(String orderInfo) {return "订单创建成功: " + orderInfo;}public String createOrderBlockHandler(String orderInfo, BlockException ex) {return "请求过于频繁,请稍后再试!当前订单信息: " + orderInfo;}
上述代码在 OrderService 类中,initFlowRules 方法初始化限流规则,设置资源为 createOrder,基于 QPS 限流,阈值 10。createOrder 方法是业务逻辑,被限流时 createOrderBlockHandler 方法返回友好提示。
2️⃣ 链路模式
🚫 链路流控(Link Flow Control)是指对资源调用关系的入口进行流量控制。与普通流控不同,链路流控关注的是入口资源和被调用资源之间的关系。
使用步骤🚲
1️⃣ 在配置文件中启用链路流控模式
spring:cloud:sentinel:web-context-unify: false # 必须设置为false才能启用链路流控
2️⃣ 定义流控规则
控制台:在Sentinel控制台中定义链路流控规则,指定入口资源和被调用资源的关系,以及流控规则。
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import javax.annotation.PostConstruct;
import java.util.Collections;public class LinkFlowRuleConfig {private static final String ENTRY_RESOURCE = "orderWeb";private static final String TARGET_RESOURCE = "orderService";@PostConstructpublic void initLinkFlowRules() {FlowRule rule = new FlowRule();rule.setResource(TARGET_RESOURCE); // 被保护的资源rule.setGrade(RuleConstant.FLOW_GRADE_QPS); // 基于QPSrule.setCount(10); // 阈值rule.setLimitApp(ENTRY_RESOURCE); // 限制的入口资源FlowRuleManager.loadRules(Collections.singletonList(rule));}
}
这里定义入口资源 orderWeb 和被保护资源 orderService,设置基于 QPS 阈值 10 的限流规则 ✌️
3️⃣ 业务代码适配example
import com.alibaba.csp.sentinel.Entry;
import com.alibaba.csp.sentinel.SphU;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.springframework.stereotype.Service;@Service
public class OrderService {public String createOrder(String orderInfo) {// 1. 定义入口资源try (Entry entry = SphU.entry("orderWeb")) {// 2. 实际业务处理return doCreateOrder(orderInfo);} catch (BlockException e) {// 3. 处理流控逻辑return "创建订单请求被限流";}}@SentinelResource(value = "orderService", blockHandler = "orderServiceBlockHandler")private String doCreateOrder(String orderInfo) {// 业务逻辑return "订单创建成功: " + orderInfo;}public String orderServiceBlockHandler(String orderInfo, BlockException ex) {return "订单服务繁忙,请稍后再试";}
}
🈲 链路流控的注意事项
-
入口资源定义:必须明确定义入口资源,通常使用
SphU.entry()
或@SentinelResource
注解 -
配置要求:必须设置 🚑
spring.cloud.sentinel.web-context-unify=false