sentinel基础概念及使用

点赞再看,养成习惯,微信搜索「小大白日志」关注这个搬砖人。

文章不定期同步公众号,还有各种一线大厂面试原题、我的学习系列笔记。

什么是sentinel
  • sentinel是Spring Cloud Alibaba的一个重要组件,类似于spring clound的hystrix,与hystrix-dashboard控制台一样,sentinel-dashboard控制台可以提供对流量的实时监控、在线维护流量规则、熔断规则,前提是微服务整合了sentinel
  • 对比hystrix
SentinelHystrix
隔离策略信号量隔离线程池隔离/信号量隔离
熔断降级策略基于响应时间或失败比率线程池隔离/ 基于响应时间或失败比率
实时指标实现滑动窗口滑动窗口(基于 RxJava)
规则配置支持多种数据源支持多种数据源
扩展性多个扩展点插件的形式
基于注解的支持支持支持
限流基于 QPS,支持基于调用关系的限流有限的支持
流量整形支持慢启动、匀速器模式不支持
系统负载保护支持不支持
控制台开箱即用,可配置规则、查看秒级监控、机器发现等不完善
常见框架的适配Servlet、Spring Cloud、Dubbo、gRPC 等Servlet、Spring Cloud Netflix

hystrix官方已停止更新,而sentinel则保持着开源

基础概念
  • Resource:资源resource可以是代码块、方法(普通方法、接口)等,把它们定义为资源后,再定义限流规则,就可以结合sentinel使用了
  • Slot插槽:sentinel中定义了7种slot插槽,sentinel正是通过各个插槽间的固定调用顺序来实现限流的,因为后面的插槽可能依赖于前面插槽的计算结果
  • Entry:是否通过限流的凭证,sentinel有三种形式来定义资源
    • 调用SphU.entry(“资源”)来定义资源:定义成功则返回一个Entry对象,否则抛出异常以拒绝往下执行限流代码,代表此资源已被定义,需要执行其他处理代码,不管是否成功定义资源最后都要执行entry.exit()退出资源
    • 调用SphO.entry(“资源”)来定义资源:返回true表示定义成功,若定义资源失败则返回false以拒绝往下执行限流代码,需要执行其他处理代码,不管是否成功定义资源最后都要执行SphO.exit()退出资源调用
    • 注解的方式定义资源:上面两种方式对代码侵入性很高,可用@SentinelResource注解的方式作用于方法上,并配置blockHandler指定限流处理方式
  • Node节点:DefaultNode=链路节点,可统计调用链路上某个资源的数据;ClusterNode=簇节点,可统计某个资源的全局数据;StatisticNode=基础节点,其数据结构有秒级/分钟级别的滑动窗口结构;EntranceNode=入口节点,包含一些入口数据
  • Context:上下文,ThreadLocal传递,包含一次链路调用的所有信息,如链路节点DefaultNode,入口节点EntranceNode
使用sentinel:定义限流规则及定义资源
  • 引入依赖
<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-core</artifactId>
    <version>1.7.1</version>
</dependency>
  • 定义规则及定义资源

规则是要作用于资源上的,下面先定义规则,再用【SphU.entry()】或【SphO.entry()】或注解的形式定义资源:

public class demo {
    public static void main(String[] args) {
        // 定义规则
        initFlowRules();
        //用SphU.entry()的形式定义资源
        while (true) {
            try (Entry entry = SphU.entry("myResource")) {//与规则定义中的rule.setResource("myResource")一致
                // 被保护的业务逻辑...
                System.out.println("业务资源访问成功!");
            } catch (BlockException ex) {
                // 处理被流控的逻辑:限流或降级...
                System.out.println("资源访问失败!!!");
            } finally {
            	if (entry != null) {
            		entry.exit();//必须退出资源调用
                }
            }
        }
        
        
        //用SphO.entry()的形式定义资源
        while (true) {
            if(SphO.entry("myResource")){//与规则定义中的rule.setResource("myResource")一致
                try{
                    // 被保护的业务逻辑...
                    System.out.println("业务资源访问成功!");
                } catch (BlockException ex) {
                    // 处理被流控的逻辑:限流或降级...
                    System.out.println("资源访问失败!!!");
                }finally{
                    SphO.exit();//必须退出资源调用
                }
            }
        }
        
        //上面两种方式对代码侵入性很高,可用注解的方式定义资源
        while(true){
            getUserById("111");
        }
    }

    //定义规则
    private static void initFlowRules(){
        List<FlowRule> rules = new ArrayList<>();// 存储规则 FlowRule
        FlowRule rule = new FlowRule();
        rule.setResource("myResource");	// 指定限流规则作用于哪个资源上,资源名为字符串,可为任意有标识意义的方法名/接口名/其他字符串,此处资源名为"myResource"
        rule.setGrade(RuleConstant.FLOW_GRADE_QPS);	// 限流类型为QPS模式:限制QPS
        rule.setCount(10);	   // QPS不得超出10
        rule.setLimitApp("default");	// 针对的调用来源,default代表不区分来源
        rules.add(rule);
        FlowRuleManager.loadRules(rules);// 加载规则
	}
	
	
	//定义"myResource"资源,并设置违背sentinel流控规则时的处理方法handlerException()
	@SentinelResource(value="myResource",blockHandler="handlerException")
	public User getUserById(String id){
	    return new User("数据库用户");
	}
	//注意:此处理方法的参数必须和定义资源的方法getUserById参数一致()同时加上【BlockException exception】参数
	public User handlerException(String id,BlockException exception){
	    return new User("流控用户");
	}
}

Entry entry = null;
try {
	entry = SphU.entry("myResource"); //此处说明资源
	// 被保护的业务逻辑
	...
} catch (BlockException e1) {
	// 资源访问阻止,被限流或被降级,进行相应的处理操作
	...
} finally {
	if (entry != null) {
		entry.exit();
    }
}
单独启动sentinel
  • 下载sentinel-dashboard-1.6.0.jar包(++链接++),启动:java -jar
    -Dserver.port=8888 sentinel-dashboard-1.6.0.jar
    image

  • 访问localhost:8888登录sentinel-dashboard控制台,默认用户名/密码是sentinel/sentinel
    image
    可以看到控制台没有对任何的微服务进行流量监控

  • 项目整合sentinel

    • pom.xml引入依赖
      <dependency>
          <groupId>org.springframework.cloud</groupId>
          <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
      </dependency>
    
    • 在项目的properties文件中加入:
    spring.clound.sentinel.transport.dashboard=localhost:8888 #设置sentinel控制台的地址
    spring.application.name=myapp  #项目名
    
    • 浏览器访问该项目后,再次回到sentinel控制台,可以看到myapp项目中所有对controller接口的监控,可以在左侧“簇点链路”新增流控规则,设置每个接口的QPS(每秒允许访问多少次)
      image
      image

OK,如果文章哪里有错误或不足,欢迎各位留言。

创作不易,各位的「三连」是二少创作的最大动力!我们下期见!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值