限流熔断

简介: 为什么要有熔断限流:为了防止服务雪崩。那么什么是服务雪崩?

限流熔断分享

为什么要有熔断限流:为了防止服务雪崩。那么什么是服务雪崩?

下面分别讲几个概念:

快速失败:在java中集合中 多个线程操作非安全集合 会发生快速失败。类比到我们在开发web应用时候,对于非法参数我们也会进行提前结束(抛出异常或者直接return),避免占用之后的资源,进行无效计算。

缓存雪崩:数据库往往是web 应用的瓶颈,为了避免频繁读取数据库引入本地缓存或者分布式缓存将数据库数据保存在内存中,对于不存在缓存中数据或者未过期数据,才去数据库读取,减少对数据库的访问。缓存往往会设置一定有效时间。如果在某段时间,缓存集体失效。大量数据访问涌入数据库,称为缓存雪崩。

分布式服务:早期使用水平拓展,对于部分服务器可能并没有充分利用资源,如io密集型和cpu密集型。为此引入分布式服务,特定服务使用适合服务器,结果使用rpc或者http进行网络传输。

服务雪崩:多个服务之间相互调用链路,一条核心链路往往可能调用十个服务。我们知道随着并发数增加,系统响应时间在某个时间段会急剧增加。

系统吞吐量评估方法

如果在链路中,某个服务发生这种情况,rt(响应时间)急剧上升,上游服务不断请求,造成恶性循环,上游等待结果线程数越多,使得更上游服务阻塞最终整条链路无法使用,称为服务雪崩。

解决思路:

借鉴 快速失败思想。发生rt超时情况,进行快速失败,返回错误结果。——熔断

借鉴 缓存雪崩是想。避免大量数据访问到该应用,控制数量在合理范围。——限流

单机限流和分布式限流:

单机限流是指限定当前进程里面的某个代码片段的 QPS 或者 并发线程数 或者 整个机器负载指数,一旦超出规则配置的数值就会抛出异常或者返回 false。

分布式则需要另启一个集中的发票服务器,这个服务器针对每个指定的资源每秒只会生成一定量的票数,在执行临界区的代码之前先去集中的发票服务领票,如果领成功了就可以执行,否则就会抛出限流异常或者返回false。

限流算法:

业界主流的限流算法,一般有以下几种。

1.令牌桶限流

令牌桶是一个存放固定容量令牌的桶,按照固定速率往桶里添加令牌,填满了就丢弃令牌,请求是否被处理要看桶中令牌是否足够,当令牌数减为零时则拒绝新的请求。令牌桶允许一定程度突发流量,只要有令牌就可以处理,支持一次拿多个令牌。令牌桶中装的是令牌。

2.漏桶限流

漏桶一个固定容量的漏桶,按照固定常量速率流出请求,流入请求速率任意,当流入的请求数累积到漏桶容量时,则新流入的请求被拒绝。漏桶可以看做是一个具有固定容量、固定流出速率的队列,漏桶限制的是请求的流出速率。漏桶中装的是请求。

3.计数器限流

有时我们还会使用计数器来进行限流,主要用来限制一定时间内的总并发数,比如数据库连接池、线程池、秒杀的并发数;计数器限流只要一定时间内的总请求数超过设定的阀值则进行限流,是一种简单粗暴的总数量限流,而不是平均速率限流。

4.固定窗口算法(滑动窗口算法)

在实现它的时候,首先要启动一个定时器定期重置计数,比如你需要限制每秒钟访问次数,而限流的逻辑就非常简单了,只需要比较计数值是否大于阈值就可以了。缺点是在两个时间间隔中间会同时涌入流量,造成窗口失败。

主流工业方案

对于单机限流 采用Guava 的RateLimiter,用的是令牌桶的算法,主要是因为它支持突发流量,并且是比较成熟的现成框架。原因是:接口级的限流,更重要的还是要保证速率均衡,还要允许一定的突发流量

对于分布式限流采用目前有hytrix 和Sentinel 。

Hystrix限流功能

  1. Hystrix使用命令模式HystrixCommand(Command)包装依赖调用逻辑,每个命令在单独线程中/信号授权下执行。
  2. 基于超时时间降级执行fallback。
  3. 为每个依赖提供一个小的线程池(或信号),如果线程池已满调用将被立即拒绝,默认不采用排队.加速失败判定时间。
  4. 依赖调用结果分:成功,失败(抛出异常),超时,线程拒绝,短路。 请求失败(异常,拒绝,超时,短路)时执行fallback(降级)逻辑。
  5. 熔断器:提供基于失败比例的熔断(50%),停止当前依赖一段时间(10秒)。
  6. 提供近实时依赖的统计和监控

接口使用

详细接口使用:http://blog.51cto.com/developerycj/1950881

使用命令模式封装依赖逻辑
public class HelloWorldCommand extends HystrixCommand<String> { 
    private final String name; 
    public HelloWorldCommand(String name) { 
        //最少配置:指定命令组名(CommandGroup) 
        super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup")); 
        this.name = name; 
    } 
    @Override 
    protected String run() { 
        // 依赖逻辑封装在run()方法中 
        return "Hello " + name +" thread:" + Thread.currentThread().getName(); 
    } 
    //调用实例 
    public static void main(String[] args) throws Exception{ 
        //每个Command对象只能调用一次,不可以重复调用, 
        //重复调用对应异常信息:This instance can only be executed once. Please instantiate a new instance. 
        HelloWorldCommand helloWorldCommand = new HelloWorldCommand("Synchronous-hystrix"); 
        //使用execute()同步调用代码,效果等同于:helloWorldCommand.queue().get();  
        String result = helloWorldCommand.execute(); 
        System.out.println("result=" + result); 
    
        helloWorldCommand = new HelloWorldCommand("Asynchronous-hystrix"); 
        //异步调用,可自由控制获取结果时机, 
        Future<String> future = helloWorldCommand.queue(); 
        //get操作不能超过command定义的超时时间,默认:1秒 
        result = future.get(100, TimeUnit.MILLISECONDS); 
        System.out.println("result=" + result); 
        System.out.println("mainThread=" + Thread.currentThread().getName()); 
    } 
        
} 

sential支持的功能

  1. 根据QPS限流
  2. 根据线程数限流
  3. 根据调用方限流
  4. 黑白名单
  5. 根据调用链限流,比如分别统计从A、B掉C接口的逻辑
  6. 根据资源读写的竞争条件限流
  7. 异步限流接口支持
  8. 全局限流与单机限流

思考与总结

Sentinel本地限流通过读取注解、代码生成一个本地全局的context,通过context保存本地的调用信息:调用链、qps等等。当然对于注解会代理生成限流逻辑。

利用Sentinel全局限流,我们可以做基于优先级的限流,比如:当支付量大时,对其它相关的所有服务限流。

为什么用sentinel

  1. hystrix只支持api维度的熔断、降级,功能较少
  2. api使用更加简单,极低的代码侵入性
  3. 丰富的限流逻辑,满足各种需求
  4. 丰富的监控接口和dashboard
  5. 性能高以及限流的pipeline设计思路,基于前人的经验设计更加轻量、以扩展
  6. 稳定且有阿里中间件团队背书
  7. 资源限流不限于接口,支持任意的调用资源
功能 Sentinel Hystrix(Tesla)
功能 Sentinel Hystrix(Tesla)
隔离策略 信号量隔离 线程池隔离/信号量隔离
熔断降级策略 基于响应时间或失败比率 基于失败比率
实时指标实现 滑动窗口 滑动窗口(基于 RxJava)
规则配置 支持多种数据源 支持多种数据源
扩展性 多个扩展点 插件的形式
基于注解的支持 支持 支持
限流 基于 QPS,支持基于调用关系的限流 有限的支持
流量整形 支持慢启动、匀速器模式 不支持
系统负载保护 支持 不支持
控制台 开箱即用,可配置规则、查看秒级监控、机器发现等 不完善
常见框架的适配 Servlet、Spring Cloud、Dubbo、gRPC 等 Servlet、Spring Cloud Netflix

参考内容

Guava官方文档-RateLimiter类

Hystrix官方文档 https://segmentfault.com/a/1190000012439580

hystrix,限流入门指南 https://www.cnblogs.com/yepei/p/7169127.html

sentinel对比hystrix https://github.com/alibaba/Sentinel/wiki/Sentinel-%E4%B8%8E-Hystrix-%E7%9A%84%E5%AF%B9%E6%AF%94

相关文章
|
6月前
|
Java Sentinel
【熔断限流组件resilience4j和hystrix】
【熔断限流组件resilience4j和hystrix】
174 0
|
1月前
|
算法 NoSQL Java
服务、服务间接口限流实现
`shigen`是一位坚持更新博客的写手,专注于记录个人成长、分享认知与感动。本文探讨了接口限流的重要性,通过实例分析了在调用第三方API时遇到的“请求过多”问题及其解决方法,包括使用`Thread.sleep()`和`Guava RateLimiter`进行限流控制,以及在分布式环境中利用Redis实现更高效的限流策略。
36 0
服务、服务间接口限流实现
|
4月前
|
Java Spring
降级与熔断处理
降级与熔断处理
|
6月前
|
监控 Java 微服务
服务降级和服务熔断的区别
服务降级和服务熔断的区别
|
监控 Java 数据安全/隐私保护
sentinel流控降级与熔断
sentinel流控降级与熔断
99 0
|
前端开发 关系型数据库 MySQL
服务降级熔断小总结|学习笔记
快速学习服务降级熔断小总结
服务降级熔断小总结|学习笔记
|
缓存 算法 网络协议
限流实现2
剩下的几种本来打算能立即写完,没想到一下三个月过去了,很是尴尬。本次主要实现如下两种算法 - 令牌桶算法 - 漏斗算法
|
缓存 NoSQL 算法
限流实现-专题一
在实际业务中,经常会碰到突发流量的情况。如果公司基础架构做的不好,服务无法自动扩容缩容,在突发高流量情况下,服务会因为压力过大而崩溃。更恐怖的是,服务崩溃如同多米诺骨牌,一个服务出问题,可能影响到整个公司所有组的业务。
|
监控 算法 安全
限流
1. 为什么需要限流 2. 如何限流 限流主要就是考虑这两点
255 0
限流
|
算法 Java API