MST

星途 面试题库

面试题:微服务架构里Sentinel的热点参数限流

在复杂的微服务业务场景中,如何利用Sentinel的热点参数限流功能来保护服务?请举例说明热点参数限流规则的具体配置步骤和可能遇到的问题及解决方案。
23.8万 热度难度
后端开发微服务架构

知识考点

AI 面试

面试题答案

一键面试

利用 Sentinel 热点参数限流功能保护服务的方法

  1. 原理:热点参数限流是对特定参数值的请求进行限流,可针对参数值设置不同的限流阈值。在微服务业务场景中,某些参数值可能会频繁被访问导致流量集中,通过热点参数限流可避免这些参数值的请求量过大而压垮服务。
  2. 应用场景:例如电商系统中,商品详情页展示接口,对于热门商品 ID 的请求可能远多于其他商品 ID,可对商品 ID 这个参数进行热点参数限流。

热点参数限流规则具体配置步骤

  1. 引入依赖:在项目的 pom.xml 文件中引入 Sentinel 相关依赖。
<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-core</artifactId>
    <version>x.x.x</version>
</dependency>
<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-annotation-aspectj</artifactId>
    <version>x.x.x</version>
</dependency>
  1. 配置 Sentinel 控制台:启动 Sentinel 控制台,并将微服务注册到控制台。
  2. 定义热点参数限流规则
    • 方式一:通过注解方式
      • 在需要限流的方法上添加 @SentinelResource 注解,例如:
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import org.springframework.stereotype.Service;

@Service
public class ProductService {
    @SentinelResource(value = "productDetail", blockHandler = "handleProductDetailBlock")
    public String getProductDetail(long productId) {
        // 业务逻辑
        return "Product detail for productId: " + productId;
    }

    public String handleProductDetailBlock(long productId, BlockException ex) {
        return "限流了,当前商品访问量过大";
    }
}
 - 在配置文件(如 `application.yml`)中配置热点参数限流规则:
spring:
  cloud:
    sentinel:
      transport:
        dashboard: localhost:8080
      datasource:
        ds1:
          nacos:
            server-addr: localhost:8848
            dataId: ${spring.application.name}-sentinel
            groupId: DEFAULT_GROUP
            rule-type: flow
 - 在 Nacos 配置中心创建 `${spring.application.name}-sentinel` 文件,添加热点参数限流规则:
[
    {
        "resource": "productDetail",
        "limitApp": "default",
        "grade": 1,
        "count": 10,
        "strategy": 0,
        "controlBehavior": 0,
        "clusterMode": false,
        "paramFlowItemList": [
            {
                "classType": "java.lang.Long",
                "fieldName": "productId",
                "count": 5,
                "grade": 1,
                "paramIdx": 0
            }
        ]
    }
]
  • 方式二:通过代码方式
import com.alibaba.csp.sentinel.Entry;
import com.alibaba.csp.sentinel.SphU;
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 com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowItem;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRuleManager;

import java.util.ArrayList;
import java.util.List;

public class HotParamLimitExample {
    public static void main(String[] args) {
        initFlowRules();

        while (true) {
            try (Entry entry = SphU.entry("productDetail",
                    RuleConstant.RES_TYPE_DEFAULT,
                    1,
                    1L)) {
                // 业务逻辑
                System.out.println("正常访问");
            } catch (Exception e) {
                System.out.println("限流了");
            }
        }
    }

    private static void initFlowRules() {
        List<FlowRule> flowRules = new ArrayList<>();
        FlowRule rule = new FlowRule();
        rule.setResource("productDetail");
        rule.setCount(10);
        rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
        rule.setLimitApp("default");
        flowRules.add(rule);
        FlowRuleManager.loadRules(flowRules);

        List<ParamFlowRule> paramFlowRules = new ArrayList<>();
        ParamFlowRule paramRule = new ParamFlowRule();
        paramRule.setResource("productDetail");
        paramRule.setCount(5);
        paramRule.setGrade(RuleConstant.FLOW_GRADE_QPS);
        ParamFlowItem item = new ParamFlowItem();
        item.setClassType("java.lang.Long");
        item.setParamIdx(0);
        paramRule.setParamFlowItemList(List.of(item));
        paramFlowRules.add(paramRule);
        ParamFlowRuleManager.loadRules(paramFlowRules);
    }
}

可能遇到的问题及解决方案

  1. 规则不生效
    • 原因:可能是依赖版本不兼容,配置文件加载错误,或者 Sentinel 控制台与微服务连接问题。
    • 解决方案:检查依赖版本是否匹配 Sentinel 控制台版本;确认配置文件路径和格式正确;检查 Sentinel 控制台与微服务的网络连接及注册配置。
  2. 限流误判
    • 原因:参数类型判断错误,或者参数位置索引错误。
    • 解决方案:仔细确认热点参数的类型和在方法参数列表中的位置索引,确保配置正确。
  3. 性能问题
    • 原因:过多的热点参数限流规则可能会增加系统的计算开销。
    • 解决方案:合理设置限流规则,避免设置过多不必要的规则;可以考虑在业务层对参数进行预处理,减少进入限流判断的请求量。