@Akintola_steve: https://x.com/Akintola_steve/status/2055620856802357587

X AI KOLs Timeline 工具

摘要

一份实用的蓝图,用于设计能够处理100万并发用户的后端系统,涵盖架构决策如语言选择、负载均衡、数据库分片、多层缓存及弹性模式。

https://t.co/1iIZ3y2IO9
查看原文
查看缓存全文

缓存时间: 2026/05/17 03:28

如何设计一个能支撑100万用户而不崩溃的后端系统

一份面向后端工程师的2026年实用架构蓝图

构建一个为1000用户服务的系统很容易。但构建一个在100万并发用户下仍保持快速、廉价且坚如磐石的系统,却是大多数工程师失败的地方。

本文为你提供一份完整且经实战检验的蓝图。没有空话。只有真正关乎扩展性的架构决策、权衡和模式。

1. 首先明确你的需求

这是大多数工程师跳过的步骤,也是他们六个月后不得不重构一切的原因。

在写任何代码之前,先确定你的非功能性需求:

  • 峰值QPS: 每秒1万到5万次请求

  • P99延迟: 低于200毫秒(目标低于100毫秒)

  • 可用性: 99.99%,即每月最多约4分钟停机时间

  • 一致性模型: 金融数据强一致性,动态消息和时间线最终一致性

  • 成本上限: 提前设定每1000用户的严格美元成本上限

使用扩展立方体从三个维度思考:

  • X轴: 水平复制。运行更多相同的服务器。

  • Y轴: 功能分解。拆分为更小、更专注的服务。

  • Z轴: 数据分区。按用户ID或区域分片。

仅凭这一思维模型即可避免90%的扩展灾难。

2. 选择正确的基础设施

语言与框架:

  • Go或Rust:追求原始性能和内存效率

  • TypeScript(NestJS)或Java/Kotlin(Spring Boot):当团队交付速度比原始吞吐量更重要时

API策略:

  • 面向公众:REST + GraphQL

  • 内部服务间通信:gRPC。类型安全、快速、支持流式传输。

从一个模块化单体应用开始。只有当某个特定服务成为可衡量的、被证实的瓶颈时,才将其拆分为微服务。

过早微服务是扩展性下工程效率的最大杀手。

3. 负载均衡与边缘层

全球用户意味着全球延迟,除非你将基础设施推到边缘。

请求路径如下:

  • 用户(拉各斯 / 伦敦 / 孟买)

  • Cloudflare或Fastly:CDN、DDoS防护、边缘缓存

  • 全球负载均衡器:AWS Global Accelerator或GCP等效产品

  • API网关:限流、WAF、机器人检测

  • 应用服务

在100万用户规模下,边缘层是你的第一道防线。在请求到达应用服务器之前,尽可能多地处理流量。

4. 应用层设计

四条不可妥协的规则:

每个服务必须无状态。 会话存储在Redis或Dragonfly中,绝不在应用内存中。如果服务器宕机,用户会话不会随之丢失。

后台任务应放入队列。 在此规模下使用Kafka或Pulsar。不是RabbitMQ。不是内存处理。不是setTimeout。

在调用级别构建弹性。 断路器、带抖动的重试以及每个出站调用的硬超时。一个慢依赖不应级联成整个系统故障。

基于正确信号进行自动扩展。 CPU是滞后指标。应根据队列深度和错误率进行扩展。这些指标在CPU数字变化之前就能反映真实的系统压力。

5. 数据库策略

单个数据库既是性能天花板,也是单点故障。永远不要只用一个。

推荐技术栈:

  • 主要OLTP:PostgreSQL + Citus实现水平分片

  • 高写入路径:Cassandra或ScyllaDB

  • 缓存与实时数据:Redis集群

  • 分析与聚合:ClickHouse

所有写操作都通过查询路由器(Vitess或Citus)路由。按user_id使用取模策略进行分片,确保数据均匀分布。只读副本放在PgBouncer后面进行连接池管理。

一条再怎么强调也不为过的规则:在第一天就选择你的分片键。 上线后再更改分片键是一个团队能经历的最痛苦的迁移之一。

6. 多层缓存

缓存是高扩展性系统中最大的成本杠杆。目标缓存命中率高于85%。

  • 第1层,边缘CDN缓存: 静态资源和可公开缓存的响应永远不会到达源站。

  • 第2层,应用层Redis缓存: 计算结果、会话数据和热门记录存放在这里。

  • 第3层,查询结果缓存: 昂贵的数据库读取在查询层面被缓存。

只有完全缓存未命中时,请求才会到达数据库。

关于失效策略:通过Kafka进行事件驱动失效。用户资料更新事件应立即使相关的缓存键失效。仅靠TTL对关键数据并不可靠。

7. 可观测性

你无法调试你看不到的东西。在此规模下,你需要从第一天就开始全面的可观测性,而不是等到凌晨2点生产环境出问题之后。

技术栈:

  • Prometheus:指标

  • Jaeger:分布式追踪

  • Loki:日志

  • 全部通过OpenTelemetry进行仪表化,全部流入Grafana仪表盘

  • Alertmanager将关键告警路由到PagerDuty

四个黄金信号。在每个服务上进行仪表化:

  • 延迟:请求耗时

  • 流量:请求量

  • 错误:失败请求的比率

  • 饱和度:资源接近极限的程度

定义真正的SLO。跟踪你的错误预算。在用户注意到之前发出告警。

8. 数据一致性与幂等性

分布式系统会以部分、不可预测的方式失败。从一开始就为此设计。

发件箱模式。 在与业务逻辑相同的事务中,将事件写入数据库表。后台进程读取并发布这些事件。即使消息代理宕机,事件也不会丢失。

Saga模式。 对于跨多个服务的事务,使用一系列补偿操作代替两阶段提交。如果下游步骤失败,每个步骤都有定义的回滚。

幂等键。 每个变更操作应接受一个唯一的请求ID。如果相同的请求到达两次,返回原始结果。这是在不可靠网络上处理重试的唯一安全方式。

在此规模下,最终一致性不是弱点。而是正确的架构权衡。

9. 安全

  • 所有内部服务之间使用mTLS。每个服务间调用都经过认证和加密。

  • 零信任网络。没有服务默认信任另一个服务,无论请求来自何处。

  • 传输中和静态数据都加密,无一例外。

  • 定期进行混沌工程。在生产环境中故意杀死随机Pod,以在流量帮你发现之前验证你的弹性假设。

在受控测试中发现故障模式,远比在凌晨2点流量高峰时才发现要好得多。

10. 完整架构

将所有部分整合在一起:

  • 100万用户

  • 边缘 + CDN + WAF

  • 全球负载均衡器

  • API网关(限流 + 认证)

  • 无状态应用服务

  • Redis集群 / Kafka事件总线 / 分片PostgreSQL + Cassandra

  • 后台工作节点

  • 可观测性层:Prometheus、Grafana、Jaeger、Loki

此架构可承载100万日活用户,并有充足的余量扩展到数千万用户,而无需根本性重写。

开始之前

  • 从小做起并测量一切。基于数据而非假设进行优化。

  • 在任何发布之前,使用k6或Locust以预期峰值流量的2倍进行负载测试。

  • 使用功能标志和金丝雀部署。永远不要直接将功能推送给100%的用户。

  • 在优化之前先分析热点路径。瓶颈很少在你认为的地方。

  • 对非关键工作负载使用竞价/抢占式实例,以大幅削减基础设施成本。

延伸阅读: 《数据密集型应用系统设计》(Martin Kleppmann) | Uber工程博客 | Netflix技术博客 | ByteByteGo

本文中的每个模式目前都在生产系统中运行。

能够承受扩展的系统与在压力下崩溃的系统之间的区别不是天赋。而是在流量到来之前尽早做出的架构决策。

收藏本文。需要时再回来查阅。

你想扩展哪个部分?在回复中告诉我。

#后端工程 #系统设计 #分布式系统 #软件工程

相似文章

ByteByteGoHq/system-design-101

GitHub Trending (daily)

一个GitHub仓库,提供复杂系统设计概念的视觉化和简单解释,涵盖API、负载均衡、HTTP和网络等主题。