概要

在大数据量高并发访问时,经常会出现服务或接口面对暴涨的请求而不可用的情况,甚至引发连锁反映导致整个系统崩溃。此时你需要使用的技术手段之一就是限流,当请求达到一定的并发数或速率,就进行等待、排队、降级、拒绝服务等。在限流时,常见的两种算法是漏桶和令牌桶算法算法。

限流算法

令牌桶(Token Bucket)、漏桶(leaky bucket)和计数器算法是最常用的三种限流的算法。

1. 令牌桶算法

令牌桶算法的原理是系统会以一个恒定的速度往桶里放入令牌,而如果请求需要被处理,则需要先从桶里获取一个令牌,当桶里没有令牌可取时,则拒绝服务。 当桶满时,新添加的令牌被丢弃或拒绝。

令牌桶算法示例

1

2

3

4

5

6

7

8

9

10

11

12

13

14

public class RateLimiterDemo {

    private static RateLimiter limiter = RateLimiter.create(5);

    public static void exec() {

        limiter.acquire(1);

        try {

            // 处理核心逻辑

            TimeUnit.SECONDS.sleep(1);

            System.out.println("--" + System.currentTimeMillis() / 1000);

        catch (InterruptedException e) {

            e.printStackTrace();

        }

    }

}

Guava RateLimiter 提供了令牌桶算法可用于平滑突发限流策略。
该示例为每秒中产生5个令牌,每200毫秒会产生一个令牌。
limiter.acquire() 表示消费一个令牌。当桶中有足够的令牌时,则直接返回0,否则阻塞,直到有可用的令牌数才返回,返回的值为阻塞的时间。

2. 漏桶算法

它的主要目的是控制数据注入到网络的速率,平滑网络上的突发流量,数据可以以任意速度流入到漏桶中。漏桶算法提供了一种机制,通过它,突发流量可以被整形以便为网络提供一个稳定的流量。 漏桶可以看作是一个带有常量服务时间的单服务器队列,如果漏桶为空,则不需要流出水滴,如果漏桶(包缓存)溢出,那么水滴会被溢出丢弃。

3. 计数器限流算法

计数器限流算法也是比较常用的,主要用来限制总并发数,比如数据库连接池大小、线程池大小、程序访问并发数等都是使用计数器算法。

使用计数器限流示例1

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

public class CountRateLimiterDemo1 {

    private static AtomicInteger count = new AtomicInteger(0);

    public static void exec() {

        if (count.get() >= 5) {

            System.out.println("请求用户过多,请稍后在试!"+System.currentTimeMillis()/1000);

        else {

            count.incrementAndGet();

            try {

                //处理核心逻辑

                TimeUnit.SECONDS.sleep(1);

                System.out.println("--"+System.currentTimeMillis()/1000);

            catch (InterruptedException e) {

                e.printStackTrace();

            finally {

                count.decrementAndGet();

            }

        }

    }

}

使用AomicInteger来进行统计当前正在并发执行的次数,如果超过域值就简单粗暴的直接响应给用户,说明系统繁忙,请稍后再试或其它跟业务相关的信息。

弊端:使用 AomicInteger 简单粗暴超过域值就拒绝请求,可能只是瞬时的请求量高,也会拒绝请求。

使用计数器限流示例2

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

public class CountRateLimiterDemo2 {

    private static Semaphore semphore = new Semaphore(5);

    public static void exec() {

        if(semphore.getQueueLength()>100){

            System.out.println("当前等待排队的任务数大于100,请稍候再试...");

        }

        try {

            semphore.acquire();

            // 处理核心逻辑

            TimeUnit.SECONDS.sleep(1);

            System.out.println("--" + System.currentTimeMillis() / 1000);

        catch (InterruptedException e) {

            e.printStackTrace();

        finally {

            semphore.release();

        }

    }

}

使用Semaphore信号量来控制并发执行的次数,如果超过域值信号量,则进入阻塞队列中排队等待获取信号量进行执行。如果阻塞队列中排队的请求过多超出系统处理能力,则可以在拒绝请求。

相对Atomic优点:如果是瞬时的高并发,可以使请求在阻塞队列中排队,而不是马上拒绝请求,从而达到一个流量削峰的目的。

什么是限流及如何限流相关推荐

  1. 可视化界面 Sentinel 流控卫兵 限流 熔断 系统保护

    Sentinel 流控卫兵 Sentinel分为两个部分: 核心库(Java客户端):客户端调用通用的应用 控制台(Dashboard):基于springboot开发的,打包后可以直接运行,不需要额外 ...

  2. Sentinel 流控(限流)

    流量控制(Flow Control),原理是监控应用流量的QPS或并发线程数等指标,当达到指定阈值时对流量进行控制,避免系统被瞬时的流量高峰冲垮,保障应用高可用性. 通过流控规则来指定允许该资源通过的 ...

  3. 【限流01】限流算法理论篇

    微服务就是将复杂的大应用拆分成小的应用,这样做的好处是各个应用之间独立开发.测试.上线,互不影响.但是服务拆分之后,带来的问题也很多,我们需要保障微服务的正常运行,就需要进行服务治理.常用手段有:鉴权 ...

  4. 高并发解决方案(缓存、降级、限流)之限流笔记

    转载自:jinnianshilongnian 高并发系统时有三把利器用来保护系统:缓存.降级和限流.缓存的目的是提升系统访问速度和增大系统能处理的容量,可谓是抗高并发流量的银弹:而降级是当服务出问题或 ...

  5. Redis(六)——限流算法:滑动时间窗口限流和漏斗限流

    本文主要总结自<redis深度历险> 限流的意义 限流一般是指在一个时间窗口内对某些操作请求的数量进行限制,比如一个论坛限制用户每秒钟只能发一个帖子,每秒钟只能回复5个帖子.限流可以保证系 ...

  6. 【限流02】限流算法实战篇 - 手撸一个单机版Http接口通用限流框架

    本文将从需求的背景.需求分析.框架设计.框架实现几个层面一步一步去实现一个单机版的Http接口通用限流框架. 一.限流框架分析 1.需求背景 微服务系统中,我们开发的接口可能会提供给很多不同的系统去调 ...

  7. java基础48 IO流技术(序列流)

    本文知识点目录: 1.SequenceInputStream序列流的步骤     2.实例     3.附录(音乐的切割与合并) 1.SequenceInputStream序列流的步骤 1.找到目标文 ...

  8. 流API--使用并行流

    这篇博客一起来研究下使用并行流.借组多核处理器并行执行代码可以显著提高性能,但是并行编程可能十分复杂且容易出错,流API提供的好处之一是能够轻松可靠的并行执行一些操作.请求并行处理流,首先要获得一个并 ...

  9. Java IO流之普通文件流和随机读写流区别

    普通文件流和随机读写流区别 普通文件流:http://blog.csdn.net/baidu_37107022/article/details/71056011 FileInputStream和Fil ...

最新文章

  1. 李飞飞团队最新论文:如何对图像中的实体精准“配对”?(附代码论文)
  2. firefox显示nagios
  3. Java 自定义线程池
  4. 你知道到底什么是Unikernel吗
  5. 矩形嵌套(NYOJ-16)
  6. AngularJs学习笔记--html compiler
  7. CUDA计算向量内积的程序(源自CUDA范例编程)
  8. java计算点在圆内外_java – 在O((n s)log n中计算圆交叉点)
  9. java停机保存数据_哦,这就是java的优雅停机?(实现及原理)
  10. matlab的v带优化设计,基于遗传算法及MATLAB的V带传动优化设计
  11. WebStorm常用插件推荐
  12. 矩阵转置,矩阵加,矩阵乘Java
  13. Windows 10连接打印机提示网路“指定的网络名已不再可用”
  14. 管理学定律三:羊群效应与刺猬法则
  15. win10清理_春节过后你的电脑该减肥了 Win10清理C盘瘦身全攻略
  16. python错误提示未定义tn_未找到Python方法,但在类中定义
  17. 哪种程序员最挣钱?平均月薪30.8K,网友说这是掌握世界的技术
  18. python入门指南
  19. 计算机基础练习题(包含答案)
  20. 使用STM32F103CBT6自制ST LINK V2-1多功能烧录器

热门文章

  1. 浏览器兼容性经典问题(一) IE6 下双边距问题
  2. 青春在为谁燃烧 梦想在为谁咆哮
  3. 网站静态化处理—缓存
  4. 你的电脑适合升级 Win11 吗?「GitHub 热点速览 v.21.26」
  5. 迄今为止最接地气的区块链应用,没有之一!
  6. 接口签名中的三位小伙伴signature,nonce,timestamp
  7. Mac打开第三方下载的软件提示已损坏的解决方法
  8. CSS盒子模型及属性
  9. 工控一体机如何选型?一文让您快速了解
  10. 四年上册级计算机教学计划,四年级上册信息技术素材-教学计划 教学进度安排 闽教版(2020年修订版)...