Skip to content
🗂️ 文章分类: 架构  
📅 文章创建时间: 2025-10-13
🕘️ 文章最后更新时间:2026-04-09

[toc]

程序系统架构演变

目前程序系统架构大体经历了下面几个过程。

架构演变的底层逻辑

先明确一个核心观点:架构的本质是 “权衡”—— 在 “业务需求”“技术成本”“性能体验” 三者间找平衡点:

  • 业务需求:用户量、功能复杂度、迭代速度(比如创业项目要 “快”,成熟产品要 “稳”);
  • 技术成本:开发效率、运维难度、团队能力(比如小团队养不起微服务运维团队);
  • 性能体验:响应速度、可用性、扩展性(比如电商双 11 要抗住 10 倍流量)。

所有架构的演变,都是这三者矛盾升级后的解决方案。

单体架构(2000-2010): “小而美” 的起步阶段

业务背景

2000 年前后,互联网刚起步,产品多是 “工具型” 或 “信息展示型”。比如企业官网(展示产品)、个人博客(写文章)、小型 CRM(管理客户) 、论坛(个人 / 中小企业建站)等。

这类系统用户量基本在千级以内,单日访问量万级,核心诉求是 “能用、快上线”,没人会为 “未来可能的增长” 提前设计架构。

这时,没人会考虑 “分布式”“高可用”。因为业务根本用不上,反而会增加开发成本。

架构设计

单体架构的核心概念是 “集中式”。即所有代码、依赖、数据(可选)都在一个应用里,部署在一台服务器上。

因此互联网早期,软件系统的架构就是将所有的功能代码都放在一个应用程序中,并且部署在一个服务器即可。这样可以减少开发,部署和维护的成本。

如图所示一个单体架构的电商系统,里面会包含很多用户管理,商品管理,订单管理,物流管理等等很多模块,这些模块通常在一个项目中,然后部署到一台服务器中。

blog_20231111181427.png

架构优缺点

优点

  • 开发成本低:一个人能搞定全栈(前端 + 后端 + 数据库),不用考虑 “服务间调用”“数据同步”等问题;
  • 维护简单:报错了直接在代码里打断点,从接口层追到数据层,一步定位问题;
  • 部署简单:打包成 war/jar 包扔到服务器中就能发布,部署时全量替换包,重启服务器就行,运维门槛为零。

缺点

  • 性能瓶颈:由于单体架构中应用和数据库部署在同一个服务器中。因此两者在流量高峰期间会抢服务器资源,导致性能下降;
  • 可扩展性差:由于所有功能都在一个应用中,因此当业务需求增加时,无法针对不同模块进行优化和扩展。
  • 部署风险:想改个程序,必须重新打包,重新部署到服务器中,在重启期间,程序无法使用。
  • 代码臃肿:如果程序代码不断增加,代码从 1 万行涨到 5 万行,找一个逻辑都要翻半天。

架构优化技巧

  • 加缓存:用 Redis 存热门数据(比如门票库存),减少数据库查询压力;
  • 数据库读写分离:主库写(下单),从库读(查订单),分担压力;例如用 MyCat 做简单的分库分表;
  • 代码分层:代码严格按 “Controller→Service→DAO→Entity” 分层,用 Spring 的 IOC 解耦,避免业务逻辑写在 Controller 里。

只有当优化后仍满足不了业务(比如用户量超 10 万),才需要考虑下一阶段。

架构突破点

当出现以下场景时,单体架构就到了 “天花板”:

  1. 服务器 CPU / 内存长期占用超 80%,优化后仍无法下降;
  2. 单次部署时间超过 10 分钟,影响业务迭代(比如一天要发 3 次版);
  3. 团队超过 5 人,多人改同一套代码,冲突不断。

这时,“垂直拆分架构” 就该登场了。

垂直拆分架构(2010-2013):业务拆分

业务背景

2010 年后,互联网产品开始向 “多功能” 发展:比如电商从 “只卖商品” 增加了 “订单支付 用户评价 物流跟踪等功能”;

这时,单体架构的 “一锅粥” 问题凸显。即随着单体应用的访问量不断增大,由于单体应用中的各个功能模块紧密耦合,因此无法针对不同的模块进行优化和扩展。

例如电商系统的 “商品模块”(读多写少)和 “订单支付模块”(写多读少)混在一起,最终会导致商品模块的高并发会拖垮支付模块,改物流逻辑要动整个电商系统的代码。

架构设计

垂直拆分架构的核心逻辑是 “按业务进行拆分,隔离”。即把原来的大单体拆成多个独立的 “小单体”,每个小单体负责一块业务,拥有自己的代码、服务器和数据库。

将一个大单体按照业务拆分为多个单体之后,每个单体就可以根据需求进行各自优化和扩展了。

例如一个大型电商系统的单体应用,拆分为电商系统,后台系统,CMS系统等。我们可以根据需求来优化扩展对应的应用。如图所示。

blog_20231111182042.png

优缺点

优点:解决了单体的 “大而全” 问题

  • 风险隔离:例如某电商的商品服务因缓存失效崩了,但订单和支付服务正常,用户还能下单(只是看不到商品详情);
  • 方便优化和扩展:商品服务访问量大,则单独对商品服务添加 2 台服务器;如果支付服务要稳定,则单独对支付服务使用高可用配置(即双机热备 + RAID 磁盘阵列);
  • 团队协作:不同的业务功能可以分给不同的团队。每个团队专注一块业务,这样代码冲突就少了。

缺点

  • 系统复杂度增加:由于是将一个单体应用拆分为多个互不相干的应用。因此系统的复杂度就会增加。
  • 运维工作量增加:要维护多套应用的部署脚本、数据库,运维工作量翻倍;
  • 数据同步问题: 由于是将一个单体应用拆分为多个互不相干的应用。因此不同应用之间的数据同步问题就会变得比较复杂。
  • 重复开发:由于各个应用之间相互独立,因此应用之间会有重复的代码。例如每个应用可能都需要写一套登录校验代码,权限管理代码等。

垂直拆分架构的 “判断标准”

不是所有业务都要拆,满足以下条件再拆:

  1. 业务模块边界清晰(比如 “商品业务模块” 和 “用户业务模块” 完全独立,没有强耦合);
  2. 某个模块的访问量 / 数据量是其他模块的 3 倍以上(比如商品模块每天 100 万访问,其他模块 10 万);
  3. 团队人数超过 10 人,需要按业务进行分工。

架构突破点

当垂直拆分后的服务越来越多(比如电商加了 “评价服务”“物流服务”),新的问题出现了。

  1. 每个服务都要对接支付接口(微信 / 支付宝),但对接逻辑复杂,每个服务都写一遍太浪费;
  2. 服务间调用越来越多(比如下单要调用商品服务查库存、调用用户服务查地址、调用支付服务发起支付),接口地址管理混乱(改一个接口,所有调用方都要改)。

这时,需要一个 “统一的公共服务” 和 “服务调用管理中心”—— 分布式架构(SOA)应运而生。

分布式架构(SOA)(2013-2016):“公共服务 + 服务总线”

业务背景

2013 年后,互联网产品开始向 “平台化” 发展:比如美团从 “外卖” 扩展到 “酒店”“打车”“买菜”;阿里从 “淘宝” 扩展到 “天猫”“支付宝”“阿里云”。

这些产品的核心特点是 多业务线复用公共能力。比如 支付,用户认证,消息推送 是所有业务线都需要的功能。如果每个业务线都自己做,不仅成本高,还容易出问题(比如支付接口不统一,导致对账混乱)。

因此分布式架构(SOA)中就需要将多个业务中重复的功能进行抽取,做出一个独立的应用,并且让其他需要的应用去调用它。

此时还需增加一个中心,这个中心就是用来连接各个服务应用。各个服务应用之间,只需要和中心进行通信,这个时候,各个应用之间的交互就会变得更加的清晰,业务架构/逻辑等,也会变得很清楚。

架构设计

分布式架构(SOA)的核心是 “标准化公共服务 + 中心化服务总线”。即把所有业务都需要的能力抽成 “公共服务”,用 “服务总线(ESB)” 统一管理服务间的调用,从而解决 “重复开发” 和 “调用混乱” 的问题。

如图所示,无ESB的分布式架构 blog_20231111182615.png

如图所示,有ESB的分布式架构 blog_20231111183817.png

此处的服务总线(ESB),是用来管理服务应用之间的调用关系的。它会记录下每个服务应用的地址,当一个服务应用需要调用另一个服务应用时,就会去服务总线中查询目标服务的地址,然后进行调用。

优缺点

优点

  • 代码复用:公共服务只需要写一次,让其他业务服务去调用。通过抽取的公共业务代码来作为服务层,提高了代码的复用性。
  • 调用可控:ESB 统一管理服务地址,改接口地址只需要在 ESB 里配置,不用改所有调用方的代码;通过使用ESB作为中心解决了服务应用之间调用关系
  • 监控方便:通过 ESB 能统计每个服务的调用量、响应时间,快速定位 “慢接口”。

缺点

  • 服务之间的耦合性更高:ESB 是核心瓶颈,一旦 ESB 崩了,所有服务调用都停摆(例如 2015 年某银行 ESB 故障,导致全国 ATM 机无法取款);
  • 运维复杂:要维护 ESB 集群、公共服务集群,测试环境要模拟多服务调用,联调一次要半天;
  • 同步调用效率低:下单流程要同步调用商品(查库存)→用户(查地址)→支付(扣钱),每个调用耗时 500ms,总耗时超 1.5 秒,用户体验差。
  • 服务之间关系变得更加复杂,并且运维和测试部署都会变得困难。

优化方向

  • 高可用:给 中心/ESB 或公共服务做集群(多台服务器部署),一台挂了,其他台继续工作;
  • 性能优化:给 中心/ESB 加缓存(比如缓存服务地址),减少 中心/ESB 的负载压力;
  • 服务解耦:用 “事件驱动” 替代 “同步调用”(比如订单创建后,发一条事件到消息队列,支付服务监听消息队列,不用 中心/ESB 同步调用)。

架构突破点

2016 年后,互联网进入 高并发时代。 例如 2016 年双 11,阿里订单峰值达 12 万 / 秒,SOA 的 ESB 根本扛不住。

  • 中心/ESB 的集群规模要扩到 10 台以上,运维成本太高;
  • 服务间的同步调用(比如下单要等 3 个服务调用完成)导致响应时间超 2 秒,用户体验差;
  • 公共服务和业务服务耦合太紧,公共服务改个小功能,所有业务服务都要停服升级。

这时,需要一种 “更灵活、更抗并发” 的架构 —— 微服务架构来了。

微服务架构(2016-2020):“细粒度拆分 + 去中心化治理”

业务背景

2016 年后,互联网产品进入 去中心化 阶段。例如抖音(拆分为推荐、评论、点赞、关注等微服务),拼多多(拆分为商品、订单、营销、物流微服务)。

这些产品的特点是 “高并发、快迭代、多团队独立开发”。原先的分布式架构的 “重总线 + 粗粒度服务” 根本满足不了。

而微服务架构能满足,可以做到 “改推荐算法只重启推荐服务,不影响评论功能”。

架构设计:“拆到最小 + 去掉总线”

微服务架构的核心是 “细粒度拆分 + 去中心化治理”。就是把服务拆到 “一个功能一个服务”。去掉中心化的 ESB,让服务之间直接调用,同时使用 “服务治理工具” 解决服务之间调用的问题。

微服务架构,简单的说就是将原有的大的系统会拆分为多个可以独立开发、设计、运行的小型服务。各个小型服务之间,相互通信,来组成一个业务系统。

blog_20231111184456.png

微服务架构下需要解决的问题

一旦采用微服务系统架构,就势必会遇到这样几个问题:

  • 这么多服务,如何管理它们?
  • 这么多服务,它们之间是如何互相通信?
  • 这么多服务,如何访问它们?
  • 这么多服务,一旦某个服务出现了问题,该如何处理?

上面的这些问题都是微服务架构下会遇到的。因此为了解决上面的问题就出现了“服务治理工具” 。如下所示

  • 服务注册发现 如:Nacos、Eureka、Consul 等
  • 服务调用 如:Spring Cloud OpenFeign(HTTP) 等
  • 服务网关 如:Spring Cloud Gateway、Kong 等
  • 服务容错 如:Sentinel、Hystrix 等
  • 服务链路追踪 如:SkyWalking、Zipkin、Jaeger 等

微服务架构的优缺点

优点:灵活、抗并发、易迭代

  • 故障隔离:若某一个微服务发送故障,不会影响到其他正常微服务,影响范围小;
  • 技术栈灵活:推荐服务用 Go(性能高),用户服务用 Java(生态成熟),视频上传服务用 Python(转码库多);
  • 按需扩容:在某些流量高的时间段,可以对负载压力大的微服务进行临时扩容 10 台服务器,其他微服务保持不变。

缺点:“分布式复杂性”

  • 分布式事务不一致:由于微服务架构下,服务之间是通过网络进行通信的,因此会存在分布式事务不一致的问题。
  • 服务调用链路太长:由于微服务架构下,服务之间是通过网络进行通信的,因此会存在服务调用链路太长的问题。这就会导致服务调用的延迟增加。
  • 运维复杂度爆炸:随着微服务的增加,服务之间的调用关系也会变得复杂。这就会导致服务治理的难度增加。

微服务架构的适用场景

不是所有公司都适合微服务,满足以下条件再上:

  1. 用户量超 1000 万,峰值 QPS 超 1 万;
  2. 团队人数超 30 人,按业务域分成多个小团队;
  3. 有专门的运维,DevOps 团队,能维护服务治理工具。

架构突破点

微服务解决了高并发问题,但对 “轻量需求” 来说,成本太高:比如抖音的 “用户点赞通知” 功能,每天调用量 10 万次,却要维护一个 “通知微服务”(包含注册中心、网关、监控),性价比太低。

云原生架构(2018 - 至今):微服务的 “云化升级”

如果说之前的微服务架构是传统微服务架构,那么云原生架构就是微服务架构的 “云化升级”。

业务背景

2018 年后,微服务的 “运维复杂度” 成了新痛点:企业要自己维护服务器、集群、监控,哪怕是 10 人团队,也要配 2 个运维。同时,云厂商开始成熟(阿里云 ACK、腾讯云 TKE、AWS EKS)。

云原生的核心诉求是:把微服务的基础设施交给云厂商,开发者只关注业务逻辑。

典型案例:字节跳动的火山引擎(基于 K8s 管理所有微服务)、阿里的淘宝系(全量迁移到云原生架构)、银行的核心系统(从物理机迁移到云原生容器集群)。

架构设计

云原生不是 “替代微服务”,而是 “微服务的最佳落地方式”,核心是 4 个原则:容器化、DevOps、持续交付、可观测性。

架构组成

层级核心组件作用
基础设施层Kubernetes(K8s)容器编排,自动部署、扩容、自愈微服务(比如某服务崩了,K8s 自动重启)
应用层容器化微服务每个微服务打包成 Docker 镜像,运行在 K8s Pod 里,隔离性更强
自动化层CI/CD(Jenkins/GitLab CI)代码提交后自动编译、打包、测试、部署到 K8s,抖音每天打 3 次版,全靠 CI/CD
可观测层Prometheus + Grafana监控微服务的 CPU、内存、调用量,Grafana 可视化,异常时自动告警
服务网格层Istio替代传统的服务治理工具,统一管理服务间的流量、熔断、限流、链路追踪

云原生架构 对比 传统微服务架构

维度传统微服务云原生微服务
部署效率手动打包、上传、部署自动化 CI/CD,分钟级部署
扩容效率手动加服务器、部署服务K8s 自动扩容,秒级响应流量高峰
故障自愈人工重启服务K8s 检测到 Pod 崩溃,自动重启 / 重建
资源利用率服务器利用率 30% 左右容器化后利用率提升到 70%+
运维成本20 个微服务需要 2 个运维200 个微服务仍只需 2 个运维(K8s 自动化)

架构优缺点

优点

  • 极致自动化:字节跳动的 “推荐服务” 代码提交后,10 分钟内自动部署到线上,无需人工介入;
  • 资源成本低:阿里将 1000 + 微服务容器化后,服务器数量减少 40%,每年省上亿成本;
  • 弹性伸缩:双 11 淘宝的 “订单服务” 流量从 1 万 QPS 涨到 10 万 QPS,K8s 自动扩容 200 个 Pod,无需人工配置。

缺点

  • 学习成本高:K8s、Istio 的知识点多,新人入职要 3 个月才能上手;
  • 复杂度转移:从 “业务运维” 转移到 “K8s 运维”,需要懂容器网络、存储、安全;
  • 不适合小业务:创业公司用户量小,用 K8s 相当于 “杀鸡用牛刀”,运维成本远超收益。

适用场景

  • 中大型企业:微服务数量超 50 个,团队人数超 50 人,有专门的 DevOps / 云原生团队;
  • 高并发场景:电商、直播、社交产品,需要快速扩容、故障自愈;
  • 合规要求高的场景:金融、政务系统,K8s 的多租户、权限控制能满足等保要求。

Serverless 架构(2020 - 至今):特殊的云原生架构,只写函数,云厂商管所有基础设施

Serverless 是利用 FaaS(函数即服务) + BaaS(后端即服务) 构建应用的架构模式,核心是 “开发者只写函数,云厂商管所有基础设施”

业务背景:从 “重服务” 到 “轻量功能”

2020 年后,互联网产品进入 精细化运营 阶段:比如电商的短信通知等功能”;社交 APP 的评论回复通知 等功能。

这些功能的核心特点是 轻量、潮汐流量 比如 短信通知等功能 平时每天 1 万次调用,双 11 当天 100 万次调用;点赞提醒功能凌晨调用量几乎为 0,晚上 8 点峰值 10 万次。

用微服务做这些功能,会有两个问题:

  • 运维成本高:一个 短信通知等功能 微服务,要维护服务器、扩容配置,太浪费;
  • 成本高:服务器 24 小时开机,即使调用量为 0,也要花钱。

因此,Serverless 架构就出现了。Serverless 架构是一种特殊的云原生架构。

架构设计

Serverless = 无服务器架构 = 你只管写业务代码,服务器、运维、扩容、重启全交给云厂商完成。

把业务逻辑写成 “函数”(比如 “发送短信” 函数),函数触发时才运行,云厂商负责服务器、扩容、运维,按调用次数收费。

可以理解为云厂商完成了这些业务功能,然后你通过付费的方式使用这些功能。你只需要在需要时触发云厂商提供的API函数,云厂商负责服务器、扩容、运维,按调用次数收费。

架构组成

架构层核心组件作用
函数层(FaaS)短信函数、优惠券核销函数、点赞提醒函数每个函数只做一件事(比如 “短信函数”:接收手机号和内容,调用阿里云短信 API 发送)
托管服务层(BaaS)云数据库 RDS、OSS、消息服务 MNS用云厂商的托管服务替代自建服务(比如用 RDS 存优惠券数据,不用自建 MySQL)
触发器层API 网关、定时触发器、MNS 触发器触发函数运行(比如用户点击 “核销优惠券”,API 网关触发 “优惠券核销函数”)

函数运行流程(以短信通知案例)

  1. 你写一个函数:sendSms (phone, content)
  2. 上传到云厂商 FaaS
  3. 订单系统发消息 → 触发函数sendSms
  4. 云厂商启动实例 → 运行函数sendSms → 发短信 → 销毁实例
  5. 只收这一次执行的钱
  6. 全程你不用管服务器

serverless 架构 和 云原生架构 的区别

Serverless 是云原生体系里最极致、最托管、最不用管基础设施的一种实现模式。

做个比喻:

  • 云原生(K8s)= 你租了一套精装公寓。按月/年付费,你需要住(服务长期运行)打扫、管理。
  • Serverless 架构 = 你住酒店。按次 / 按天付费,不用打扫、不用管理。

优缺点

优点:极致轻量化,降本增效

  • 开发快:“发送短信” 函数只需要 10 行代码(调用云厂商的短信 API),不用写服务治理逻辑,10 分钟就能上线;
  • 运维为 0:不用管服务器、扩容、监控,云厂商全搞定(比如函数运行报错,云厂商会发告警到钉钉);
  • 成本低:某电商的 “优惠券核销” 函数,每月调用量 50 万次,成本不到 1 元,比微服务(每月服务器费 500 元)省 99%。

缺点:不适合所有场景(别滥用!)

  • 状态管理难:函数无状态,可以频繁调用 BaaS 服务(比如 RDS)。但是如果业务逻辑依赖复杂状态(比如长会话),会很麻烦;
  • 厂商绑定严重:阿里云函数的 API 和 腾讯云的 不一样,把函数从阿里云迁到腾讯云,要改代码;

适用场景

对于核心服务(推荐、订单),推荐使用云原生微服务(K8s 部署),保证低延迟、高可用;

对于边缘功能(短信通知、点赞提醒、日志处理),特别是无状态的边缘功能。推荐使用Serverless 函数,降本增效;

架构没有 “银弹”,选择合适的架构

回顾上文,你会发现一个规律:架构的演变,不是 “从差到好”,而是 “从适合小业务到适合大业务”。 没有哪种架构是 “绝对先进” 的。

现在很多内部管理系统(比如公司的 OA)还是用单体架构(因为用户量小,没必要拆);某些大公司的核心业务用微服务架构,边缘业务(短信通知)用 Serverless架构;

而一个创业项目,从单体架构起步,用户量超 10 万拆垂直架构,超 1000 万拆微服务,边缘功能用 Serverless,这才是 “合理的演进路径”。

总结 4 个核心避坑原则:

  1. 不要 为了拆分而拆分:小业务用单体架构不丢人,等用户量、团队规模到了再拆,拆早了只会增加成本;
  2. 不要 技术先行:先满足业务需求,再谈技术优化。比如金融系统先保证合规,再谈性能;
  3. 不要 过度设计:比如给日活 1 万的 APP 设计 “异地多活” 架构,纯属浪费;
  4. 不要 忽视运维:选架构前先看团队能力,没有运维团队就别上微服务 / 云原生,用 Serverless 或托管服务。

架构选择决策表

最后,给你一个 “架构选择决策表”,帮你快速判断该用哪种架构。

业务规模团队人数核心需求推荐架构
用户量 < 1 万,功能 < 10 个1-5 人快速上线,成本低单体架构。优先 Spring Boot 单体架构,避免过度分层
用户量 1 万 - 10 万,功能 10-20 个5-10 人风险隔离,性能可控垂直拆分架构,按业务域拆分,用 Redis 做跨应用缓存
用户量 10 万 - 100 万,多业务线10-30 人公共能力复用,调用标准化分布式架构(SOA)
用户量 100 万 - 1 亿,高并发30 + 人灵活迭代,抗并发云原生微服务(K8s),小团队可以先用 Spring Cloud 传统微服务架构,成熟后迁移到 K8s 云原生微服务架构。
轻量功能,潮汐流量任意降本增效,运维为 0Serverless 架构。核心逻辑用函数,状态存在 BaaS 服务

记住:最好的架构,是能支撑当前业务,又能为未来 1-2 年的增长预留空间的架构。千万不要为了 “追热点” 而盲目拆分,也不要为了 “省成本” 而固守旧架构。