Sentinel[超详细讲解]-4

发布于:2025-04-06 ⋅ 阅读:(55) ⋅ 点赞:(0)

🚓 主要讲解流控模式的 三种方式中的两种: 直接、链路🚀

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 "订单服务繁忙,请稍后再试";
    }
}

🈲 链路流控的注意事项

  1. 入口资源定义:必须明确定义入口资源,通常使用SphU.entry()@SentinelResource注解

  2. 配置要求:必须设置 🚑 spring.cloud.sentinel.web-context-unify=false