高可用之限流降级_压测流量降级-程序员宅基地

技术标签: 限流  降级  高可用  

高可用之限流降级

1、前言

在大规模微服务架构的场景下,为了避免服务出现雪崩,要减少停机时间,尽可能的提高服务可用性。提高服务可用性,可以从很多方向入手,比如缓存、池化、异步化、负载均衡、队列和降级熔断等手段。

  • 缓存以及队列等手段,增加系统的容量
  • 限流和降级则是关心在到达系统瓶颈时系统的响应,更看重稳定性

缓存和异步等关注提高系统战力,而限流降级则关注增强系统防御,具体实施方法可以归纳为八字箴言,限流、降级、熔断、隔离

2、限流&降级

2.1、限流

  • 限流,顾名思义,即提前对各个类型的请求设置最高的QPS阈值,若高于设置的阈值则对该请求直接返回,不再调用后续资源

  • 限流需要结合压测等,了解系统的最高水位,也是在实际开发中应用最多的一种稳定性保障手段。

2.2、降级

  • 降级,则是指在系统调用高峰时,优先保证核心服务,对于非核心服务可以选择将其关闭以保证核心服务的可用。 例如在淘宝双11时,支付功能是核心,其他诸如用户中心等非核心功能可以选择降级,优先保证交易。

  • 从降级配置方式上,降级一般可以分为主动降级和自动降级

    • 主动降级是提前配置,自动降级则是系统发生故障时,如超时或者频繁失败,自动降级。
    • 其中自动降级,又可以分为以下策略:
      • 超时降级
      • 失败次数降级
      • 故障降级

2.3、降级通知设计

在系统设计中,降级一般是结合系统配置中心,通过配置中心进行推送,下面是一个典型的降级通知设计:

img

3、 熔断&隔离

3.1、熔断

  • 如果某个目标服务调用慢或者有大量超时,此时熔断该服务的调用,对于后续调用请求,不在继续调用目标服务,直接返回,快速释放资源。

  • 熔断一般需要设置不同的恢复策略,如果目标服务情况好转则恢复调用。

3.2、隔离

服务隔离与前面的三个略有区别,我们的系统通常提供了不止一个服务,但是这些服务在运行时是部署在一个实例,或者一台物理机上面的,如果不对服务资源做隔离,一旦一个服务出现了问题,整个系统的稳定性都会受到影响!

  • 服务隔离的目的就是避免服务之间相互影响。一般来说,隔离要关注两方面,一个是在哪里进行隔离,另外一个是隔离哪些资源。
  • 何处隔离?

    • 一次服务调用,涉及到的是服务提供方和调用方,我们所指的资源,也是两方的服务器等资源,服务隔离通常可以从提供方和调用方两个方面入手。
  • 隔离什么?

    • 广义的服务隔离,不仅包括服务器资源,还包括数据库分库,缓存,索引等,这里我们只关注服务层面的隔离。

3.3、降级和熔断的区别

服务降级和熔断在概念上比较相近,通过两个场景,谈谈我自己的理解。

  • 熔断,一般是停止服务

典型的就是股市的熔断,如果大盘不受控制,直接休市,不提供服务,是保护大盘的一种方式。

  • 降级,通常是有备用方案

从深圳到郑州,下雨导致航班延误,我可以乘坐高铁,如果高铁票买不到,也可以乘坐汽车或者开车过去。

  • 两者的区别

降级一般是主动的,有预见性的,熔断通常是被动的,服务A降级以后,一般会有服务B来代替,而熔断通常是针对核心链路的处理。实际开发中,熔断的下一步通常就是降级

4、常用限流算法设计

4.1、计数器法

计数器法是限流算法里最简单也是最容易实现的一种算法。

  • 假设一个接口限制一分钟内的访问次数不能超过100个,维护一个计数器,每次有新的请求过来,计数器加一,这时候判断,如果计数器的值小于限流值,并且与上一次请求的时间间隔还在一分钟内,允许请求通过,否则拒绝请求,如果超出了时间间隔,要将计数器清零。

  • 计数器限流可以比较容易的应用在分布式环境中,用一个单点的存储来保存计数值,比如用Redis,并且设置自动过期时间,这时候就可以统计整个集群的流量,并且进行限流。

  • 计数器方式的缺点是不能处理临界问题,或者说限流策略不够平滑。假设在限流临界点的前后,分别发送100个请求,实际上在计数器置0前后的极短时间里,处理了200个请求,这是一个瞬时的高峰,可能会超过系统的限制。

  • 计数器限流允许出现2*permitsPerSecond 的突发流量,可以使用滑动窗口算法去优化

4.2 漏桶算法

  • 假设我们有一个固定容量的桶,桶底部可以漏水(忽略气压等,不是物理问题),并且这个漏水的速率可控的,那么我们可以通过这个桶来控制请求速度,也就是漏水的速度。

  • 我们不关心流进来的水,也就是外部请求有多少,桶满了之后,多余的水会溢出。

漏桶算法的示意图如下:

img
  • 将算法中的水换成实际应用中的请求,可以看到漏桶算法从入口限制了请求的速度。
  • 使用漏桶算法,我们可以保证接口会以一个常速速率来处理请求,所以漏桶算法不会出现临界问题。漏桶算法无法解决系统突发流量的情况
  • 可以使用GuavaSmoothWarmingUp类,可以更好的控制漏桶算法,

4.3 令牌桶算法

  • 假设一个大小恒定的桶,桶里存放着令牌(token)。桶一开始是空的,现在以一个固定的速率往桶里填充,直到达到桶的容量,多余的令牌将会被丢弃。

  • 如果令牌不被消耗,或者被消耗的速度小于产生的速度,令牌就会不断地增多,直到把桶填满。后面再产生的令牌就会从桶中溢出。最后桶中可以保存的最大令牌数永远不会超过桶的大小,

  • 每当一个请求过来时,就会尝试从桶里移除一个令牌,如果没有令牌的话,请求无法通过

  • 在令牌桶算法中,只要令牌桶中存在令牌,那么就允许突发地传输数据直到达到用户配置的门限,因此它适合于具有突发特性的流量。

4.4、令牌桶和漏桶区别

  • 漏桶是控制水流入的速度,令牌桶则是控制流出,通过控制token,调节流量。

  • 令牌桶算法相对漏桶算法的优势在于可以处理系统的突发流量

  • 这两种算法的主要区别在于漏桶算法能够强行限制数据的传输速率,而令牌桶算法在能够限制数据的平均传输速率外,还允许某种程度的突发传输。

5、使用RateLimiter实现限流

  • Google开源工具包Guava提供了限流工具类RateLimiter,该类基于令牌桶算法实现流量限制,使用方便。

  • RateLimiter使用的是令牌桶的流控算法,RateLimiter会按照一定的频率往桶里扔令牌,线程拿到令牌才能执行,比如你希望自己的应用程序QPS不要超过1000,那么RateLimiter设置1000的速率后,就会每秒往桶里扔1000个令牌,方法说明如下:

import com.google.common.util.concurrent.RateLimiter;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class RateLimiterExample {
    

    public static void main(String[] args) throws InterruptedException {
    
        // qps设置为5,代表一秒钟只允许处理五个并发请求
        RateLimiter rateLimiter = RateLimiter.create(5);
        ExecutorService executorService = Executors.newFixedThreadPool(5);
        int nTasks = 10;
        CountDownLatch countDownLatch = new CountDownLatch(nTasks);
        long start = System.currentTimeMillis();
        for (int i = 0; i < nTasks; i++) {
    
            final int j = i;
            executorService.submit(() -> {
    
                rateLimiter.acquire(1);
                try {
    
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
    
                }
                System.out.println(Thread.currentThread().getName() + " gets job " + j + " done");
                countDownLatch.countDown();
            });
        }
        executorService.shutdown();
        countDownLatch.await();
        long end = System.currentTimeMillis();
        System.out.println("10 jobs gets done by 5 threads concurrently in " + (end - start) + " milliseconds");
    }
}


5.1、算法原理

RateLimiter基于令牌桶算法,它的核心思想主要有:

  1. 响应本次请求之后,动态计算下一次可以服务的时间,如果下一次请求在这个时间之前则需要进行等待。SmoothRateLimiter类中的 nextFreeTicketMicros 属性表示下一次可以响应的时间。例如,如果我们设置QPS为1,本次请求处理完之后,那么下一次最早的能够响应请求的时间一秒钟之后。
  2. RateLimiter 的子类 SmoothBursty 支持处理突发流量请求,例如,我们设置QPS为1,在十秒钟之内没有请求,那么令牌桶中会有10个(假设设置的最大令牌数大于10)空闲令牌,如果下一次请求是 acquire(20) ,则不需要等待20秒钟,因为令牌桶中已经有10个空闲的令牌SmoothRateLimiter 类中的 storedPermits 就是用来表示当前令牌桶中的空闲令牌数。
  3. acquire 方法没有等待超时的概念,会一直阻塞直到满足本次请求。
  4. RateLimiter 子类SmoothWarmingUp 不同于SmoothBursty,它存在一个“热身”的概念。它将 storedPermits 分成两个区间值:[0, thresholdPermits) 和 [thresholdPermits, maxPermits]。当请求进来时,如果当前系统处于"cold"的状态,从 [thresholdPermits, maxPermits] 区间去拿令牌,所需要等待的时间会长于从区间 [0, thresholdPermits) 拿相同令牌所需要等待的时间。当请求增多,storedPermits 减少到 thresholdPermits 以下时,此时拿令牌所需要等待的时间趋于稳定。这也就是所谓“热身”的过程。这个过程后面会详细分析。

RateLimiter主要的类的类图如下所示:

image-20200813074533804

RateLimiter 是一个抽象类,SmoothRateLimiter继承自RateLimiter,不过 SmoothRateLimiter 仍然是一个抽象类,SmoothBurstySmoothWarmingUp 才是具体的实现类。

5.2、SmoothRateLimiter主要属性

storedPermits 表明当前令牌桶中有多少令牌。maxPermits 表示令牌桶最大令牌数目,storedPermits 的取值范围为:[0, maxPermits]。stableIntervalMicros 等于 1/qps,它代表系统在稳定期间,两次请求之间间隔的微秒数。例如:如果我们设置的 qps 为5,则 stableIntervalMicros 为200ms。nextFreeTicketMicros 表示系统处理完当前请求后,下一次请求被许可的最短微秒数,如果在这之前有请求进来,则必须等待。

当我们设置了 qps 之后,需要计算某一段时间系统能够生成的令牌数目,那么怎么计算呢?一种方式是开启一个后台任务去做,但是这样代价未免有点大。RateLimiter 中采取的是惰性计算方式:在每次请求进来的时候先去计算上次请求和本次请求之间应该生成多少个令牌。

【面试系列】会持续更新,欢迎关注公众号“任冬学编程”,一起学习与进步!

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_29893385/article/details/120004980

智能推荐

大数据认知实习的实习目的_如何在数据实习中取得成功-程序员宅基地

文章浏览阅读3.4k次。大数据认知实习的实习目的With internship season well underway, we reached out to some Alteryx ACEs, top analytics experts and participants in the Alteryx Community, to see what advice they’d offer to interns in da..._实习目的大数据

地理信息系统学习笔记——地图开发相关介绍_地图数据发布系统的开发是否属于研发活动-程序员宅基地

文章浏览阅读3k次。最近看了一些地图开发的文章,在此做一下记录。 估计很大一部分人认为地图开发就是基于高德地图、百度地图、腾讯地图结合自己的业务进行二次开发,这只是一个方面。在这些地图上做的二次开发仅仅是方便用户导航到自己业务所在的位置,要是再往深层次走的话,做一些定制化的地图的开发则不止力不从心,很多时候也无法实现。比如城市给水排水管网信息管理,这就是定制性开发,也可称行业应用。本人通过学习Naa(李晓辉) 该博主_地图数据发布系统的开发是否属于研发活动

全面理清概念,C风格字符串(多重定义方式,区别,易错点)-程序员宅基地

文章浏览阅读1.5k次,点赞4次,收藏11次。字符数组方式定义C风格字符串编译器会自动计算字符串长度,并为字符数组分配适当的空间(包括空字符)。这个例子中,str 是一个包含14个字符的数组,包括13个实际字符和1个空字符。指针方式定义C风格字符串str 是一个指针,它指向一个字符串常量。因此,尽管你可以更改指针指向的位置,但不能通过指针来更改字符串内容。试图修改字符串常量的内容可能导致未定义的行为。// 错误!不能修改字符串常量的内容在使用这种写法时,字符串的长度不需要显式指定。编译器会自动计算字符串长度,并在末尾添加空字符。_c风格字符串

c语言指针定义和使用-程序员宅基地

文章浏览阅读948次,点赞2次,收藏9次。数据内存中的地址也称为指针,如果一个变量存储了一份数据的指针,我们就称它为指针变量。定义指针变量定义指针变量与定义普通变量非常相似,不过要在变量名前加星号 * ,格式为:datatype *name ; 或者dataype *name = value;* 表示一个指针变量,datatype表示该指针变量所指向的数据的类型。例如:int *p1;p1 是一个指向int...

一个适用于单片机的开源网络协议栈_单片机简单协议栈,2024年最新Golang插件化入门指南-程序员宅基地

文章浏览阅读781次,点赞17次,收藏15次。onps是一个开源且完全自主开发的国产网络协议栈,适用于资源受限的单片机系统,提供完整地ethernet/ppp/tcp/ip协议族实现,同时提供sntp、dns、ping等网络工具,支持以太网环境下dhcp动态ip地址申请,也支持动态及静态路由表。协议栈还封装实现了一个伯克利套接字(Berkeley sockets)层。

苹果系统Fn键怎样使用?_ios fn+1-程序员宅基地

文章浏览阅读1.2k次。大家有没有发现Mac的键盘上是没有Home, End, Page UP, Page DOWN这几个功能键?其实可以用Fn键来组合得到同样的功能,Mac键盘上的Fn键除了用来配合F1-F12实现一些特殊硬件功能外(如屏幕亮度、喇叭大小声、itunes的控制等),还有几个比较少人知道的用处,macz小编就给大家介绍几个关于Mac上Fn键的小技巧。1、Home键=Fn+左方向2、End键=Fn+右方向3、PageUP=Fn+上方向4、PageDOWN=Fn+下方向5、向前Delete=Fn+dele_ios fn+1

随便推点

[debug] PyTorch报错:ConnectionResetError: [Errno 104] Connection reset by peer_pytorch issue connection reset by peer-程序员宅基地

文章浏览阅读1w次。问题描述:使用PyTorch 1.10.0,训练报错:ConnectionResetError: [Errno 104] Connection reset by peer问题解析参见pytorch的issueI believe the issue is only triggered for the case that bothpersistent_workers and pin_memory are turned on and iteration isterminated at the t_pytorch issue connection reset by peer

openwrt 之 DNS配置文件修改_openwrt nameserver-程序员宅基地

文章浏览阅读2.9w次,点赞2次,收藏5次。参考:http://www.openwrt.org.cn/bbs/thread-1639-1-1.html我在openwrt的web界面修改的wan口dns服务器为8.8.8.8。但是通过ssh查看/etc/resolv.conf文件发现总是被重置为了:root@Wrv54g:~# cat /etc/resolv.conf search lannam_openwrt nameserver

Linux学习必备基础知识_链接程序,共同完成任务-程序员宅基地

文章浏览阅读257次。1. 计算机的功能及组成_链接程序,共同完成任务

【推荐】骡友们推荐的各个学习英文网站的汇总【选择自CSDN i_like_cpp 的 Blog】...-程序员宅基地

文章浏览阅读2.9k次。骡友们推荐的各个学习英文网站的汇总。--------------------------------------------------------------------------------http://www.edunet.com/elt 主题:是一个全方位的学英语作为第二语言的网站 功能:聊天室,语法讲解,练习,小测试,成语讲解 特色:特别深入地介绍了语法,听力,沟通技巧等 对象:ESL..._qc 学习网站

DCN神州数码WAF-P-2021命令行恢复出厂_dcn-waf怎么用console重置-程序员宅基地

文章浏览阅读213次。注意:执行该命令将会清除设备的所有配置信息,包括网络配置、安全策略等,并将设备恢复到出厂设置时的默认配置。在执行该操作之前,请务必备份重要的设备配置信息。启动后,网线接G5口web登陆https://192.168.254.1输入帐号密码admin/yunke1234!Console接入波特率9600,输入帐号密码admin/yunke1234!进入后输入facroryreset -R回车,设备自动重启。_dcn-waf怎么用console重置

Sophus安装_error: static assertion failed: cannot format an a-程序员宅基地

文章浏览阅读747次。Sophus安装 SLAM 说明fmt安装未成功,安装8.1.1版本的fmt参考:解决办法 Ceres 2.0.0没有manifold.h 修改Sophus/test/ceres/CMakeLists.txt和 Sophus/test/core/CMakeLists.txt 中的下面这句话,使用2.1.0的版本_error: static assertion failed: cannot format an argument. to make type t fo

推荐文章

热门文章

相关标签