CloudNativeEra
  • Introduction
  • 名词解释
  • Computer Science
    • Computer Organization
      • CPU
      • 二进制、电路、加法器、乘法器
      • 编译、链接、装载
      • 存储器
      • IO
    • Operating System
      • 操作系统基础知识
      • 系统初始化
      • 进程管理
      • Everything about Memory
      • 文件系统
      • 并行编程
      • Linux
        • CPU
        • IO 多路复用
        • DMA IO and Linux Zero Copy
    • Computer Network
      • 网络相关命令
      • 评估系统的网络性能
      • 网络抓包
      • Linux 最多支撑的 TCP 连接
      • 网络虚拟化
      • DHCP 工作原理
    • Data Structure and Algorithm
      • 题目列表
      • Summarize
        • 方法总结
        • 二分思想
        • 树的演化
        • 算法思想总结
      • Data Structure
        • Data Struct - Array
        • Tree
        • Heap
        • Hash
        • 字符串
      • Algorithm
        • Sorting Algorithm
        • 查找
        • 贪心算法
        • 动态规划
        • 位运算
      • Practice Topics
        • Data Struct in SDK
        • Topic - Tree
        • Topic - Graph
        • Topic - 滑动窗口
        • 剑指 Offer 题解
    • 并发编程
      • 并发模式
      • 并发模型
  • 系统设计
    • 软件设计
      • 软件架构
      • 编程范式
      • 系统设计题
      • 设计原则
      • 计算机程序的构造和解释 SICP
    • 领域驱动设计
      • 应用:在线请假考勤管理
      • 应用: library
    • 微服务与云原生
      • Designing and deploying microservices
      • 容器技术
      • Docker
      • Etcd
      • Kubernetes
        • Kubernetes - Mapping External Services
      • Istio
      • 监控
    • 分布式系统
      • 分布式理论
      • 分布式事务
    • 后端存储设计
      • 缓存设计
      • 数据库架构设计
    • CI/CD
    • 设计最佳实践
    • 测试
    • 安全
    • 综合
      • 开发实践
      • 分布式锁
      • 分布式计数服务
      • 弹幕系统设计
      • 消息队列设计
      • 分布式ID生成算法
      • 限流设计
      • 网关设计
      • 通用的幂等设计
      • 分布式任务调度
        • Timer
        • ScheduledExecutorService
        • Spring Task
        • Quartz
      • 交易系统
      • 权限设计
  • 编程语言
    • 编程语言
    • C & C++
    • Java
      • JVM
        • JVM Bytecode
      • Java 核心技术
      • Java 8 新特性
      • Java 集合框架
      • Java NIO
      • 并发编程
        • 线程生命周期与线程中断
        • 三个线程交替打印
        • 两个线程交替打印奇偶
        • 优雅终止线程
        • 等待通知机制
        • 万能钥匙:管程
        • 限流器
        • 无锁方案 CAS
    • Java 源码阅读
      • Unsafe
      • 异步计算 Future
      • Java Queue
      • CoalescingRingBuffer 分析
      • Java Collections
        • PriorityQueue 分析
        • HashMap 分析
        • TreeMap
    • Golang
    • Python
  • 框架/组件/类库
    • Guava
      • Guava Cache
      • Guava EventBus
    • RxJava
    • Apache MINA
    • Netty
      • 网络 IO 模型
      • Netty 生产问题
    • Apache Tomcat
    • MyBatis
    • 限流框架
    • Spring Framework
      • Spring Core
      • Spring 事务管理
    • Spring Boot
    • Spring Cloud
      • Feign & OpenFeign
      • Ribbon
      • Eurake
      • Spring Cloud Config
    • FixJ
    • Metrics
    • Vert.x
  • 中间件
    • Redis
      • Redis 基础
        • Redis 数据结构设计与实现
        • Redis 高性能网络模型
      • Redis checklist
      • 应用案例 - Redis 数据结构
      • 应用案例 - Redis 缓存应用
      • 应用案例 - Redis 集群
      • Redis 客户端
      • Redis 生产案例
        • [译] 在 Redis 中存储数亿个简单键值对
    • MySQL
      • MySQL 基础
      • MySQL Index
      • MySQL Transaction
      • MySQL 优化
      • MySQL 内核
      • MySQL Command
      • MySQL Checklist
      • MySQL Analysis Tool
      • 实现 MySQL
    • State Machine
    • 数据库连接池
    • MQ
      • 高性能内存队列 Disruptor
      • Kafka
      • Pulsar
      • RocketMQ
        • Broker 的设计与实现
      • NSQ
  • 实际案例
    • 线上 Case
      • Request Aborted
      • MySQL - Specified key was too long
      • Java 应用 CPU 100% 排查优化
      • 频繁 GC 导致的 Java 服务不响应
      • 导出优化
  • 大数据
    • 流计算
    • Flink
  • 其他
    • 工具
    • 读书
      • 设计数据密集型应用
      • 实现领域驱动设计
      • 精通比特币
      • 提问的智慧
    • 论文
    • 工程博客
    • 阅读源码
    • 面试
      • 如何在最短的时间里对对方有个全面的了解
    • 分享
    • 软技能
    • Todo
  • Blog
    • #算法
      • 查找
      • 位运算
      • 树
    • #架构
      • 1- 通信
    • Design & Dev & Opt
      • High Performance Data structure Design
  • Tiny Project
    • A Simple WeChat-like Instant Messaging Platform
由 GitBook 提供支持
在本页
  • 分析
  • 设计
  • 实现
  • 开源的限流框架
  • 问题思考
  • 参考
  • 如何完成百万 QPS 的限流

这有帮助吗?

  1. 系统设计
  2. 综合

限流设计

设计一个通用的限流框架

分析

对于一个服务来讲,接口请求来自很多不同的系统(后面统称为调用方),比如各种金融产品的后端系统。在系统上线一段时间里,我们遇到了很多问题。比如,因为调用方代码 bug 、不正确地使用服务(比如启动 Job 来调用接口获取数据)、业务上面的突发流量(比如促销活动),导致来自某个调用方的接口请求数突增,过度争用服务的线程资源,而来自其他调用方的接口请求,因此来不及响应而排队等待,导致接口请求的响应时间大幅增加,甚至出现超时。

解决这类问题的基本思路就是使用限流的方式对调用方的调用做限制,以免因为流量的抖增将自身服务压垮,进而导致服务不可用,最终引发雪崩效应;限流的策略应该很灵活,此外,开发一个限流框架应该具备:通用性,可以集成到微服务的治理平台中;我们要善于识别出通用的功能模块,将它抽象成通用的框架、组件、类库等。

分析方法:画线框图、写用户用例、测试驱动开发等。我们可以使用用户用例和测试驱动开发的思想,先思考,用户最终如何使用这个框架,找到一个应用场景,针对这个场景写出第一版的应用程序,这样比较直观,然后我们再花时间去优化。

对于限流框架:

  1. 需要一种设置限流规则的方式,要做到在不修改代码的情况下修改规则,可以使用配置文件的方式定义限流规则,比如 yml 文件

  2. 限流框架的主要功能:接收到请求后,限流框架做判断,是继续处理还是熔断,在落地到代码,我们可以直接提供一个限流入口,也可以使用 AOP 的思想,尽可能对代码做到无侵入,主要逻辑做到切面中

  3. 此外,还要注意框架的易用性(编程接口和使用要非常简单,可以支持不同的限流算法等,框架还要能很方便的和 Spring 等集成)、扩展性和灵活性(可以非常灵活的扩展各种限流算法,同时还要支持不同格式、不同数据源的限流规则配置)、性能(限流框架要尽可能的低延迟、尽可能减少对接口请求的影响)、容错性(限流框架出现问题不能影响正常的接口请求,要快速失败)等

可见,对于限流框架来说,非功能性需求是设计与实现的难点。怎么做到易用、灵活、可扩展、低延迟、高容错,才是开发的重点。

设计

做完分析之后,就可以开始进行系统设计,限流框架作为一个通用框架,在设计上尤其需要花精力去权衡,它的主要复杂度来源是非功能性需求方面的,设计一个合理的、满足易用易扩展灵活低延时高容错的限流框架。

  • 限流规则:不同时间粒度、接口粒度、调用方等

  • 限流算法:支持各种限流算法,如时间窗口、滑动窗口、令牌痛、漏桶等

  • 限流模式:单机限流和分布式限流

  • 集成:易于和 Spring 等集成,要做到与业务代码松耦合、方便集成等

实现

利用设计思想、原则、模式、编码规范、重构技巧等,写出易读、易扩展、易维护、灵活、简洁、可复用、易测试的代码。

优秀的代码是重构出来的,复杂的代码是慢慢堆砌出来的。小步快跑、逐步迭代是比较好的开发模式。

V1 版本

主要功能:支持HTTP协议接口的限流;支持本地文件配置,文件格式为yml;支持滑动窗口的限流算法;支持单机限流

非功能性:要预留好扩展点

开源的限流框架

问题思考

  • 如何选择合理的时间粒度和限流值?如何验证设置的合理性?

  • 开发一个MVP版本后,进行 code review,可以从哪些方面找出问题并改进?

  • 重构代码,支持自定义的限流规则配置文件名和路径?可以借鉴 Spring 的设计思路

  • 如何做到和 Spring 的快速方便集成?

参考

如何完成百万 QPS 的限流

常见的两个基础限流算法是漏斗算法和令牌算法,这两个算法大同小异。漏斗算法可以理解为每一个请求都会消耗一定的空气,而漏斗里的空气是有限的,通过漏水的方式获得空气的速率也是有限的。令牌算法可以理解为每一个请求都会消耗一个令牌,而令牌桶生产令牌的能力是有限的,存放令牌的桶容量也是有限的。

生产环境的请求QPS在曲线上看是平滑的,因为大多数统计系统都采用了平滑算法(一段时间内的均值),但是在实际的运行过程中会有一定的随机性和波动性,会有突发的一些离群点,这个一般被称之为突发流量。

限流算法需要考虑这种突发流量,它应该可以短期内容忍,容忍也是有上限的,就是容忍时间必须很短。上面两个算法都具有这个容忍能力,这个容忍就体现在漏斗中空气的积蓄,令牌桶中令牌的积蓄,积蓄耗光就达到了容忍的上限。

分布式限流我们一般是采用 Redis + Lua,应用在做限流时,需要做一次网络 IO,通常这种方式可以做到几万的 QPS;如果需要提高限流的 QPS,可以考虑将 key 分桶,使用 Redis 集群来扩容,将请求经过 hash 分散到不同的实例上,这样能达到 10 w+ 的 QPS 能力,如果是百万的 QPS 怎么设计呢?

将整体的 QPS 按照权重分散到多个子节点,每个子节点在内存中进行单机限流。如果每个节点都是对等的,那么每个子节点就可以分得 1/n 的 QPS。

它的优点在于分散了限流压力,将 IO 操作变成纯内存计算,这样就可以很轻松地应对超高的 QPS 限流。但是这也增加了系统的复杂度,需要有一个集中的配置中心来向每个子节点来分发 QPS 阈值,需要每个应用子节点向这个配置中心进行注册,需要有一个配置管理后台来对系统的 QPS 分配进行管理。

如果没有一个完善易用成熟的开源软件的话,这样的一个控制中心服务和SDK往往需要一个小型团队来完成。这对于中小型企业来说往往是承受不起的。

上一页分布式ID生成算法下一页网关设计

最后更新于4年前

这有帮助吗?

参考 章节,主要分析了目前比较流行的三个开源限流框架:Sentinel、resilience4j、hystrix.

限流框架
分布式的令牌桶算法实现
RedissionRateLimiter.java
Guava RateLimiter
Hystrix 技术解析