🚓 主要讲解流控模式的 三种方式中的两种: 直接、链路🚀
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";
@PostConstruct
private 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";
@PostConstruct
public void initLinkFlowRules() {
FlowRule rule = new FlowRule();
rule.setResource(TARGET_RESOURCE); // 被保护的资源
rule.setGrade(RuleConstant.FLOW_GRADE_QPS); // 基于QPS
rule.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