文档章节

限流

學習是一种信仰
 學習是一种信仰
发布于 2017/05/28 20:50
字数 2151
阅读 40
收藏 1

在开发高并发系统时,有很多手段可以用来保护系统,如:缓存、降级和限流等。在某些场景下并不能用缓存和降级来解决,比如稀缺资源(秒杀、抢购)、写服务(如评论、下单)、频繁的复杂查询(评论的最后几页)等,因此需要有一种手段来限制这些场景下的并发/请求量,这种手段就是限流。

限流的目的是通过对并发访问、请求进行限流或者一个时间窗口内的请求进行限速来保护系统,一旦达到限制速率则可以拒绝服务(定向到错误页或告知资源没有了)、排队或者等待(比如秒杀、评论、下单)、降级(返回兜底数据或者默认值,如商品详情默认有货)。在压测时,我们能找到每个系统的处理峰值,然后通过设定峰值阀值,来防止当系统过载时,通过拒绝过载的请求阿里保障系统可用。另外,也应根据系统的吞吐量,响应时间、可用率来动态调整限流阀值。

常见的限流

1、限制总并发数(比如数据库连接池)

2、限制瞬时并发数(如Nginx的limit_conn模块,用来限制瞬时并发连接数)

3、限制时间窗口内的平均速率(如Guava的RateLimiter、Nginx的limit_req模块),用来限制每秒的平均速率

4、限制远程接口调用速率、限制MQ的消费速率等

限流算法

常见的限流算法有:令牌桶、漏桶。计数器也可以用来进行粗暴的限流。

令牌桶算法

在 Wikipedia 上,令牌桶算法是这么描述的:

  1. 每秒会有 r 个令牌放入桶中,或者说,每过 1/r 秒桶中增加一个令牌
  2. 桶中最多存放 b 个令牌,如果桶满了,新放入的令牌会被丢弃
  3. 当一个 n 字节的数据包到达时,消耗 n 个令牌,然后发送该数据包
  4. 如果桶中可用令牌小于 n,则该数据包将被缓存或丢弃

漏桶算法

  • 一个固定容量的漏桶,按照常量固定速率流出水滴;

  • 如果桶是空的,则不需流出水滴;

  • 可以以任意速率流入水滴到漏桶;

  • 如果流入水滴超出了桶的容量,则流入的水滴溢出了(被丢弃),而漏桶容量是不变的。

令牌桶限制的是平均流入速率(允许突发请求,只要有令牌就可以处理,允许一定程度的突发流量)

漏桶限制的是常量流出速率,从而可以平滑突发流入速率

令牌桶允许一定程度的突发,而漏桶主要目的是平滑流入速率。

计数器限流

它是限流算法中最简单最容易的一种算法,比如我们要求某一个接口,1分钟内的请求不能超过10次,我们可以在开始时设置一个计数器,

每次请求,该计数器+1;如果该计数器的值大于10并且与第一次请求的时间间隔在1分钟内,那么说明请求过多;如果该请求与第一次请求的时间间隔大于1分钟,并且该计数器的值还在限流范围内,那么重置该计数器。具体代码如下:

public class CounterDemo {
    public long timeStamp = getNowTime();
    public int reqCount = 0;
    public final int limit = 100; // 时间窗口内最大请求数
    public final long interval = 1000; // 时间窗口ms
    public boolean grant() {
        long now = getNowTime();
        if (now < timeStamp + interval) {
            // 在时间窗口内
            reqCount++;
            // 判断当前时间窗口内是否超过最大请求控制数
            return reqCount <= limit;
        }
        else {
            timeStamp = now;
            // 超时后重置
            reqCount = 1;
            return true;
        }
    }
}

不过,以上代码有致命问题,当遇到恶意请求,在0:59时,瞬间请求100次,并且在1:00请求100次,那么这个用户在1秒内请求了200次,用户可以在重置节点突发请求,而瞬间超过我们设置的速率限制,用户可能通过算法漏洞击垮我们的应用。如下图,如何解决呢,看下边的滑动窗口算法。

滑动窗口

在上图中,整个红色矩形框是一个时间窗口,在我们的例子中,一个时间窗口就是1分钟,然后我们将时间窗口进行划分,如上图我们把滑动窗口划分为6格,所以每一格代表10秒,每超过10秒,我们的时间窗口就会向右滑动一格,每一格都有自己独立的计数器,例如:一个请求在0:35到达,那么0:30到0:39的计数器会+1,那么滑动窗口是怎么解决临界点的问题呢?如上图,0:59到达的100个请求会在灰色区域格子中,而1:00到达的请求会在红色格子中,窗口会向右滑动一格,那么此时间窗口内的总请求数共200个,超过了限定的100,所以此时能够检测出来触发了限流。回头看看计数器算法,会发现,其实计数器算法就是窗口滑动算法,只不过计数器算法没有对时间窗口进行划分,所以是一格。由此可见,当滑动窗口的格子划分越多,限流的统计就会越精确。滑动窗口算法实现

应用级限流

限制总并发/连接/请求数

应用系统一定会存在极限并发/请求数,即总有一个TPS/QPS阀值。

Tomcat,Connector配置参数:acceptCount(超出排队大小,则拒绝连接),maxConnections(瞬时最大连接数,超出的会排队等待),maxThreads(处理请求的最大线程数)

MySQL的max_connections、Redis的tcp-backlog有类似限制连接数的参数配置。

限制总资源数

稀缺资源如:数据库连接、线程可以使用池化技术限制总资源数,如连接池、线程池。

限制某个接口的总并发/请求数

某些接口可能会有突发访问情况,为避免访问量太大造成崩溃,如抢购业务,那么此时就需要限制这个接口的总并发/请求数了,超出限额,要么让用户排队,要么告诉用户没货了,这对用户来说是可以接受的。因为粒度比较细,可以为每个接口都设置相应的阀值。可以使用Java中的AtomicLong或者Semaphore进行限流。

限制某个接口的时间窗请求数

限制一个时间窗口内的请求数

平滑限流某个接口的请求数

某些场景下需要对突发请求进行整形,整形为平均速率请求处理,这个时候有两种算法满足我们的场景,令牌桶和漏桶算法。Guava框架RateLimiter类提供了令牌桶算法实现,可以直接拿来使用,可用于平滑突发限流(SmoothBursty)和平滑预热限流(SmoothWarmingUp)实现。

SmoothBursty允许一定程度的突发,会有人担心如果允许这种突发,假设突然来了很大的流量,那么系统很可能扛不住这种突发。因此,需要一种平滑速率的限流工具,从而在系统启动后慢慢趋于平均固定速率(即刚开始速率小一些,然后慢慢趋于我们设置的固定速率),SmoothWarmingUp实现了这种需求,其可以认为是漏桶算法,但是在某些特殊场景下又不太一样。参数warmupPeriod表示从冷启动速率过渡到平均速率的时间间隔。

分布式限流

将限流服务做成原子化,而解决方案可以使用Redis+Lua或者Nginx+Lua技术进行实现,通过这两种技术可以实现高并发和高性能。

接入层限流

接入层通常指请求流量的入口,该层的主要目的有:负载均衡、非法请求过滤、请求聚合、缓存、降级、限流等等。对于Nginx接入层限流可以使用Nginx自带的两个模块:连接数限流模块和漏桶算法实现的请求限流模块。

——————————————————————————————————

参考:《亿级流量网站架构核心技术——跟开涛学搭建高可用高并发系统》

 

本文转载自:http://blog.csdn.net/ljj821061514/article/details/52512943

上一篇: JVM必知必会
下一篇: DNS负载均衡
學習是一种信仰
粉丝 4
博文 64
码字总数 88909
作品 0
杭州
私信 提问
Spring Cloud Gateway 限流操作

开发高并发系统时有三把利器用来保护系统:缓存、降级和限流,API网关作为所有请求的入口,请求量大,我们可以通过对并发访问的请求进行限速来保护系统的可用性。 常用的限流算法比如有令牌桶...

尹吉欢
2018/07/23
0
0
简易RPC框架-客户端限流配置

关键资源 关键资源总是有限的,也就意味着处理能力也有限,所以当面对大量业务时,为了保障自己能够有序的提供服务最经济的做法就是限制同一时间处理的事务数。比如银行的工作人员,一个工作...

xiaomin0322
2018/03/30
0
0
纳秒级分布式无锁限流插件 - Current-Limiting

1.简介 Current-Limiting 是一个基于令牌桶算法和漏桶算法实现的纳秒级分布式无锁限流插件,完美嵌入SpringBoot、SpringCloud应用,支持接口限流、方法限流、系统限流、IP限流、用户限流等规...

像风一样i
04/24
0
0
【.NET Core项目实战-统一认证平台】第七章 网关篇-自定义客户端限流

【.NET Core项目实战-统一认证平台】开篇及目录索引 上篇文章我介绍了如何在网关上增加自定义客户端授权功能,从设计到编码实现,一步一步详细讲解,相信大家也掌握了自定义中间件的开发技巧...

金焰的世界
2018/11/20
0
0
Spring Cloud 入门教程9、服务限流/API限流(Zuul+RateLimiter)

一、前言 1、什么是RateLimiter、Spring Cloud Zuul RateLimiter? RateLimiter是Google开源的实现了令牌桶算法的限流工具(速率限制器)。http://ifeve.com/guava-ratelimiter/ Spring Clou...

吴伟祥
02/19
0
0

没有更多内容

加载失败,请刷新页面

加载更多

10分钟详解Spring全家桶7大知识点

点关注,不迷路;持续更新Java架构相关技术及资讯热文!!! Spring框架自诞生以来一直备受开发者青睐,有人亲切的称之为:Spring 全家桶。它包括SpringMVC、SpringBoot、Spring Cloud、Spr...

我最喜欢三大框架
26分钟前
5
0
注册服务&开机自启动

列出所有服务[root@localhost ~]# systemctl list-unit-files[root@localhost ~]# systemctl status mysqld[root@localhost ~]# systemctl stop mysqld[root@localhost ~]# ......

jxlgzwh
29分钟前
1
0
解决jdk8 stream tomap方法报错:java.lang.IllegalStateException: Duplicate key异常解决(key重复)

List<User> userList = User.ME.loadList(users); if (CollectionUtils.isNotEmpty(userList)) { Map<Long, User> userMap = userList.stream().filter(Objects::nonN......

冰峰雪座
38分钟前
1
0
jdk中的一些命令

jdk中的一些命令 jps jstack jmap jstat jhat jinfo javap http://www.importnew.com/18398.html

晨猫
39分钟前
1
0
Bystack的高TPS共识算法

共识算法是分布式系统保证节点数据状态一致性的方法,在区块链的共识算法分POW(工作量证明)和POS(权益证明)两大类。第一类POW模式是在公链项目中运用的最广泛应用的共识算法,比特币长达10年...

比原链Bytom
39分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部