






















"我们要不要上微服务?""这个得做成分布式的吧?"——聊到架构,这类话满天飞,但架构设计到底在设计什么? 这个问题反而很少被说清。至少我刚开始补这块时是一头雾水的:总以为架构就是画框图、堆时髦技术,后来才慢慢发现不是这么回事。
这是《服务端架构设计》系列的开篇,先建一张全局地图:架构的本质是什么、它在哪几个目标之间权衡,以及一个系统从单体长到微服务,每一步到底在解决什么问题。把这张地图揣在手里,后面每一块(高并发、高可用、微服务、分布式)才挂得上去。
是什么。 架构是一个系统的骨架:它决定了系统拆成哪些模块、模块之间怎么协作、数据怎么流动、请求怎么被处理。但更本质的一句话是——
架构设计不是"选最牛的技术",而是在一组互相冲突的目标之间做权衡(trade-off)。
评价一个架构好不好,业界有一套公认的坐标系,叫非功能性需求(功能之外、但决定系统"扛不扛得住"的那些):
| 维度 | 一句话 | 衡量 |
|---|---|---|
| 高性能 | 快不快 | 响应时间、吞吐(QPS / TPS) |
| 高可用 | 稳不稳、宕不宕机 | 可用性(几个 9,如 99.99%) |
| 可扩展性 | 能不能长大 | 加机器能不能线性扛更多 |
| 可维护 / 可演进 | 好不好改 | 加功能要不要动全身 |
| 安全 | 守不守得住 | 鉴权、防攻击、数据保护 |
| 成本 | 烧多少钱 | 机器、带宽、人力 |
关键认知:这些维度互相冲突。 高可用要靠冗余(多备几台)→ 成本上升;高性能加缓存 → 一致性变难、复杂度上升;微服务让系统更可扩展 → 运维和排查的复杂度暴涨。
所以没有"完美架构",只有"最适合当前业务阶段的权衡"。脱离业务场景问"要不要上微服务""要不要上 K8s",其实很难有答案——基本都是"看情况"。所以搞懂一个架构,关键是看清它在为哪个目标、牺牲了什么代价。
为什么。 因为业务会增长,而系统要跟着长大。今天扛 100 个用户的写法,到 100 万用户时大概率会崩;架构决定了系统能不能平滑地跟上这个增长,而不是每翻一个量级就推倒重来。
不设计的代价很具体:单体代码堆到几十万行,改一行牵一发动全身,上线前总担心带崩别的模块;所有功能挤在一个进程里,一个不起眼的模块内存泄漏,能把整个系统一起拖下水;数据库一个慢查询,也能让全站跟着卡——而且这类线上事故,还特别爱挑凌晨来。
但反过来——过度设计是另一个坑,而且更隐蔽。一个日活几百的产品,一上来就上微服务、上 K8s、上消息队列,背上了一整套分布式的复杂度和成本,却没有任何与之匹配的流量。这就是著名的 YAGNI(You Aren't Gonna Need It,你并不会用到它)反面教材。
所以架构设计真正要做的,是匹配业务的当前阶段,既不滞后(扛不住)、也不超前(白烧钱),并给未来留好演进的空间。
补到这儿,可能有人(我自己一开始也犯过嘀咕)会想:AI 都能写代码了,还费劲学架构干嘛? 这事得正过来看。
现状是什么。 现在用 AI 写代码,几秒就生成一大段,能跑就想直接上线。但凡用 AI 写过东西的人大概都体会过:它写的代码"能跑",离"扛得住"还差一截——demo 跑得好好的,一上量、一上线,各种意想不到的 bug 就冒出来了。
为什么会这样。 因为 AI 特别擅长"局部正确":你让它写一个函数、一个接口,它大概率又快又对。但它默认只盯着你给的那一小段上下文,不会主动替你操心全局的那些事:
这些恰恰不是"写代码"的问题,而是"架构设计"的问题。"能跑"和"扛得住"之间那段距离,基本就是架构——AI 默认不会替你想,除非你明确告诉它该考虑什么;而你得先自己懂,才说得出来。
于是带来一个反直觉的转变。 当"写代码"这件事变得越来越便宜,真正稀缺、也更值钱的,反而是另一种能力:做架构设计 + 给 AI 把关——知道这段东西上线会不会出事、哪里得约束它、该怎么 review。
业界正在形成的做法,大致是这样:
这也是这个系列想补的东西:不是"怎么写代码"(那件事 AI 帮你做了一大半),而是"怎么把系统设计对、怎么判断什么地方会出事"。AI 越强,这种判断力反而越值钱——它能帮你写,但替你担责的还是你自己。
这是全文的骨架。一个互联网系统的架构,基本都沿着下面这条路长大——而且每一步,都是被一个具体的痛点逼出来的,不是为了"更高级"。
阶段 0 · 单体应用(All-in-One)。 创业初期:一个应用 + 一个数据库,部署在一台服务器上,所有功能(用户、订单、支付)都在一个进程里。优点是简单——开发快、部署快、排查直接。用户不多、团队就几个人时,这反而就是最优解。
痛点 1:用户变多,一台机器扛不住了。 → 先做应用与数据库分离(各占一台);还不够就上应用集群 + 负载均衡:部署多台一样的应用机,前面架一个负载均衡器(Nginx / LVS / 云 SLB)把请求分发下去。 → 新问题:多台机器之间,用户的登录态(session)放哪?(引出 session 共享 / 把状态放 Redis——正好接《缓存》篇讲的"短命数据主存储"。)
痛点 2:读请求太多,数据库先扛不住。 → 上缓存(热点数据放 Redis,挡住大部分读)+ 读写分离(一主多从,写主库、读从库,把读压力摊到多个从库)。 → 新问题:缓存和数据库的一致性、主从同步延迟——这些《缓存》篇和后面的高可用篇会展开。
痛点 3:数据量大到单表 / 单库装不下。 → 分库分表:把一张大表水平切成多张、甚至拆到多个库。 → 新问题:跨库查询怎么办、分布式事务怎么保证——留给"分布式"那个阶段。
痛点 4:单体代码膨胀,改不动、一处挂全挂、团队互相踩脚。 这才是上微服务的真正理由——不是因为微服务高级,而是单体的协作和稳定性成本扛不住了。 → 垂直拆分 / 微服务:按业务边界把单体拆成多个独立服务(用户服务、订单服务、支付服务),各自独立开发、部署、扩容。 → 新问题:服务之间怎么调用、怎么找到对方、一个挂了会不会连环拖垮——引出服务治理。
痛点 5:服务拆了几十个,调用关系乱成一团、部署运维成噩梦。(本来指望拆完更清爽,结果查一个 bug 要顺着调用链翻好几个服务的日志,反而比单体时候更让人头大。) → 服务治理 + 云原生:注册发现(服务自动找到彼此)、API 网关(统一入口)、链路追踪(《可观测性》篇)、容器化与编排(Docker + Kubernetes),再往上是服务网格(Istio)。 → 这一层解决的是"服务多了之后,怎么管得过来"。
这里能看出一个规律:每一步演进 = 解决上一步的痛点 + 引入新的痛点,而新痛点就是下一步(也是这个系列后面每一篇)要搞懂的。架构往往不是一开始设计出来的,是一个痛点一个痛点演进出来的。
主流演进范式。 上面这条路不是我编的,是几乎所有大型互联网系统都走过的公认路径:
单体 → 垂直拆分 → 分布式服务(SOA)→ 微服务 → 云原生(容器 / K8s / 服务网格)
每一层,业界都有成熟的开源主流方案,选型时大致认这些:
| 能力 | 业界主流方案 / 技术库 |
|---|---|
| 负载均衡 | Nginx、LVS、HAProxy、云厂商 SLB / ALB |
| 缓存 | Redis、Memcached |
| 微服务框架 | Spring Cloud(Java)、Dubbo、gRPC、Go-Zero / Kratos(Go) |
| 服务注册发现 | Nacos、Consul、etcd、Eureka |
| API 网关 | Spring Cloud Gateway、Kong、APISIX、Nginx |
| 配置中心 | Nacos、Apollo |
| 容器与编排 | Docker + Kubernetes |
| 服务网格 | Istio、Linkerd |
| 可观测 | Prometheus + Grafana、OpenTelemetry(见《可观测性》篇) |
但最重要的一条业界共识是:不是每个系统都要走到最后一步。绝大多数业务,单体 + 缓存 + 读写分离就能扛很久;真到了需要微服务的体量,你自然会被痛点推着走。技术大厂走完全程,是因为它们的流量和团队规模真到了那个量级;终点的架构,未必适合起点的业务。
把全文收进一张表,这也是整个系列的"地图"——每一行的"新问题",基本就是后面一篇的主题:
| 业务阶段 | 痛点 | 架构解法 | 带来的新问题(后面解决) |
|---|---|---|---|
| 起步 | —— | 单体 + 单库 | —— |
| 用户变多 | 单机扛不住 | 应用集群 + 负载均衡 | 会话 / 状态放哪 |
| 读压力大 | 数据库读扛不住 | 缓存 + 读写分离 | 缓存一致性、主从延迟 |
| 数据量大 | 单表 / 单库装不下 | 分库分表 | 分布式事务、跨库查询 |
| 代码 / 团队膨胀 | 改不动、一处挂全挂 | 微服务拆分 | 服务治理、分布式复杂度 |
| 服务太多 | 调用乱、部署难 | 注册发现 / 网关 + 容器化 | 可观测、运维复杂度 |
本文是《研发都要懂的事》·服务端架构设计系列开篇——建立全局地图。后面逐阶段深入:高并发三板斧、高可用、微服务拆分、分布式事务……每一篇都对应上面那张表里的一个"新问题"。完整代码与系列在 GitHub · backend-notes。
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。