Sentinel——流控规则

发布时间 2023-12-04 14:25:55作者: 谁风霜依旧

流控规则

流控规则是用于完成服务流控的。服务流控即对访问流量的控制,也称为服务限流。Sentine实现流控的原理是监控应用流量的 QPS 或并发线程数等指标,当达到指定的值时对再到来的请求进行进行控制,以避免被瞬时的流量高峰冲垮,从而保障应用的高可用性。

设置流控规则

代码设置流控调用的方法,@SentinelResource(value = "get", fallback = "getFallBack", blockHandler = "getFlowFallBack")

package com.zjw.controller;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.zjw.domain.Depart;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.List;

/**
 * <p>
 * 部门表 前端控制器
 * </p>
 *
 * @author zjw
 * @since 2023-11-20
 */
@RestController
@RequestMapping("/depart")
@Slf4j
public class DepartController {

    @Resource
    private RestTemplate restTemplate;

    private static final String PROVIDER_URL = "http://depart-provider/depart";

    /**
     * 根据id查询部门
     */
    // 发生异常,跳到500空白页
//    @SentinelResource(value = "get")
    // 发生异常会降级,调用getFallBack方法
//    @SentinelResource(value = "get", fallback = "getFallBack")
    //发生异常会降级,调用getFallBack方法, 触发流控,会调用流控的getFlowFallBack方法
    @SentinelResource(value = "get", fallback = "getFallBack", blockHandler = "getFlowFallBack")
    // 发生异常会降级,调用getFallBack方法,
    @GetMapping("/get/{id}")
    public Depart get(@PathVariable Long id) {
        return restTemplate.getForObject(PROVIDER_URL + "/get/" + id, Depart.class);
    }

    /**
     * 服务流控使用的方法.
     * 需要指定BlockException参数,否则调用降级方法
     */
    public Depart getFlowFallBack(Long id, BlockException e) {
        log.info("id = " + id);
        log.info("exception = " + e.getMessage());
        Depart depart = new Depart();
        depart.setId(id);
        depart.setName("flow fall back");
        return  depart;
    }

    /**
     * 服务降级使用的方法
     */
    public Depart getFallBack(Long id, Throwable t) {
        log.info("id = " + id);
        log.info("throwable = " + t.getMessage());
        Depart depart = new Depart();
        depart.setId(id);
        depart.setName("no this depart");
        return  depart;
    }

控制台设置流控的规则:

如果调用的服务停止了,会触发降级,调用getFallBack方法。

当请求QPS超过3时会触发流控规则,调用getFlowFallBack方法。

api设置流控规则

通过控制台设置的流控规则会在服务重启后失效,可以通过sentinel的api在代码中指定规则

package com.zjw;

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.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

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

@SpringBootApplication
public class ConsumerFlowRule8080Application {

    public static void main(String[] args) {
        SpringApplication.run(ConsumerFlowRule8080Application.class, args);
        //初始化流控规则
        initFlowRule();
    }

    private static void initFlowRule() {
        FlowRuleManager.loadRules(configFlowRule());
    }

    private static List<FlowRule> configFlowRule() {
        List<FlowRule> flowRuleList = new ArrayList<>();
        FlowRule rule = new FlowRule();
        // 资源名
        rule.setResource("get");
        // 针对来源
        rule.setLimitApp("default");
        // 阈值类型 (并发线程数 0: thread count, 1: QPS).
        // RuleConstant.FLOW_GRADE_THREAD 0
        // RuleConstant.FLOW_GRADE_QPS 1
        rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
        // 单机阈值
        rule.setCount(3);
        flowRuleList.add(rule);
        return flowRuleList;
    }
}