FantasticMao 技术笔记
BlogGitHub
  • README
  • C & Unix
    • C
      • 《C 程序设计语言》笔记
      • C 语言中的陷阱
      • CMake 示例
      • GNU make
      • LLVM Clang
      • Nginx 常用模块
      • Vim 常用命令
    • Unix-like
      • 《深入理解计算机系统》笔记
      • 《UNIX 环境高级编程》笔记 - UNIX 基础知识
      • 《UNIX 环境高级编程》笔记 - 文件 IO
      • 《UNIX 环境高级编程》笔记 - 标准 IO 库
      • 《鳥哥的 Linux 私房菜》笔记 - 目录配置
      • 《鳥哥的 Linux 私房菜》笔记 - 认识与学习 bash
      • 《鳥哥的 Linux 私房菜》笔记 - 任务管理
      • OpenWrt 中的陷阱
      • iptables 工作机制
  • Go
    • 《A Tour of Go》笔记
    • Go vs C vsJava
    • Go 常用命令
    • Go 语言中的陷阱
  • Java
    • JDK
      • 《Java 并发编程实战》笔记 - 线程池的使用
      • 设计模式概览
      • 集合概览
      • HashMap 内部算法
      • ThreadLocal 工作机制
      • Java Agent
    • JVM
      • 《深入理解 Java 虚拟机》笔记 - Java 内存模型与线程
      • JVM 运行时数据区
      • 类加载机制
      • 垃圾回收算法
      • 引用类型
      • 垃圾收集算法
      • 垃圾收集器
    • Spring
      • Spring IoC 容器扩展点
      • Spring Transaction 声明式事务管理
      • Spring Web MVC DispatcherServlet 工作机制
      • Spring Security Servlet 实现原理
    • 其它
      • 《Netty - One Framework to rule them all》演讲笔记
      • Hystrix 设计与实现
  • JavaScript
    • 《写给大家看的设计书》笔记 - 设计原则
    • 《JavaScript 权威指南》笔记 - jQuery 类库
  • 数据库
    • ElasticSearch
      • ElasticSearch 概览
    • HBase
      • HBase 数据模型
    • Prometheus
      • Prometheus 概览
      • Prometheus 数据模型和指标类型
      • Prometheus 查询语法
      • Prometheus 存储原理
      • Prometheus vs InfluxDB
    • Redis
      • 《Redis 设计与实现》笔记 - 简单动态字符串
      • 《Redis 设计与实现》笔记 - 链表
      • 《Redis 设计与实现》笔记 - 字典
      • 《Redis 设计与实现》笔记 - 跳跃表
      • 《Redis 设计与实现》笔记 - 整数集合
      • 《Redis 设计与实现》笔记 - 压缩列表
      • 《Redis 设计与实现》笔记 - 对象
      • Redis 内存回收策略
      • Redis 实现分布式锁
      • Redis 持久化机制
      • Redis 数据分片方案
      • 使用缓存的常见问题
    • MySQL
      • 《高性能 MySQL》笔记 - Schema 与数据类型优化
      • 《高性能 MySQL》笔记 - 创建高性能的索引
      • 《MySQL Reference Manual》笔记 - InnoDB 和 ACID 模型
      • 《MySQL Reference Manual》笔记 - InnoDB 多版本
      • 《MySQL Reference Manual》笔记 - InnoDB 锁
      • 《MySQL Reference Manual》笔记 - InnoDB 事务模型
      • B-Tree 简述
      • 理解查询执行计划
  • 中间件
    • gRPC
      • gRPC 负载均衡
    • ZooKeeper
      • ZooKeeper 数据模型
    • 消息队列
      • 消息积压解决策略
      • RocketMQ 架构设计
      • RocketMQ 功能特性
      • RocketMQ 消息存储
  • 分布式系统
    • 《凤凰架构》笔记
    • 系统设计思路
    • 系统优化思路
    • 分布式事务协议:二阶段提交和三阶段提交
    • 分布式系统的技术栈
    • 分布式系统的弹性设计
    • 单点登录解决方案
    • 容错,高可用和灾备
  • 数据结构和算法
    • 一致性哈希
    • 布隆过滤器
    • 散列表
  • 网络协议
    • 诊断工具
    • TCP 协议
      • TCP 报文结构
      • TCP 连接管理
由 GitBook 提供支持
在本页
  • 熔断
  • 限流
  • 计数器
  • 漏斗算法
  • 令牌桶算法
  • 降级
  1. 分布式系统

分布式系统的弹性设计

熔断

熔断的目的是防止应用不断尝试可能会执行失败的操作,从而使得应用可以继续执行而不用等待异常情况的修复,或者浪费时间来等待长时间的超时操作。当异常已经修复的时候,应用会再次尝试执行操作。

熔断模式类似于容易失败操作的一种代理,它能够记录和统计最近执行失败的次数,然后决定是否继续执行,或者是立即返回错误。

实现熔断模式需要考虑以下三个状态:

  1. 闭合状态:熔断器会定义一个执行操作失败的计数器,在执行操作连续失败或者高频失败时,计数器数值会自增。如果计数器值大于某个阈值,则熔断器会切换到断开状态,同时熔断器会设置一个计时器,在经过一段时间之后会切换到半开状态;

  2. 断开状态:在断开状态下,应用执行操作会立即返回失败,或者可以在当本地缓存中没有数据时返回失败;

  3. 半开状态:在半开状态下,应用会被允许执行一次或者一些操作。如果这些操作执行成功,熔断器则会切换到闭合状态,同时会重置计数器。如果这些操作继续执行失败,熔断器则会重新切换到断开状态,同时会重置计时器。

限流

限流的目的是通过对并发访问进行限速。一般来说,限流的行为如下:

  1. 把多出来的请求拒绝掉;

  2. 关闭或者降级后端服务;

  3. 把有限资源分配给重要用户;

  4. 使用队列来削去请求高峰;

  5. 通过自动化运维的方式,实现服务的自动化伸缩。

限流的经典实现方式有基于计数器、漏斗算法、令牌桶算法。

计数器

使用计数器来实现限流的算法如下:

  1. 准备执行一个请求时,计数器加一;

  2. 执行完毕一个请求时,计数器减一;

  3. 当计数器值大于某个阈值时,开始限流。

在基于计数器的限流算法中,请求是以「次数」而不是以「频率」来被限制。

漏斗算法

漏斗算法的具体步骤如下:

  1. 用一个队列(在漏斗中接水)来堆积请求;

  2. Processor(从漏斗中出水)从队列中消费请求;

  3. 如果队列满了,则开始限流。

         +-----------+ accept  +-----------+
-------->| | | | | | |-------->| Processor |
         +-----------+         +-----------+
               |
               | rejected
               v
            Discard

在漏斗算法中,请求是以 Processor 最大消费能力的频率来执行的。

令牌桶算法

令牌桶算法的具体步骤如下:

  1. 以恒定的速率产生 token,放入至一个集合(承担令牌桶角色)中;

  2. 准备执行一个请求时,从集合中获取一个 token;

  3. 当集合中没有 token 时,则开始限流。

    +-----------+  add token
    | | | | | | |<-----------
    +-----------+
          ^
get token |
          | accept
          |        +-----------+
----------+------->| Processor |
          |        +-----------+
          | rejected
          v
       Discard

在令牌桶算法中,当令牌桶中有堆积的 token 时,请求可以被允许高频率地执行。

降级

降级的本质是为了解决在资源不足时,系统访问量过大的问题。当资源和访问量出现矛盾时,在资源有限的情况下,为了能够扛住大量的请求,而对系统进行降级操作。

一般来说,系统降级的策略有:

  1. 降低系统对一致性的要求;

  2. 完全停止次要功能,或者限制次要功能流量;

  3. 简化功能,例如只返回页面或者接口的部分信息。

一般来说,控制降级的形式是:

  1. 主动推送:开启系统配置;

  2. 由上游系统驱动:对外 API 的参数。

最后更新于1年前