令牌桶算法

高并发场景下的限流策略

≯℡__Kan透↙ 提交于 2019-11-28 05:15:22
高并发场景下的限流策略:   在开发高并发系统时,有很多手段来保护系统:缓存、降级、限流。   当访问量快速增长、服务可能会出现一些问题(响应超时),或者会存在非核心服务影响到核心流程的性能时, 仍然需要保证服务的可用性,即便是有损服务。所以意味着我们在设计服务的时候,需要一些手段或者关键数据进行自动降级,或者配置人工降级的开关。 缓存的目的是提升系统访问速度和增大系统处理的容量,可以说是抗高并发流量的银弹;降级是当服务出问题或者影响到核心流程的性能则需要暂时屏蔽掉某些功能,等高峰或者问题解决后再打开;而有些场景并不能用缓存和降级来解决,比如秒杀、抢购;写服务(评论、下单)、频繁的复杂查询,因此需要一种手段来限制这些场景的并发/请求量性能调优是针对于代码本身的不规范性和系统资源的瓶颈的,当计算机的硬件资源达到瓶颈的时间已经无法调优了。高并发场景下一方面通过缓存,异步化,服务化,集群去增加整个系统的吞吐量,另一方面通过限流,降级来保护系统。 限流的作用:   在各大节假日旅游高峰期,各大旅游景点都是人满为患。所有有些景点为了避免出现踩踏事故,会采取限流措施。那在架构场景中,是不是也能这么做呢?针对这个场景,能不能够设置一个最大的流量限制,如果超过这个流量,我们就拒绝提供服务,从而使得我们的服务不会挂掉。当然,限流虽然能够保护系统不被压垮,但是对于被限流的用户,就会很不开心

限流算法

為{幸葍}努か 提交于 2019-11-27 10:18:29
简介 令牌桶算法 令牌桶算法最初来源于计算机网络。在网络传输数据时,为了防止网络拥塞,需限制流出网络的流量,使流量以比较均匀的速度向外发送。令牌桶算法就实现了这个功能,可控制发送到网络上数据的数目,并允许突发数据的发送。 令牌桶算法是网络流量整形(Traffic Shaping)和速率限制(Rate Limiting)中最常使用的一种算法。典型情况下,令牌桶算法用来控制发送到网络上的数据的数目,并允许突发数据的发送。 大小固定的令牌桶可自行以恒定的速率源源不断地产生令牌。如果令牌不被消耗,或者被消耗的速度小于产生的速度,令牌就会不断地增多,直到把桶填满。后面再产生的令牌就会从桶中溢出。最后桶中可以保存的最大令牌数永远不会超过桶的大小。 传送到令牌桶的数据包需要消耗令牌。不同大小的数据包,消耗的令牌数量不一样。 令牌桶这种控制机制基于令牌桶中是否存在令牌来指示什么时候可以发送流量。令牌桶中的每一个令牌都代表一个字节。如果令牌桶中存在令牌,则允许发送流量;而如果令牌桶中不存在令牌,则不允许发送流量。因此,如果突发门限被合理地配置并且令牌桶中有足够的令牌,那么流量就可以以峰值速率发送。 漏桶算法 漏桶(Leaky Bucket)算法思路很简单,水(请求)先进入到漏桶里,漏桶以一定的速度出水(接口有响应速率),当水流入速度过大会直接溢出(访问频率超过接口响应速率),然后就拒绝请求

关于分布式服务限流的一些思考

一世执手 提交于 2019-11-27 10:09:25
限流必然是很有价值的,在系统资源不足时面对外部世界的不确定性(突发流量,超预期的用户)而形成的一种自我保护机制。 但是价值感是很低的,因为99.99%的时候系统总是工作在安全线之下,甚至一年到头都碰不到一次撞线的机会。这就好比法律,它始终存在,但是大部分时候对于大多数人它几乎不存在,或者说感知不到它的存在。 一、限流的作用 由于API接口无法控制调用方的行为,因此当遇到瞬时请求量激增时,会导致接口占用过多服务器资源,使得其他请求响应速度降低或是超时,更有甚者可能导致服务器宕机。 限流(Rate limiting)指对应用服务的请求进行限制,例如某一接口的请求限制为100个每秒,对超过限制的请求则进行快速失败或丢弃。 限流可以应对: 热点业务带来的突发请求; 调用方bug导致的突发请求; 恶意攻击请求。 因此,对于公开的接口最好采取限流措施。 二、为什么要分布式限流 当应用为单点应用时,只要应用进行了限流,那么应用所依赖的各种服务也都得到了保护。 但线上业务出于各种原因考虑,多是分布式系统,单节点的限流仅能保护自身节点,但无法保护应用依赖的各种服务,并且在进行节点扩容、缩容时也无法准确控制整个服务的请求限制。 而如果实现了分布式限流,那么就可以方便地控制整个服务集群的请求限制,且由于整个集群的请求数量得到了限制,因此服务依赖的各种资源也得到了限流的保护。 三、限流的算法

面试官:来谈谈限流-RateLimiter源码分析

跟風遠走 提交于 2019-11-27 09:59:41
  RateLimiter有两个实现类:SmoothBursty和SmoothWarmingUp,其都是令牌桶算法的变种实现,区别在于SmoothBursty加令牌的速度是恒定的,而SmoothWarmingUp会有个预热期,在预热期内加令牌的速度是慢慢增加的,直到达到固定速度为止。其适用场景是,对于有的系统而言刚启动时能承受的QPS较小,需要预热一段时间后才能达到最佳状态。   基本使用   RateLimiter的使用很简单:   //create方法传入的是每秒生成令牌的个数   RateLimiter rateLimiter= RateLimiter.create(1);   for (int i = 0; i < 5; i++) {   //acquire方法传入的是需要的令牌个数,当令牌不足时会进行等待,该方法返回的是等待的时间   double waitTime=rateLimiter.acquire(1);   System.out.println(System.currentTimeMillis()/1000+" , "+waitTime);   }   输出如下:   1548070953 , 0.0   1548070954 , 0.998356   1548070955 , 0.998136   1548070956 , 0.99982   需要注意的是

Java限流——RateLimiter使用

ε祈祈猫儿з 提交于 2019-11-27 02:25:51
Java限流策略 概要 在大数据量高并发访问时,经常会出现服务或接口面对暴涨的请求而不可用的情况,甚至引发连锁反映导致整个系统崩溃。此时你需要使用的技术手段之一就是限流,当请求达到一定的并发数或速率,就进行等待、排队、降级、拒绝服务等。在限流时,常见的两种算法是漏桶和令牌桶算法算法。 限流算法 令牌桶(Token Bucket)、漏桶(leaky bucket)和计数器算法是最常用的三种限流的算法。 1. 令牌桶算法 令牌桶算法的原理是系统会以一个恒定的速度往桶里放入令牌,而如果请求需要被处理,则需要先从桶里获取一个令牌,当桶里没有令牌可取时,则拒绝服务。 当桶满时,新添加的令牌被丢弃或拒绝。 优点:能处理瞬间增大的流量,比如现在正常情况下每秒产生5个令牌,在预制了5个令牌,如果一瞬间流量为一秒8个令牌,首先这一秒正常能生成5个令牌,在加上预制了5个令牌,所以可以处理这个瞬间流量 public class RateLimiterDemo { // 每秒生成5个令牌,预制5个令牌 private static RateLimiter limiter = RateLimiter.create(5); public static void exec() { // limiter.acquire() 表示消费一个令牌。当桶中有足够的令牌时,则直接返回0,否则阻塞,直到 //

RateLimiter限流

让人想犯罪 __ 提交于 2019-11-26 20:35:12
1、处理高并发   1.1高并发处理方案:  缓存 缓存的目的是提升系统访问速度和增大系统处理容量 降级 降级是当服务出现问题或者影响到核心流程时,需要暂时屏蔽掉,待高峰或者问题解决后再打开 限流 限流的目的是通过对并发访问/请求进行限速,或者对一个时间窗口内的请求进行限速来保护系统,一旦达到限制速率则可以拒绝服务、排队或等待、降级等处理   1、2限流方式: mq、ratelimiter    2、ratelimiter是基于令牌桶算法来做的    guava的RateLimiter使用的是令牌桶算法,也就是以固定的频率向桶中放入令牌,例如一秒钟10枚令牌,实际业务在每次响应请求之前都从桶中获取令牌,只有取到令牌的请求才会被成功响应,获取的方式有两种:阻塞等待令牌或者取不到立即返回失败 另外简单介绍漏铜算法:   请求以一定速度进入漏桶中,如果请求速度>处理请求速度则溢出,漏桶算法能强行处理请求速率。但如果在处理高并发时,突然来大量请求这种方案不合适   令牌桶代码:create():每秒创建多少令牌       tryacquire():尝试获取令牌,tryacquire():尝试获取一个令牌,如果获取不到立即返回;tryacquire(int permits, long timeout, TimeUnit unit):尝试获取permits个令牌

RateLimiter服务限流实现

本小妞迷上赌 提交于 2019-11-26 20:34:59
目录 服务限流 需求 算法 通过限制单位时间段内调用量来限流 通过限制系统的并发调用程度来限流 漏桶算法 令牌桶算法 代码 限流设计 环境配置 配置文件 限流服务 切面拦截 测试 测试环境 测试结果 总结 服务限流 需求 1、针对单机的服务流量进行控制,避免突发大流量造成服务异常。2、对业务无侵入。 算法 现在主流的几种限流方式: 通过限制单位时间段内调用量来限流 通过限制系统的并发调用程度来限流 使用漏桶(Leaky Bucket)算法来进行限流 (使用令牌桶(Token Bucket)算法来进行限流 通过限制单位时间段内调用量来限流 通过限制某个服务的单位时间内的调用量来进行限流。我们需要做的就是通过一个计数器统计单位时间段某个服务的访问量,如果超过了我们设定的阈值, 则该单位时间段内则不允许继续访问,或者把接下来的请求放入队列中等待到下一个单位时间段继续访问。 优点:实现简单,阈值可动态配置。 缺点:若单位时间内前一小段时间内就被大流量消耗完,则将导致该时间段内剩余的时间都拒绝服务。该现象为:“突刺消耗”。 通过限制系统的并发调用程度来限流 通过并发限制来限流,我们通过严格限制某服务的并发访问程度,其实也就限制了该服务单位时间段内的访问量, 比如限制服务的并发访问数是100,而服务处理的平均耗时是10毫秒,该服务每秒能提供( 1000 / 10 ) * 100 = 10

高并发系统之限流特技

大憨熊 提交于 2019-11-26 18:49:35
在开发高并发系统时有三把利器用来保护系统:缓存、降级和限流。缓存的目的是提升系统访问速度和增大系统能处理的容量,可谓是抗高并发流量的银弹;而降级是当服务出问题或者影响到核心流程的性能则需要暂时屏蔽掉,待高峰或者问题解决后再打开;而有些场景并不能用缓存和降级来解决,比如稀缺资源(秒杀、抢购)、写服务(如评论、下单)、频繁的复杂查询(评论的最后几页),因此需有一种手段来限制这些场景的并发/请求量,即限流。 限流的目的是通过对并发访问/请求进行限速或者一个时间窗口内的的请求进行限速来保护系统,一旦达到限制速率则可以拒绝服务(定向到错误页或告知资源没有了)、排队或等待(比如秒杀、评论、下单)、降级(返回兜底数据或默认数据,如商品详情页库存默认有货)。 一般开发高并发系统常见的限流有:限制总并发数(比如数据库连接池、线程池)、限制瞬时并发数(如nginx的limit_conn模块,用来限制瞬时并发连接数)、限制时间窗口内的平均速率(如Guava的RateLimiter、nginx的limit_req模块,限制每秒的平均速率);其他还有如限制远程接口调用速率、限制MQ的消费速率。另外还可以根据网络连接数、网络流量、CPU或内存负载等来限流。 先有缓存这个银弹,后有限流来应对618、双十一高并发流量,在处理高并发问题上可以说是如虎添翼,不用担心瞬间流量导致系统挂掉或雪崩

统一流控服务开源-2:基于.Net Core的流控服务

拜拜、爱过 提交于 2019-11-26 18:11:30
先前有一篇博文,梳理了流控服务的场景、业界做法和常用算法 统一流控服务开源-1:场景&业界做法&算法篇 最近完成了流控服务的开发,并在生产系统进行了大半年的验证,稳定可靠。今天整理一下核心设计和实现思路,开源到Github上,分享给大家 https://github.com/zhouguoqing/FlowControl 一、令牌桶算法实现 先回顾一下令牌桶算法示意图 随着时间流逝,系统会按恒定1/QPS时间间隔(如果QPS=100,则间隔是10ms) 往桶里加入Token(想象和漏洞漏水相反,有个水龙头在不断的加水), 如果桶已经满了就不再加了. 新请求来临时, 会各自拿走一个Token,如果没有Token可拿了就阻塞或者拒绝服务. 令牌添加速度支持动态变化,实时控制处理的速率. 令牌桶有两个关键的属性: 令牌桶容量(大小)和时间间隔, 有两个关键操作, 从令牌桶中取Token;令牌桶定时的Reset重置。 我们看TokenBucket类: using System; namespace CZ.FlowControl.Service { using CZ.FlowControl.Spi; /// <summary> /// 令牌桶 /// </summary> public abstract class TokenBucket : IThrottleStrategy {