一文搞定算法和架构,微服务接口限流不用愁!

目录1、服务限流的概念2、单服务节点限流2.1、漏桶算法2.2、令牌桶算法3、服务集群限流4、限流的难点及注意事项5、作者简介线上系统遇到的一大风险就是流量的暴涨暴跌,尤其是在这个全民上网的时代,一条明星出轨的新闻带来的访问流量暴涨可以把微博给压趴。企业会优先通过扩容来尽量容纳所有的流量,以保障业务不受损失。但通过资源扩容来提升系统容量也不是无限的,不仅技术实现上不现实,从成本投入角度看也不划算。相对而言,更经济可行的方式是限流或者降级。这就像一些城市在上班高峰期车流量增大时,临时增调对行车道以增加通行容量;如果车流量再继续增大,就只能限行,控制进入车道的车辆数。本文将重点介绍微服务接口的限流算法及架构实现。1、服务限流的概念所谓限流,是根据某个应用或基础部件的某些核心指标,如总并发数、QPS或并发线程数,甚至是白名单,来决定是否将后续的请求进行拦截。比如我们设定1秒的QPS阈值为1000,如果某一秒的QPS为1100,那超出的100个请求就会被拦截掉,直接返回约定的错误码或提示页面。服务限流是在高流量下保证服务集群整体稳定,并提供一定可用性的有效办法。比起系统整体被“压趴”,所有用户都无法获得服务的状况,拒绝一部分用户,对另一部分用户提供正常服务总是要好一些。限流操作一定要前置,对于已经明确要被拒绝处理的流量,尽量不要放到后续环节。一方面可以避免不必要的资源浪费,另一方面也可以减少调用方无谓的等待。如图1所示,如果在服务调用方限流,则在接口调用发起时就可以进行限流控制;如果在服务提供方限流,则在请求接入后、解码前就可以进行限流控制。

图1 服务流控架构流控的模式也不仅仅局限于一种,可以采用多种流控模式的组合来应对复杂业务场景下的限流需求。比如,当发生热点事件时,可以先基于IP白名单,只允许联通用户的请求接入,在此基础上再基于QPS进行限流。对服务集群而言,单个服务节点的限流是基础,它是实现集群整体限流的前提,下面,我们首先介绍单服务节点的限流实现。2、单服务节点限流限流的目的不仅是要控制访问的总并发量,还要尽量让访问的流量来的更均衡,才不会让系统的负载大起大落,因此又称之为“流量整形”。在单点模式下有多种手段能达到“流量整形”式限流,也有很多组件可供选择,例如Java自带的信号量组件semaphore,Google Guava的RateLimiter组件等。那么,这些组件的限流模式有什么不同呢?2.1、漏桶算法很多受欢迎的餐厅在就餐高峰期都需要排队,餐厅为客满后再来的顾客发放排队号,当有顾客用餐完毕离开,就按排号顺序让最早的顾客进入餐厅就餐。这实际上就是一种限流措施,严格控制客流量稳定在餐厅的招待能力范围内。这种限流方式保证在餐厅内就餐的顾客总数(并发数)是一致的,只有出去一个顾客,才能放进来一个顾客。新来的顾客能不能吃上饭,完全取决于已就餐顾客是否“翻牌”。

图2 漏桶算法&令牌桶算法餐厅排号就餐的方式非常像一个漏桶,桶的容量是固定的,桶底的水不断的流出,桶顶的水不断流入,如果流入的水量(请求量)超出了流出的水量(最大并发量),桶满后新流入的水会直接溢出,这就是限流应用中常用的漏桶算法,如图2-1所示。漏桶算法可以很好的控制流量的访问速度,一旦超过该速度就拒绝服务。Java中自带的信号量组件Semaphore就是典型的基于漏桶算法的组件,它可以有效控制服务的最大并发总数,防止服务过载。以下是Semaphore的典型用法:01.         private Semaphore smp = new Semaphore(30);     //非公平策略02.         ...03.         if(smp.getQueueLength()>0){   //如果有排队现象,则立刻拒绝服务04.             return;05.         }06.         try{07.             smp.acquire();                      //获取一个信号量08.             //处理具体的业务逻辑09.         }catch(InterruptedException ex){10.             ex.printStackTrace();11.         }finally{12.             smp.release();      //释放信号量13.         }研究漏桶算法可以发现,它主要关注当前的并发总量(信号总量),只有某个资源被释放的信号发出(release操作),等待进入的请求才能获得通行证,有“出”才有“进”,通过这种方式,来保证系统负载可控。2.2、令牌桶算法限流的另一种常用算法是令牌桶算法,它的原理如图2-2所示,系统以恒定的速率往桶里放令牌,请求需要从桶里获得令牌才能被处理,一旦桶里无令牌可取,则拒绝服务。Google Guava的RateLimiter组件就是采用的令牌桶算法。下面是基于RateLimiter实现的简单限流示例:01.         RateLimiter limiter = RateLimiter.create(5);02.         System.out.println(limiter.acquire());03.         System.out.println(limiter.acquire());04.         System.out.println(limiter.acquire());05.         System.out.println(limiter.acquire());06.         System.out.println(limiter.acquire());代码运行之后,可以获得如下结果:0.00.1990130.1956620.1997810.200103上面的代码中,01行代码创建了一个容量为5的“桶”,并且每秒投入5个令牌。第一次申请一个令牌时(02行),当前桶中有足够的令牌,因此可以马上获取到,此时打印出来的等待时间是0。后面再请求令牌时,由于要达到“流量整形”的目标,RateLimiter会以固定周期,间歇性的往“桶”里投入令牌,平均时间间隔是1000ms/5=200ms左右,因此03~07行的代码运行就被阻塞了,从运行结果上看,基本符合理论计算的预期。可见,RateLimiter通过这种策略将突发请求速率平均为(整形成)固定请求速率。在实际应用中,对无法获取令牌,注定要被拒绝的请求可以快速抛弃,减少请求的等待时间,降低阻塞带来的无谓资源损耗。因此,实际使用中会更多使用无阻塞的tryAcquire方法,尽量少用阻塞的acquire方法。如下代码是常用的基于RateLimiter令牌桶的限流模式:01.     RateLimiter rateLimiter = RateLimiter.create(100);    //控制每秒只能有100个请求进来02.     if(!rateLimiter.tryAcquire()){   //判断是否能马上获取令牌,如不能则直接给客户端返回错误信息03.          //给客户端返回异常或者拒绝信息04.          return;05.      }06.      //下面是正常业务逻辑07.      ...;比较RateLimiter和Semaphore的限流,可以发现,RateLimiter并没有一个后置的、类似Semaphore的release这样显式的信号释放动作,其通过acquire和tryAcquire动作是否能够获取到令牌完全取决于时间,限流控制是在请求流入端进行。3、服务集群限流单机限流下,各个服务节点负责各自机器的限流,不关注其它节点,更不关注服务集群总调用量。因为后台总资源是有限的,有时虽然各个单节点的流量都没有超,但总流量会超过后台资源的总承受量,所以必须控制服务在所有节点上的总流量,这就是集群限流。总流量控制可以在前台通过网关来实施。但P2P直连模式的服务集群没有网关一说。所以要控制总流量,就必须先汇总集群各个服务节点的流量,并将这个总流量与预先设定的SLA阈值相比较,如果超了就要进行限流。比如SLA设置1000,总流量算出来是1200,那就超了200,这时就必须将总流量降到(1-(200/1200)),大概0.85左右。每个服务节点都要将当前流量降低到这个比例。由于流量的倾斜,每台机器的流量都不一样,需要将0.85这个限流比例推到各个服务节点,让每个节点基于自己之前统计的流量结合0.85限流比率算出各自的限流阈值。再根据各自的限流阈值去调用semaphore或者RateLimiter做单机限流。因此集群环境下的限流也要以单点的限流为基础,但流量判定上有所不同,集群环境下需要采集所有服务节点的流量信息进行统一判定,图3是典型的集群限流架构图。

图3 集群限流架构图服务集群限流基本遵循如下步骤:将时间分片,可以1分钟,也可以30秒钟、10秒钟,具体时间长度根据业务实际需求,也与线上日志的采集及处理能力相关。每个服务节点记录本节点的每次实际调用及调用延时,并统计本时间片内的总调用量及平均调用延时。一个时间片结束后,这个时间片内的调用计数会以日志的形式被采集并汇总到日志中心(如图3的步骤1),对日志的流式分析中会有专门的统计分析器对这些调用计数日志进行分析。当统计分析器确定所有的日志都已到位,会进行集群调用量的汇总,并基于时间片算出这个时间片对应的此服务集群的QPS(步骤2)。分析器集合中的集群限流分析器根据统计分析器的结果,并结合服务注册中心中定义的限流配置来判断是否需要进行限流控制。对于一些自动化程度高的系统,可能还要综合平均调用延时及服务等级协议(SLA)来做综合评判,如果实际流量超过了限流阈值(或者综合评判满足限流条件),则计算出一个限流比例(步骤3)。不考虑其他因素的限流比例的计算公式如下:限流比例=1-(实际QPS-限流QPS)/实际QPS集群限流分析器将“限流比例”指标写入服务注册中心(步骤4),并通过服务注册中心的事件推送机制将此配置下发到各服务节点。服务节点基于获取到的限流比例,根据对应时间片的调用量换算出限流调用量,再采用“单点限流”的限流策略进行限流控制。从上述步骤可见,服务集群的限流机制比较复杂,需要依赖监控、计数、分析、配置下发、节点流控等各个能力的协同配合,缺一不可。为了实现高效的集群限流控制,必须实现各个环节的高效处理,要注意以下几个方面:时间片太长,会导致限流操作滞后,可能限流指令还未下发,服务集群就被压垮了,因此要尽量缩短时间片的长度。但时间片也不是越小越好,由于流量的波动,太小的时间片计算出来的QPS可能会有较大偏差。所以,需要根据线上流量特点来评估时间片的长度设置。日志采集一定要及时,时间片一结束,要尽快将计数日志发出,可以让计数日志采用单独的日志文件,并配置独立的采集器,优先保障其信息采集。如果采用消息队列对日志数据进行缓冲,可以给访问计数日志设置独立的Topic,以提高其处理优先级。对计数日志的分析一定要采用实时分析,不能是离线分析,否则不具有时效性。4、限流的难点及注意事项如果只是单纯的单点限流其实并不难,有很多现成的组件可以选择。但如果要构建系统的限流体系又是一件极“难”的事情。它的难度在于,由于涉及服务节点的调用监控、日志采集发送、日志接收聚合、计算分析、限流决策判断、指令下发、节点限流等许多环节,要实现各环节的高效衔接和紧密协作配合,需要整个技术栈的统一及协同调度。所以说,要构建一套行之有效的限流体系,必须统一微服务框架、日志采集规范、日志分析规范、SLA的定义及节点限流的技术策略,这些都要有很明确的要求。如果某些环节使用的框架不同,那么这套统一的技术体系就无法推广落地。试想,如果企业内部同时存在基于Java和Go两种语言构建的微服务框架,那么针对它们的节点限流就必须要创建两套不同语言的节点限流及对应计数、日志采集的能力,相应的开发及维护成本也会升高。技术栈的统一,依赖于技术体系的标准化建设。如果在IT建设的初期就注重技术选型及构建的标准化,后续在构建新能力时,就可以有效减少业务代码的改变和调整。不仅仅是限流体系,还有治理工作甚至运维自动化遇到的大部分困难往往都是标准化缺失导致的。“没有规矩,不成方圆”,这里的规矩就是我们从各式各样的IT运维对象及流程中提取出来的标准和规范,也是构建自动化及智能化运维能力的前提。所以,一定要重视标准化的建设,具体到限流体系的构建上也是如此,要“标准先行”。限流体系的标准涉及如下几点:节点限流策略的选择及集成;节点调用度量时间片的设定策略;计数日志采集规范及度量规范;限流配置规范;限流指令规范。本文节选自《微服务治理:体系、架构及实践》一书5、作者简介作者简介: 著有《微服务治理:体系、架构及实践》一书,目前在金融行业负责基金直销平台的整体技术架构和技术团队管理;在此之前,在华为的中间件技术团队,任六级技术专家,主导了多款华为软件的云计算产品的规划、设计、构建及落地工作,包括APaaS、ASPaaS、服务治理平台、分布式服务调测框架等几款产品;更早之前,在当当网的运作产品中心做技术负责人,主要负责电商中后台的仓储、物流、客服等系统的重构优化及技术管理工作。个人从业十多年,在并行计算、大规模分布式服务及治理、中间件云化及服务化(PaaS)、APM监控、基础开发平台、数据集成及治理等领域都有技术积累,如果大家在这些领域有疑问或好的建议,欢迎共同探讨。。

(0)

相关推荐

  • 生产环境中的Kubernetes最佳实践

    DevOps从提出到现在,已经走过了一段很长的路.包括Docker和Kubernetes在内的多种平台也已经帮助企业用前所未有的速度实现了软件应用的交付.同时,随着应用的容器化构建和发布比率不断上升, ...

  • 2020年11月CERNET主干网总流量达2020年最高值

    2020年11月CERNET主干网 总流量达2020年最高值 文/李锁钢 2020年11月CERNET主干网网络运行正常. 11月CERNET主干网总流量相比于10月增加了37.5G:国内互联互通总流 ...

  • 7月CERNET2出口入流量峰值32G

    7月CERNET主干网总流量比6月降78G 文/李锁钢 2020年7月CERNET主干网网络运行正常. 7月CERNET主干网总流量相比6月有所减少,主要原因是高校进入暑假.主干网总流量相比于6月减少 ...

  • Hadoop跨机房架构选型与改造落地

    作者介绍 昱康,携程架构师,对分布式计算和存储.调度.查询引擎.在线离线混部.高并发等方面有浓厚兴趣. 本文将分享携程Hadoop跨机房架构实践,包含Hadoop在携程的发展情况,整个跨机房项目的背景 ...

  • 10月CERNET主干网总流量达疫情以来最高值

    10月CERNET主干网 总流量达疫情以来最高值 文丨李锁刚 2020年10月CERNET主干网网络运行正常. 10月CERNET主干网总流量相比于9月增加了59.98G:国内互联互通总流量相比于9月 ...

  • 8月CERNET2主干网入流量环比增22.84%

    8月CERNET主干网总流量比7月增58G 文/李锁钢 2020年8月CERNET主干网网络运行正常. 8月CERNET主干网总流量相比7月有所增加,主要原因是高校陆续开学,用户逐渐增加.主干网总流量 ...

  • 稳定性五件套-限流的原理和实现

    背景 最近了解到很多朋友对限流.熔断.降级.隔离.超时重试的概念和应用场景理解的不是很到位,所以想用五篇的篇幅稍微系统的介绍一下. 本篇是第一篇,是限流做详解,如果反馈好的话,我会继续写下面四篇.不好 ...

  • 微服务架构师的道、法、术

    作者:李鑫 | 天弘基金移动直销平台技术负责人 出品:百林哲 导语: 这几年微服务的热度持续居高不下,企业纷纷向微服务架构转型.但微服务架构会对整个研发体系,包括开发.运维.团队协同.组织架构都带来冲 ...

  • 4月CERNET主干网总流量比3月增23.63G

    4月CERNET主干网总流量比3月增23.63G 文/李锁钢 2020年4月CERNET主干网网络运行正常. 4月CERNET主干网总流量相比3月有所增加,主要原因是部分高校毕业年级开学,用户流量增加 ...

  • 通过API网关实现微服务管控-限流,熔断和降级

    今天准备谈下基于API网关来实现微服务治理管控中的服务限流,熔断和降级方面的内容.在前面谈微服务架构的时候也谈到过类似通过Hystrix,Sentinel来是服务限流熔断.包括也不断地在谈去中心化架构 ...

  • 【深度学习】一文搞定面试中的优化算法

    深度学习各类优化器 借用古代炼丹的一些名词,我们可以把训练模型中的数据比做炼丹药材,模型比做炼丹炉,火候比做优化器.那么我们知道,同样的药材同样的炼丹炉,但是火候不一样的话,炼出来的丹药千差万别,同样 ...

  • 伴脑微出血的房颤患者,该不该抗凝?一文搞定

    房颤伴脑微出血(MB)的患者一直被视为棘手的病例.房颤需要抗凝,脑出血又需要抗栓,医生处于进退两难的境地. 一.疾病特点 付教授首先从一个临床病例进行引入.患者为一名78岁的女性,有房颤.高血压和两次 ...

  • 劳务报酬所得的预扣个税有4种算法?一文搞定,赶快来get一下吧!

    劳务报酬所得的预扣个税有4种算法?一文搞定,赶快来get一下吧! 彭怀文 国家税务总局于2020年7月28日发布<关于完善调整部分纳税人个人所得税预扣预缴方法的公告>(国家税务总局公告20 ...

  • 5类降压药物有何区别?男性和女性如何选择降压药?一文搞定!

    作者:高丽丽 来源:药评中心 高血压是一种常见的慢性病.女性高血压受年龄.月经周期.生育及疾病过程和特殊药物等多方面影响,比男性高血压更复杂.那么,男性高血压和女性高血压患者,在选择降压药方面有什么区 ...

  • 5类降压药物有何区别?男性和女性该如何选择降压药?一文搞定!

    *仅供医学专业人士阅读参考 妊娠期.哺乳期.更年期......用药各不同! 高血压是一种常见的慢性病.女性高血压受年龄.月经周期.生育及疾病过程和特殊药物等多方面影响,比男性高血压更复杂.那么,男性高 ...

  • 一文搞定最值系列之“瓜豆原理”(附word)

    作者简介: 朱昌伟,中学教师,9年教龄.毕业于北京师范大学,双学士学位.江苏省"优秀青年教师",现任深圳市耐思培优总校区理科教研组长,主编的<初中几何模型与解题通法>已 ...

  • 一文搞定初中数学9大重要几何模型

    重要几何模型1--半角模型 模型特点 倍长中线或类中线(与中点有关的线段)构造全等三角形 如图①: (1)∠2=1/2∠AOB:(2)OA=OB. 如图②: 连接 FB,将△FOB 绕点 O 旋转至△ ...

  • 一文搞定!MR上脑出血信号的演变机制

    之前写过一篇关于脑出血MR信号演变机制的文章,可能是有点偏难,阅读人数很低,后来我就把这篇文章删了.不过在2020年放射规培结业理论考试中,脑出血MR信号演变居然考了一道大题(多选题),既然这么重要, ...