Spring Cloud(四)Sentiel服务熔断器组件

一、引言

  小伙伴们应该都有过双11,双12等电商节的抢购经历吧?那么电商节当天的瞬时并发请求是非常非常巨量了,尽管做了很多性能优化及高可用等优化手段,仍然还是无法保证能马上处理所有的请求的,那么如何在高并发场景提供一项功能来对服务进行限流熔断降级呢?像是老牌的Hystrix,以及阿里开源的Sentinel都可以帮我们实现这一功能,这篇文章主要学习Sentinel如何使用以及和我们的工程进行整合。

  PS:熔断、限流、降级其实体现在我们的工程流程中,就是当大量的请求到达服务端时,为了避免直接打崩我们的服务器,所采取的一种保护措施。我们通过熔断器组件直接返回一些信息,而不去真实的调用服务

  PS:说实话学这个的时候找了很多网上的教程搭建都不是很顺利,后来终于摸索出来了,如果小伙伴想跟着我的文章进行搭建的话,请一定不要漏一些步骤,遇到bug找资料都得找挺久还不一定有有效的解决方案,小伙伴们共勉~

二、下载Sentinel控制台

  这里我就以windows的安装为例了,linux版本的安装大同小异,小伙伴们可以自己尝试动手玩一下。

  下载地址:https://github.com/alibaba/Sentinel/releases

三、在工程中整合Sentinel

  根据前面的文章,我们知道请求入口是OREDER-SERVER,所以这里我们的熔断器主要加在OREDER-SERVER工程中:

pom.xml

  在pom.xml文件中增加以下依赖

        <!--alibaba-sentinel熔断器核心依赖-->
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-core</artifactId>
            <version>1.8.2</version>
        </dependency>
        <!--alibaba-sentinel熔断器接入控制台的依赖-->
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-transport-simple-http</artifactId>
            <version>1.8.2</version>
        </dependency>
        <!--alibaba-sentinel熔断器注解方式实现的依赖-->
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-annotation-aspectj</artifactId>
            <version>1.8.2</version>
        </dependency>

配置熔断规则

方式一、手写熔断规则

/**
 * sentinel熔断示例【手写方式实现】
 *
 * @author 有梦想的肥宅
 * @date 2021/9/6
 */
@RestController
public class OrderSentinelHandWriteController {

    @Autowired
    private OutGdsApi outGdsApi;

    @RequestMapping("/orderSentinelHandWrite")
    public String showOrderInfo() {

        //1、根据资源orderSentinelHandWrite的熔断规则,判断时候可以执行try{}内部的业务代码
        try (Entry entry = SphU.entry("orderSentinelHandWrite")) {
            
            return business();//执行业务逻辑

        } catch (Exception e) {
            //2、当服务熔断时会抛出异常,进入此代码块,可以编写熔断后的逻辑
            e.printStackTrace();
            return "系统繁忙,请稍后重试!【Sentinel已经拦截请求~】【手写规则】";
        }
    }


    /**
     * 定义熔断规则
     *
     * @PostConstruct 此注解的含义是:本类构造方法执行结束后执行
     */
    @PostConstruct
    public void init() {
        //1.创建存放限流规则的集合
        List<FlowRule> rules = new ArrayList<>();
        //2.创建限流规则
        FlowRule rule = new FlowRule();
        //定义资源,表示Sentinel会对哪个资源生效
        rule.setResource("orderSentinelHandWrite");
        //定义限流的类型(此处使用QPS作为限流类型)
        rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
        //定义QPS每秒通过的请求数
        rule.setCount(2);
        //3.将限流规则存放到集合中
        rules.add(rule);
        //4.加载限流规则
        FlowRuleManager.loadRules(rules);
    }

    //业务代码
    private String business() {
        Map orderInfo = new HashMap();
        orderInfo.put("orderId", 1);
        orderInfo.put("gdsInfo", outGdsApi.getGdsInfo("1"));
        return JSON.toJSONString(orderInfo);
    }

}

方式二、注解方式设置资源,并在Sentinel控制台配置熔断规则

SentinelAspectConfiguration配置类
/**
 * Sentinel注解方式的配置
 *
 * @author 有梦想的肥宅
 * @date 2021/9/8
 */
@Configuration
public class SentinelAspectConfiguration {

    //定义一个SentinelResourceAspect类型的Bean交由Spring容器管理
    @Bean
    public SentinelResourceAspect sentinelResourceAspect() {
        return new SentinelResourceAspect();
    }
}
OrderSentinelAspectjController
/**
 * sentinel熔断示例【注解方式实现】
 *
 * @author 有梦想的肥宅
 * @date 2021/9/6
 */
@RestController
public class OrderSentinelAspectjController {


    @Autowired
    private OutGdsApi outGdsApi;

    //value:代表资源名称【在sentinel控制台设置】  blockHandler:设置熔断时的处理方法
    @SentinelResource(value = "orderSentinelAspectj", blockHandler = "exceptionHandler")
    @RequestMapping("/orderSentinelAspectj")
    public String showOrderInfo() {
        Map orderInfo = new HashMap();
        orderInfo.put("orderId", 1);
        orderInfo.put("gdsInfo", outGdsApi.getGdsInfo("1"));
        return JSON.toJSONString(orderInfo);
    }

    //限流降级的处理方法
    private String exceptionHandler(BlockException e) {
        e.printStackTrace();
        return "系统繁忙,请稍后重试!【Sentinel已经拦截请求~】【注解实现】";
    }
}
配置流控规则

启动项目进行测试

 

 

原文地址:https://www.cnblogs.com/riches/p/15248278.html