# 分布式系统的弹性设计

## 熔断

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

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

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

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 的参数。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://gitbook.fantasticmao.cn/tech/fen-bu-shi-xi-tong/fen-bu-shi-xi-tong-de-tan-xing-she-ji.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
