模块 09第 3 学期 · 可靠性与扩展16 海报条目

性能与扩展

登录后可在不同设备间同步进度。在此之前,进度只保存在当前浏览器中。

为什么重要

两种相反的错误都会毁掉产品:做出来的东西 100 个用户就扛不住,或者为根本不存在的一百万用户过度建设。本模块教你先测量,再用最便宜的办法修,并且按既定顺序来。

学习目标

  1. 用压测和性能剖析找瓶颈,而不是靠猜。
  2. 按正确顺序走扩展阶梯。
  3. 正确使用缓存,包括缓存失效。
  4. 理解负载均衡器、反向代理和 API 网关。
  5. 了解 serverless 的限制和冷启动。
  6. 把云成本和 AI 成本当作一等指标来控制。

扩展阶梯(测量过才往上爬)

  1. 修代码: 索引、N+1、分页、payload 大小(03 · 数据基础)。
  2. 缓存: 静态资源走 CDN,公开的动态内容走边缘缓存,昂贵的计算用应用层缓存。
  3. 把工作改成异步(08 · 异步、事件与实时)。
  4. 纵向扩展(47): 更大的数据库或服务器。几乎不花工程时间,能撑的量比大家以为的多。
  5. 横向扩展无状态应用层(46),放在负载均衡器后面,配合自动扩缩容(45)。
  6. 只读副本(29) 应对读多写少的负载(接受复制延迟)。
  7. 分区(31) 大表(例如事件和日志按月分区)。
  8. 分片(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:找到悬崖

  1. 为你的主要用户路径写一个 k6 场景;持续加压,直到错误率超过 1% 或 p95 超出预算。记录下这个“悬崖”。
  2. 剖析并修复排名第一的瓶颈。再重复两次。用图表展示每次修复带来的容量提升。
  3. 为一个公开的动态页面加上 CDN 和边缘缓存,并在更新时正确失效。
  4. 搭一个成本仪表盘:每个活跃用户每月的基础设施和 AI 成本。

完成标准(Definition of Done)

AI 提示词包

  • “根据这份 k6 输出和这些数据库统计,给可能的瓶颈排序,并为每一个提出最便宜的修复办法。”
  • “给这个接口加缓存。包括缓存 key 设计(含租户)、TTL、写入时失效,以及防击穿保护。”