Files
sanbuphy df51f84ab5 docs: 重构 README 附录展示 & 新增多个附录交互组件
README 更新:
- 移除顶部 header.png 横幅图片
- 新增「附录知识库」板块,以 3×3 网格展示 9 大知识领域精选内容
- 附录链接指向部署版网站 (datawhalechina.github.io)
- 阶段表格新增「附录」行,突出 80+ 交互式专题
- 章节标题「新手入门 & PM」简化为「零基础入门」
- News 新增 2026-02-25 附录知识库更新条目

新增交互组件:
- 异步任务队列 (async-task-queues) 演示组件
- 文件存储 (file-storage) 演示组件
- 项目架构 (project-architecture) 演示组件
- 限流与背压 (rate-limiting) 演示组件
- 搜索引擎 (search-engines) 演示组件
- 计算机基础: AppLaunch/BiosUefi/OSBoot 等启动流程演示组件

新增附录文档:
- 前端项目架构 (frontend-project-architecture.md)
- 后端项目架构 (backend-project-architecture.md)

内容优化:
- 算法思维、数据结构、编程语言、调试艺术等多篇附录内容更新
- HTML/CSS 布局、请求旅程等前后端文档完善
- 附录索引页 (index.md) 同步更新
2026-02-25 12:22:49 +08:00

132 lines
6.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 限流与背压控制
::: tip 前言
**双十一零点,几亿用户同时涌入——服务器扛得住吗?** 任何系统都有处理能力的上限。当请求量超过系统承载能力时,如果不加控制,结果就是所有人都用不了。限流和背压就是保护系统不被"压垮"的两道防线。
:::
**这篇文章会带你学什么?**
学完这章后,你将获得:
- **限流必要性**:理解为什么需要主动拒绝部分请求来保护系统
- **限流算法**:掌握令牌桶、漏桶、滑动窗口三种核心算法的原理和差异
- **背压机制**:理解当上游速度超过下游时的处理策略
- **多层限流**:了解从客户端到网关到服务的多层限流架构
- **实战能力**:知道在什么场景下选择什么限流策略
| 章节 | 内容 | 核心概念 |
|-----|------|---------|
| **第 1 章** | 为什么需要限流 | 雪崩效应、服务保护 |
| **第 2 章** | 限流算法 | 令牌桶、漏桶、滑动窗口 |
| **第 3 章** | 背压控制 | 缓冲区、丢弃策略、弹性扩容 |
| **第 4 章** | 多层限流架构 | 客户端、网关、服务端 |
| **第 5 章** | 实战与选型 | Nginx、Redis、Sentinel |
---
## 0. 全景图:为什么要"拒绝"用户?
这听起来很反直觉——我们不是应该服务好每一个用户吗?但现实是:**不拒绝一部分请求,所有请求都会失败**。
想象一个只能坐 100 人的餐厅,突然涌进来 1000 人。如果不限流,结果不是 1000 人都能吃上饭,而是厨房崩溃、服务员瘫痪,1000 人谁都吃不上。正确的做法是在门口排队限流,让 100 人先进去,其余人等候。
::: tip 限流的核心目标
- **保护系统**:防止过载导致服务完全不可用
- **公平分配**:确保已接受的请求能正常处理
- **优雅降级**:被限流的请求收到明确的 429 状态码,而不是超时或 500 错误
:::
---
## 1. 限流算法:三种经典方案
限流的核心问题是:**在单位时间内,最多允许多少个请求通过?** 不同的算法在精确度、突发流量处理、实现复杂度上各有取舍。
<RateLimitAlgorithmDemo />
| 算法 | 原理 | 突发流量 | 精确度 | 实现复杂度 |
|------|------|---------|--------|-----------|
| 令牌桶 | 固定速率放令牌,请求消耗令牌 | 允许(桶中有存量) | 高 | 中 |
| 漏桶 | 请求排队,固定速率处理 | 不允许(完全平滑) | 高 | 中 |
| 滑动窗口 | 统计窗口内请求数 | 部分允许 | 较高 | 低 |
| 固定窗口 | 按时间窗口计数 | 边界处可能突发 | 低 | 最低 |
::: tip 选哪个算法?
- **API 限流**:令牌桶最常用,允许合理的突发流量
- **流量整形**:漏桶适合需要恒定输出速率的场景
- **简单计数**:滑动窗口实现简单,适合大多数 Web 应用
:::
---
## 2. 背压控制:当上游比下游快
限流解决的是"外部请求太多"的问题,而**背压(Backpressure**解决的是"内部组件速度不匹配"的问题。
当生产者产生数据的速度持续超过消费者处理数据的速度时,中间的缓冲区会不断膨胀,最终导致内存溢出或数据丢失。背压机制就是让消费者能够"反向通知"生产者减速。
<BackpressureDemo />
::: tip 背压的四种策略
1. **丢弃(Drop**:缓冲区满时丢弃新数据或旧数据,适合实时性要求高但允许丢失的场景
2. **阻塞(Block**:让生产者暂停,等消费者处理完再继续,适合数据不能丢失的场景
3. **采样(Sample**:只处理部分数据,适合高频数据流
4. **弹性扩容(Scale**:动态增加消费者数量,适合云原生环境
:::
---
## 3. 多层限流架构
生产环境中,限流不是在某一个点做就够了,而是需要**多层防护**,每一层解决不同粒度的问题。
| 层级 | 位置 | 限流粒度 | 工具 |
|------|------|---------|------|
| 客户端 | 前端/App | 按钮防抖、请求节流 | lodash.throttle、debounce |
| CDN/WAF | 边缘节点 | IP 级别、地域级别 | Cloudflare Rate Limiting |
| API 网关 | 入口网关 | 路由级别、用户级别 | Nginx limit_req、Kong |
| 服务端 | 应用内部 | 接口级别、资源级别 | Sentinel、Resilience4j |
| 数据库 | 存储层 | 连接数、QPS | 连接池配置、慢查询熔断 |
::: tip 限流的 HTTP 规范
被限流的请求应该返回 `429 Too Many Requests` 状态码,并在响应头中包含:
- `Retry-After`: 建议客户端多久后重试(秒数或日期)
- `X-RateLimit-Limit`: 限流上限
- `X-RateLimit-Remaining`: 剩余配额
- `X-RateLimit-Reset`: 配额重置时间
:::
---
## 4. 实战选型
| 场景 | 推荐方案 | 说明 |
|------|---------|------|
| Nginx 入口限流 | `limit_req_zone` | 基于漏桶算法,配置简单 |
| 分布式限流 | Redis + Lua 脚本 | 令牌桶或滑动窗口,多实例共享计数 |
| Java 微服务 | Sentinel / Resilience4j | 支持熔断、降级、热点限流 |
| Node.js API | express-rate-limit | 简单易用,支持 Redis 存储 |
| Go 服务 | golang.org/x/time/rate | 标准库令牌桶实现 |
---
## 总结
限流和背压是保护系统稳定性的两道关键防线。限流控制外部流量的涌入速度,背压协调内部组件的处理速度。
回顾本章的关键要点:
1. **限流的必要性**:不拒绝部分请求,所有请求都会失败
2. **三种核心算法**:令牌桶(允许突发)、漏桶(完全平滑)、滑动窗口(简单精确)
3. **背压机制**:丢弃、阻塞、采样、扩容四种策略
4. **多层防护**:从客户端到数据库,每层解决不同粒度的问题
5. **429 规范**:被限流时返回标准状态码和限流头信息
## 延伸阅读
- [Stripe 的限流实践](https://stripe.com/blog/rate-limiters) - 支付系统的限流设计
- [Nginx limit_req 文档](https://nginx.org/en/docs/http/ngx_http_limit_req_module.html) - Nginx 限流模块
- [Alibaba Sentinel](https://sentinelguard.io/) - 面向分布式服务的流量控制组件
- [Resilience4j](https://resilience4j.readme.io/) - Java 轻量级容错库
- [Token Bucket 算法详解](https://en.wikipedia.org/wiki/Token_bucket) - 令牌桶算法的数学原理