分布式系统架构5:限流设计模式

这是小卷对分布式系统架构学习的第5篇文章,今天来学习限流器和限流设计模式

1.为什么要限流?

任何一个系统的运算、存储、网络资源都不是无限的,当系统资源不足以支撑外部超过预期的突发流量时,就应该要有取舍,建立面对超额流量自我保护的机制,而这个机制就是微服务中常说的“限流”

2.四种限流设计模式

说到限流,大家直接的想法就是Sentinel,但是Sentinel限流的原理可能很多人没去深入理解,或者限流到底是怎么做的?具体如何进行限流,业界内也有一些常见设计模式。

2.1流量计数器模式

流量计数器是一种最简单的限流方式,通过记录固定时间窗口内的请求次数来判断是否达到限流阈值。如果请求次数超过限制值,则拒绝后续请求。

实现方式:

  • 将时间划分为固定的时间窗口(如 1 秒、1 分钟)。

  • 每个窗口维护一个计数器,记录当前时间窗口内的请求次数。

  • 如果计数器值超过限流阈值,直接拒绝请求;否则增加计数器。

固定窗口边界问题:

  • 在窗口边界的两端,可能存在短时间内超量请求的“临界问题

比如场景设定:一秒内的TPS大于80时,就限流。

存在问题:即使每一秒的统计流量都没有超过 80 TPS,也不能说明系统没有遇到过大于 80 TPS 的流量压力。比如说系统在连续2秒内都收到60TPS的请求,但是请求发生的时间分别在第1秒的后0.5秒,以及第2秒的前0.5秒。这样系统实际曾在1秒内发生超过80 TPS的请求。

  • 即使连续若干秒统计流量超过阈值,也不能说明流量压力一定超过系统承受能力

假设 10 秒的时间片段中,前 3 秒的 TPS 平均值到了 100,而后 7 秒的平均值是 30 左右,此时系统是否能够处理完这些请求而不产生超时失败?答案是可以的

存在缺陷:造成上面2个问题得原因是流量计数器模式是对时间点进行离散的统计

2.2滑动窗口模式

概念:时间轴上,一个固定大小的窗口随时间平滑滚动。任何时刻,静态地通过窗口内观察到的信息,都等价于一段长度与窗口大小相等的信息。主要是通过记录多个较小时间窗口(子窗口)的请求次数,实现更精细化的限流控制

假设:准备观察的时间片段为 10 秒,以 1 秒作为统计精度,那可以得到一个长度为 10 的数组。设定限流阈值是最近 10 秒内收到的请求不超过 500 个,那么就需要统计10个子数组的请求总数,是否超过阈值。

限流设计模式1.png

优点

  • 解决了固定窗口边界问题

缺点

  • 只适用于否决式限流,超过阈值的流量就必须失败

2.3漏桶模式

漏桶可以简单的理解:小学水池应用题,一个水池,每秒以 X 升速度注水,同时又以 Y 升速度出水,问水池啥时候装满。

概念:将请求视为流入漏桶的水,漏桶以固定速率“漏水”。当请求流量超过漏桶的处理能力时,多余的请求会被丢弃或排队。其核心思想是平滑请求流量

实现方式

  1. 维护一个队列(或计数器),用来模拟漏桶。

  2. 新请求到来时,将请求放入桶中。

  3. 按固定速率处理桶中的请求。

  4. 如果桶已满,则拒绝新请求。

缺点:

  • 比较难确定桶的大小和水流出的速度

2.4令牌桶算法

和漏桶一样是基于缓冲区的限流算法,简单理解就是去银行办事时在排队机号取号的场景。

概念:通过固定速率向桶中添加令牌,请求到来时需要先消耗令牌才能被处理。如果桶中没有足够的令牌,请求会被拒绝。与漏桶算法不同,令牌桶允许一定的突发流量

实现方式

  1. 维护一个桶,桶中存储令牌。
  2. 按固定速率(比如限流是1秒100次请求,那么间隔10ms时间放入令牌)向桶中添加令牌,直到桶满为止。
  3. 请求到来时从桶中取出令牌,如果没有令牌就马上失败或者进入降级逻辑。

实际开发的时候,不需要专门做放令牌到桶里这件事,只需要在获取令牌前,比较一下时间戳与当前时间,就能算出需要放入多少令牌,下面是示例代码:

private long lastTime = System.currentTimeMillis();
private int tokens = 0; // 当前令牌数
private static final int LIMIT = 100; // 桶容量
private static final int REFILL_RATE = 10; // 令牌添加速率(令牌/秒)

public synchronized boolean tryAcquire() {
    long now = System.currentTimeMillis();
    // 添加令牌
    tokens = Math.min(LIMIT, tokens + (int) ((now - lastTime) / 1000) * REFILL_RATE);
    lastTime = now;

    if (tokens > 0) {
        tokens--;
        return true;
    }
    return false;
}

3.分布式限流

上面介绍的4种限流算法都只适用于单机限流,或者把系统当做整体来限流。实际应用中仍然需要精细的每个服务的限流。

概念:过将限流逻辑分散到多个节点,同时使用一致性算法保证全局限流的一致性。它结合了本地限流和集中式限流的优点。

实现方式

  • 基于 Redis + Lua 脚本
    • 使用 Redis 脚本实现分布式限流,在 Redis 中存储全局的请求计数器
  • 基于一致性算法
    • 使用分布式一致性算法(如 Raft、Paxos)维护全局流量状态
  • 分布式网关
    • 通过 API 网关(如 Kong、Nginx、Spring Cloud Gateway)实现流量的统一调度和限流。

缺点

  • 实现复杂度高,且网络通信和一致性操作带来额外延迟。当流量大时,限流本身会降低系统处理能力

总结

今天学习了4种限流设计模式:流量计数器模式、滑动窗口模式、漏桶模式、令牌桶模式,后面2种都是基于缓冲区的限流算法。简单了解了下分布式限流的概念。限流本身是有代价的,实际开发中需要权衡方案的代价和收益。后续有时间补充Sentinel的限流原理和其中用了哪些设计模式。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,258评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,335评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,225评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,126评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,140评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,098评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,018评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,857评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,298评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,518评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,678评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,400评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,993评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,638评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,801评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,661评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,558评论 2 352

推荐阅读更多精彩内容