zoukankan      html  css  js  c++  java
  • Sentinel: 分布式系统的流量防卫兵

    前言

    在 Spring Cloud 体系中,熔断降级我们会使用 Hystrix 框架,限流通常会在 Zuul 中进行处理,Zuul 中没有自带限流的功能,我们可以自己做限流或者集成第三方开源的限流框架。最新一代的网关 Spring Cloud Gateway 则自带了限流的功能。

    有没有那么一个框架能够把熔断跟限流都给做了,以前没有,但是现在有了,我这属于自问自答哈!这个框架就是阿里最新开源的 Sentinel。

    第一眼见到 Sentinel 有一种很熟悉的感觉,似曾相识啊!Redis 里面集群的那个哨兵模式不就是 Sentinel 嘛。后来我才发现我错了,大错特错,这是一个新的框架,潜力 + 实力 = 阿里开源。

    Sentinel 是什么?

    本段介绍来源于Sentinel Github主页介绍

    随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。

    Sentinel 具有以下特征:

    • 丰富的应用场景:Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。
    • 完备的实时监控:Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。
    • 广泛的开源生态:Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。
    • 完善的 SPI 扩展点:Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。

    Sentinel 的主要特性:

    本图来源于Sentinel Github主页介绍

    Sentinel 的开源生态:

    本图来源于Sentinel Github主页介绍

    初次见面的我们

    先来简单的体验下 Sentinel 吧,在你的Maven项目中增加 Sentinel 的依赖:

    <dependency>
    	<groupId>com.alibaba.csp</groupId>
    	<artifactId>sentinel-core</artifactId>
    	<version>1.4.1</version>
    </dependency>
    

    Sentinel中需要限流的称之为资源,对资源进行处理,下面来看最简单的一段代码:

    public static void main(String[] args) {
        initFlowRules();
        while (true) {
            Entry entry = null;
            try {
    	        entry = SphU.entry("HelloWorld");
                /*您的业务逻辑 - 开始*/
                System.out.println("hello world");
                /*您的业务逻辑 - 结束*/
    	    } catch (BlockException e1) {
                /*流控逻辑处理 - 开始*/
    	        System.out.println("block!");
                /*流控逻辑处理 - 结束*/
    	    } finally {
    	       if (entry != null) {
    	           entry.exit();
    	       }
    	   }
        }
    }
    
    private static void initFlowRules(){
        List<FlowRule> rules = new ArrayList<>();
        FlowRule rule = new FlowRule();
        rule.setResource("HelloWorld");
        rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
        // Set limit QPS to 20.
        rule.setCount(20);
        rules.add(rule);
        FlowRuleManager.loadRules(rules);
    }
    

    第一行中初始化限流的规则,创建了一个资源叫 HelloWorld,设置了这个资源的QPS 为 20。

    在业务开始前使用SphU.entry();方法标识开始,结束使用entry.exit();,如果触发了流控逻辑就会抛出BlockException异常让用户自行处理。

    代码运行之后,我们可以在日志 ~/logs/csp/${appName}-metrics.log.xxx 里看到下面的输出:

    |--timestamp-|------date time----|-resource-|p |block|s |e|rt
    1529998904000|2018-06-26 15:41:44|HelloWorld|20|0    |20|0|0
    1529998905000|2018-06-26 15:41:45|HelloWorld|20|5579 |20|0|728
    1529998906000|2018-06-26 15:41:46|HelloWorld|20|15698|20|0|0
    1529998907000|2018-06-26 15:41:47|HelloWorld|20|19262|20|0|0
    1529998908000|2018-06-26 15:41:48|HelloWorld|20|19502|20|0|0
    1529998909000|2018-06-26 15:41:49|HelloWorld|20|18386|20|0|0
    
    • p:通过的请求,
    • block:被阻止的请求
    • s:成功执行完成的请求个数
    • e:用户自定义的异常
    • rt:平均响应时长。

    我是Mac系统,日志是在这个目录下,Windows我没试过,应该也在用户的主目录下

    上面这个列子是官方的示列,如果你觉得没有看到你想要的效果,因为一直在循环,也不知道有没有限流成功,我们可以稍微改动一下进行测试就知道了。

    将while循环改成for循环, 次数为10000次,只输出一句话,不做任何限制,执行完成的时间大概在40毫秒左右。

    long startTime = System.currentTimeMillis();
    for (int i = 0; i < 10000; i++) {
    	System.out.println("hello world");
    }
    long endTime = System.currentTimeMillis();
    System.out.println(endTime - startTime);
    

    下面加上限流的逻辑,执行完成的时间基本上就超过100毫秒了,可见限流起了作用。

    for (int i = 0; i < 10000; i++) {
    	Entry entry = null;
    	try {
    		entry = SphU.entry("HelloWorld");
    		// 资源中的逻辑.
    		System.out.println("hello world");
    	} catch (BlockException e1) {
    		System.out.println("blocked!");
    	} finally {
    		if (entry != null) {
    			entry.exit();
    		}
    	}
    }
    long endTime = System.currentTimeMillis();
    System.out.println(endTime - startTime);
    

    欢迎加入我的知识星球,一起交流技术,免费学习猿天地的课程(http://cxytiandi.com/course)

    PS:目前星球中正在星主的带领下组队学习Sentinel,等你哦!

    微信扫码加入猿天地知识星球

    猿天地

  • 相关阅读:
    N4-某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。
    N3-按链表值从尾到头的顺序返回一个ArrayList。
    N2-替换字符串空格
    innodb死锁1213
    innodb是行锁还是表锁
    docker是什么,docker干什么用
    innodb通过frm ibd还原数据,线上项目验证过
    机器性能预警系统(cpu,process,内存,硬盘监控)并钉钉机器人报警
    mysql++ query.more_results()为true时,query.store_next()就崩掉了
    yum install nload失败,提示No package nload available.Error: Nothing to do
  • 原文地址:https://www.cnblogs.com/yinjihuan/p/10468950.html
Copyright © 2011-2022 走看看