模块 09第 3 学期 · 可靠性与扩展16 海报条目
性能与扩展
登录后可在不同设备间同步进度。在此之前,进度只保存在当前浏览器中。
为什么重要
两种相反的错误都会毁掉产品:做出来的东西 100 个用户就扛不住,或者为根本不存在的一百万用户过度建设。本模块教你先测量,再用最便宜的办法修,并且按既定顺序来。
学习目标
- 用压测和性能剖析找瓶颈,而不是靠猜。
- 按正确顺序走扩展阶梯。
- 正确使用缓存,包括缓存失效。
- 理解负载均衡器、反向代理和 API 网关。
- 了解 serverless 的限制和冷启动。
- 把云成本和 AI 成本当作一等指标来控制。
扩展阶梯(测量过才往上爬)
- 修代码: 索引、N+1、分页、payload 大小(03 · 数据基础)。
- 缓存: 静态资源走 CDN,公开的动态内容走边缘缓存,昂贵的计算用应用层缓存。
- 把工作改成异步(08 · 异步、事件与实时)。
- 纵向扩展(47): 更大的数据库或服务器。几乎不花工程时间,能撑的量比大家以为的多。
- 横向扩展无状态应用层(46),放在负载均衡器后面,配合自动扩缩容(45)。
- 只读副本(29) 应对读多写少的负载(接受复制延迟)。
- 分区(31) 大表(例如事件和日志按月分区)。
- 分片(30) 只在单个主库确实扛不住时才做。大多数公司永远用不上。
课程内容
9.1 缓存(2, 48, 49, 50)
- 缓存层次:浏览器(
Cache-Control)、静态资源用 CDN(48)、动态响应的边缘缓存(49)、应用缓存(Redis)、数据库查询缓存。 - 模式:cache-aside(由应用读取并回填)、write-through(写穿)、stale-while-revalidate。
- 缓存失效(50): TTL(简单,最终会更新)、写入时显式清除(基于标签清除)、带版本的 key(
user:42:v7)。 - 绝不要把用户私有数据用共享的 key 放进共享缓存(会泄露数据)。在 key 中加入用户/租户,或标记
Cache-Control: private。 - 防止缓存击穿雪崩:请求合并、给 TTL 加随机抖动、提前刷新。
- LLM 专项:对很长的静态前缀使用服务商的 prompt caching;缓存确定性结果(embedding、分类结果)。
9.2 入口组件(3, 4, 5)
- 反向代理(4): 终结 TLS、压缩、为慢客户端做缓冲、路由(Nginx、Caddy、Cloudflare、平台边缘)。
- 负载均衡器(3): 根据健康检查把流量分发到各实例;分 L4(TCP)和 L7(HTTP)。依赖粘性会话是个坏信号;应用服务器要保持无状态。
- API 网关(5): 为多个服务统一处理认证、配额、限流、路由、API key。当你有多个服务或对外售卖 API 访问时才有用。
9.3 Serverless 的现实(89, 90)
- 限制: 最长执行时间、内存、payload 大小、并发执行数,以及数据库连接压力。要清楚你所用平台的具体数字。
- 冷启动: 闲置后的第一个请求会很慢。缓解办法:更小的 bundle、更轻的运行时(edge)、为延迟敏感路径预置或保留最小实例。
- 长时间运行的 agent 工作不应放在受请求约束的函数里;用持久化任务。
9.4 成本优化(88)
- 把每个活跃用户的成本和每个 AI 任务的成本当作产品指标放在仪表盘上。
- 收益最大的做法:实例规格合适、清理闲置资源、缓存 LLM 结果、把简单任务路由到更小更便宜的模型、批处理、存储生命周期规则、留意出站流量费用。
- 每个服务商都设置硬性消费上限和异常告警。按产品/业务给资源打标签,便于成本归属。
9.5 压测方法
定义场景(真实的用户路径、思考时间、数据量)→ 逐步加压(冒烟、负载、压力、浸泡)→ 观察 p95/p99、错误率、饱和度(CPU、内存、数据库连接、队列深度)→ 找出第一个崩掉的环节 → 修复 → 重复。
实验 9:找到悬崖
- 为你的主要用户路径写一个 k6 场景;持续加压,直到错误率超过 1% 或 p95 超出预算。记录下这个“悬崖”。
- 剖析并修复排名第一的瓶颈。再重复两次。用图表展示每次修复带来的容量提升。
- 为一个公开的动态页面加上 CDN 和边缘缓存,并在更新时正确失效。
- 搭一个成本仪表盘:每个活跃用户每月的基础设施和 AI 成本。
完成标准(Definition of Done)
AI 提示词包
- “根据这份 k6 输出和这些数据库统计,给可能的瓶颈排序,并为每一个提出最便宜的修复办法。”
- “给这个接口加缓存。包括缓存 key 设计(含租户)、TTL、写入时失效,以及防击穿保护。”