八、服务容错Sentinel

一、雪崩效应

在这里插入图片描述

二、常见容错方案

1、超时:设置调用服务的时间

2、限流:在一个高并发系统中,为微服务设置一个限流的值

3、仓壁模式
在这里插入图片描述
4、断路器模式:监控+开关

断路器模式原文

断路器三态转换
在这里插入图片描述

三、使用Sentinel实现容错

1、什么是Sentinel?

github

2、整合Sentinel

添加依赖

	   <!--sentinel依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>
        <!--/actuator/sentinel-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

application.yml

management:
  endpoints:
    web:
      exposure:
        include: '*'

测试结果
在这里插入图片描述

四、sentinel控制台

1、搭建sentinel控制台

下载地址
启动sentinel-dashboard
在这里插入图片描述
访问地址
在这里插入图片描述
在这里插入图片描述

2、整合应用和控制台

application.yml

spring:
	cloud:
		sentinel:
      		transport:
       			 # 指定sentinel控制台的地址
        		 dashboard: localhost:8080

浏览器访问地址
在这里插入图片描述

五、流控规则

1、直接流控模式
在这里插入图片描述
在这里插入图片描述
2、关联流控模式
在这里插入图片描述
测试类进行测试
在这里插入图片描述
此时http://localhost:8010/shares/1一直处于限流状态
在这里插入图片描述
3、链路流控模式
在这里插入图片描述
在这里插入图片描述
分别访问http://localhost:8010/test-a和http://localhost:8010/test-b
在这里插入图片描述
再次访问http://localhost:8010/test-a会发生限流,而访问http://localhost:8010/test-b没有

排队等待流控效果
在这里插入图片描述
测试代码
在这里插入图片描述

六、降级规则

1、降级策略-RT

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
注意:RT默认最大值为4900ms,可以通过
-Dcsp.sentinel.statistic.max.rt=xxx修改

2、降级策略-异常比例

在这里插入图片描述

3、降级策略-异常数

在这里插入图片描述
注意点:
时间窗口 < 60秒可能会出问题

七、热点规则

在这里插入图片描述
在这里插入图片描述
对http://localhost:8010/test-hot?a=5&b=2不限流

八、系统规则

◆当系统load1(1分钟的load)超过阈值,且并发线程数超过系统容量时触发,建议设置为CPU核心数*2.5。(仅对Linux/Unix- like 机器生效)
◆系统容量=maxQps*minRt
◆maxQps:秒级统计出来的最大QPS
◆minRt:秒级统计出来的最小响应时间


系统-RT、线程数、入口QPS
◆RT:所有入口流量的平均RT 达到阈值触发
◆线程数:所有入口流量的并发线程数达到阈值触发
◆入口QPS:所有入口流量的QPS达到阈值触发

九、代码配置规则

Alibaba Sentinel 规则参数总结

测试代码TestController.java

	@GetMapping("/test-add-flow-rule")
    @SentinelResource("hot")
    public String testHot(){
        this.initFlowQpsRule();
        return "success";
    }

    private void initFlowQpsRule() {
        List<FlowRule> rules = new ArrayList<>();
        FlowRule rule = new FlowRule("/shares/1");
        // set limit qps to 20
        rule.setCount(20);
        rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
        rule.setLimitApp("default");
        rules.add(rule);
        FlowRuleManager.loadRules(rules);
    }

测试结果
在这里插入图片描述

十、Sentinel与控制台通信原理分析

在这里插入图片描述

十一、控制台相关配置项

1、应用端连接控制台配置项
在这里插入图片描述
2、控制台配置项
在这里插入图片描述
配置Dashboard登录的账号和密码

java -jar -Dsentinel.dashboard.auth.username=czy -Dsentinel.dashboard.auth.password=123456 sentinel-dashboard-1.6.3.jar

十二、Sentinel API

TestController.java

	@GetMapping("/test-sentinel-api")
    public String testSentinelApi(@RequestParam(required = false) String a) {
        Entry entry = null;
        String resourceName = "test-sentinel-api";
        // 针对来源
        ContextUtil.enter(resourceName,"test-wfw");
        try {
            // 定义需要保护资源的名称
            entry = SphU.entry(resourceName);
            // 被保护的业务逻辑
            if (StringUtils.isBlank(a)) {
                throw new IllegalArgumentException("a不能为空");
            }
            return a;
        }
        // 如果被保护的资源被限流或降级,就会抛出BlockException异常
        catch (BlockException e) {
            log.warn("限流,或降级了",e);
            return "限流,或降级了";
        }
        catch (IllegalArgumentException e2) {
            // 统计IllegalArgumentException发生的次数等
            Tracer.trace(e2);
            return "参数非法";
        }
        finally {
            if (entry != null) {
                // 退出entry
                entry.exit();
            }
            ContextUtil.exit();
        }
    }

三个核心API

  • SphU:定义、监控、保护资源
  • Tracer:对异常进行统计
  • ContextUtil:实现调用来源,标记调用

十三、@SentinelResource注解

在这里插入图片描述
TestController.java

@GetMapping("/test-sentinel-resource")
    @SentinelResource(value = "test-sentinel-api",blockHandlerClass = TestControllerBlockHandlerClass.class,fallback = "fallback")
    public String testSentinelResource(@RequestParam(required = false) String a) {
        if (StringUtils.isBlank(a)) {
            throw new IllegalArgumentException("a can not be blank");
        }
        return a;
    }
    /**
     *  Sentinel 1.5 处理降级
     *  Sentinel 1.6开始,也可在方法最后加 Throwable 类型的参数。
     * @param a
     * @return
     */
    public String fallback(String a) {
        return "限流,或降级了 fallback";
    }

十四、RestTemplate整合Sentinel

在这里插入图片描述
application,yml

resttemplate:
  sentinel:
    # false 关闭@SentinelRestTemplate注解
    enabled: true

TestController.java

@Autowired
    private RestTemplate restTemplate;
    @GetMapping("/test-rest-template-sentinel/{userId}")
    public UserDTO test(@PathVariable Integer userId){
        return this.restTemplate.getForObject("http://user-center/users/{userId}",UserDTO.class,userId);
    }

十五、Feign整合Sentinel

application.yml

feign:
  sentinel:
    # 为feign整合sentinel
    enabled: true

在这里插入图片描述
UserCenterFeignClientFallbackFactory .java

package com.uos.contentcenter.feignclient.fallbackfactory;

import com.uos.contentcenter.domain.dto.user.UserDTO;
import com.uos.contentcenter.feignclient.UserCenterFeignClient;
import feign.hystrix.FallbackFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;


@Slf4j
@Component
public class UserCenterFeignClientFallbackFactory implements FallbackFactory<UserCenterFeignClient> {
    @Override
    public UserCenterFeignClient create(Throwable cause) {
        return new UserCenterFeignClient() {
            @Override
            public UserDTO findById(Integer id) {
                log.warn("远程调用被限流/降级了",cause);
                UserDTO userDTO = new UserDTO();
                userDTO.setWxNickname("一个默认用户");
                return userDTO;
            }
        };
    }
}

十六、Sentinel总结

在这里插入图片描述

十七、规则持久化-拉模式

拉模式详解

十八、规则持久化-推模式

推模式详解

十九、在生产环境中使用sentinel

参考我的另一篇博客在生产环境中使用sentinel

二十、集群流控

集群流控

发布了135 篇原创文章 · 获赞 41 · 访问量 4249

猜你喜欢

转载自blog.csdn.net/weixin_41842236/article/details/104662251