🚓 主要講解流控模式的 三種方式中的兩種:?直接、鏈路🚀
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