直接扔上来一张系统架构图刚接触企业项目的人可能会有点懵觉得怎么这么复杂。但其实这一切都是一步步被逼演化出来的。今天我想从最开始的那个纯粹的单体应用说起带大家走一遍电商系统架构的完整演进之路。1. 最初的大泥球单体应用这就是我们刚接触编程时写的那些 Java 或 C 应用特点就是All in One。用户交互界面可能是 JavaFx 写的业务逻辑、数据访问逻辑全都在一个进程里数据库也是本地的如文件型数据库。本质上软件开发的核心从来没变过把用户的输入经过逻辑处理后写入数据库再把数据库里的数据经过加工后展示给用户。但单体应用存在两个致命弱点数据封闭数据都是本地的虽然安全但无法共享每个人只能看到自己的数据无法与别人产生链接。性能瓶颈所有东西跑在一台机器上受限于单台机器的 CPU 和内存资源。2. 第一次进化数据库分离与 C/S 架构为了让数据集中且共享我们将数据库从本地抽离出来独立部署在一台服务器上应用程序通过网络连接数据库。此时用户设备上只需要安装逻辑代码不再需要内置数据库。这既实现了数据实时交互又节省了本地存储空间。但问题接踵而至业务功能越来越丰富后用户需要下载的安装包依然庞大而且逻辑运算消耗本地 CPU低配设备容易卡顿甚至闪退。3. 第二次进化前后端分离与瘦客户端经过分析我们发现核心计算逻辑完全可以抽取成公共服务跑在提供商的云端机器上。用户的设备只需要发送 HTTP 请求获取数据并渲染展示即可。这便是前后端分离架构的雏形也就是我们常说的 C/S 架构。注B/S 是 C/S 的一种特殊形式只是 Client 统一变成了浏览器Browser。B/S 架构有更好的传播性因为用户不用额外安装任何客户端软件打开网页就能用。4. 第三次进化分层架构职责分离随着业务逻辑越来越复杂为了让代码低耦合、易维护后端内部开始实行分层架构Controller控制层负责接收请求、参数校验与响应封装。Service业务层负责承载核心的业务逻辑如下单扣库存。DAO数据层负责与数据库进行 CRUD 交互。当业务进一步膨胀时我们还会按照业务领域如订单、用户、商品将服务拆分成多个独立的业务模块模块间通过组合调用。用通俗的话讲就是“专业的事找专业的人”避免同一个逻辑在代码里到处复制粘贴。5. 第四次进化物理解耦与 SOA面向服务架构此时虽然逻辑上已经分开了但所有服务依然部署在同一台机器同一个 JVM 进程里。这就有一个致命隐患物理上高度耦合。举个例子订单服务和购物车服务都跑在同一个 JVM 里订单的重要性远高于购物车。如果双11大促时大批用户疯狂加购物车导致 CPU 飙高进而拖垮了整个 JVM 进程那么下单服务也会跟着一起挂——这将是巨大的经济损失。因此我们必须让服务在物理进程上也彻底隔离。每个服务独立部署、独立运行通过网络如 RPC 或 HTTP进行通信。这便进入了SOA面向服务架构阶段也就是我们常说的服务化。SOA 的核心思想是将业务能力封装成标准的服务服务之间通过定义良好的接口进行通信强调服务的松耦合和可复用。6. 第五次进化微服务架构然而SOA 虽然解决了物理隔离但服务间的调用方式却倒退了。在单体时代所有代码都在同一个 JVM 进程里服务间调用仅仅是本地方法调用xxxService.method()就像在同一个房间里喊一嗓子随叫随到。物理隔离之后调用变成了跨网络的远程调用就像两地打电话要拨号、要等待、还可能断线——复杂性骤然增加。传统的 SOA 解决方案是把所有服务调用都发送到ESB企业服务总线由 ESB 负责协议转换、消息路由、数据格式编排。但这存在一个严重的弊端ESB 本身成了单点和整个系统的性能瓶颈而且服务之间依然通过 ESB 产生隐性耦合。伴随着Docker 容器化技术和DevOps 理念的普及服务的独立部署与弹性扩缩容成为可能。业界开始反思既然 ESB 这么重为什么不干脆去掉它把治理能力下沉到基础设施中呢于是微服务架构应运而生。它坚决抛弃了 ESB 这个重装坦克转而采用轻量级通讯协议如 HTTP/REST 或 gRPC并把 ESB 的功能打散到了各个基础设施中注册中心做服务发现代替 ESB 的路由API 网关做对外入口代替 ESB 的协议转换熔断器做容错代替 ESB 的异常处理下面是 SOA 与微服务架构的对比表维度传统 SOA微服务服务粒度较粗通常是整个业务域如ERP系统极细精确到单个业务能力如扣减库存通讯协议重通常依赖 SOAP、WS-* 等复杂协议轻偏爱 HTTP/REST、gRPC、Dubbo数据治理中央集权ESB 统一管理去中心化每个服务独立管理自己的数据库部署方式大多部署在几台大型应用服务器上完全独立部署每个服务拥有独立进程甚至独立容器进阶思考微服务强调去中心化数据管理即每个服务拥有独立数据库。这彻底解决了数据库耦合问题但也因此引入了分布式事务和最终一致性的新挑战——这将是架构演进绕不开的下一道坎。欢迎大家评论区聊聊自己对分布式的理解。7. 第六次进化BFF——给前端减负微服务拆分得很细之后订单、商品、库存、优惠券都独立了后端确实清爽了。但前端的开发却变得极其痛苦。场景痛点电商 APP 首页需要同时展示用户信息 商品图片 优惠券 库存状态 活动倒计时。如果前端直接去调 5 个微服务就要发 5 次网络请求在弱网环境下 APP 会卡死。而且前端开发人员需要熟悉每个微服务的接口参数沟通成本极高。架构演进此时我们在微服务和前端之间加一层胶水层——BFFBackend for Frontend服务于前端的后端。它的职责是“定制化聚合”根据前端APP 端、PC 端、小程序端的不同需求把后台多个微服务的数据抓过来组装成一个刚好满足前端展示的大 JSON 返回回去。这样一来前端只需要发1 次请求BFF 帮它搞定所有数据拼装。前端同学再也不需要关心订单接口怎么调、商品接口什么参数只需要跟 BFF 对接即可。8. 第七次进化服务网格——让治理能力下沉微服务通过注册中心、网关和熔断器解决了服务拆分后的治理问题。但渐渐地我们发现这些治理能力如熔断、重试、超时的代码依然需要耦合在业务应用里比如引入 Spring Cloud Netflix 或 Dubbo 的 SDK。当公司有 Java、Go、Python 多个技术栈时每个语言都要维护一套治理逻辑成本极高——改一个超时配置三个语言的团队要分别改、分别测、分别发布。于是服务网格Service Mesh应运而生。它将微服务的业务逻辑和网络通信治理彻底分离业务代码只负责处理订单和扣库存而所有的限流、熔断、鉴权、监控统统交由部署在业务 Pod 旁的Sidecar边车代理处理。这让业务开发人员可以完全专注于业务而不必关心底层网络有多复杂。升级熔断策略时只需要升级 Sidecar业务代码一行都不用改。9. 第八次进化大数据层——让数据活起来微服务、BFF、服务网格都搞定了系统终于稳定地跑起来了。但跑起来只是及格。电商平台真正的核心竞争力在于“懂用户”和“快决策”。然而我们很快发现一个尴尬的事实交易数据越积越多却是一堆沉睡的金矿。运营想看一眼实时 GMV商品交易总额不敢直连订单库——一个复杂的group by统计查询就能把数据库 CPU 打满直接影响用户下单。产品想分析**加购但未支付的用户画像**发现数据散落在订单、商品、用户、优惠券十几个库里根本无法关联查询。用户搜**“蓝牙耳机”** 如果只是数据库的LIKE模糊匹配搜出来的结果又慢又不准。这时候我们必须在业务交易系统OLTP之外单独构建一套大数据系统。两者的分工非常明确交易系统负责高并发的写下单、支付数据系统负责海量数据的读分析、推荐、搜索。大数据层内部长什么样简单来说它分为四个环节环节组件职责数据接入Canal Kafka实时监听业务数据库变更把数据同步到消息队列数据计算Flink实时/ Spark离线清洗、聚合、关联计算数据存储ClickHouse / Elasticsearch / Redis存放报表数据、搜索索引、推荐缓存数据应用运营大屏 / 商品搜索 / 推荐系统直接面向用户和运营提供服务实际业务场景举例实时大屏双11大促时Flink 每 5 秒聚合一次订单流实时推送到大屏展示 GMV。猜你喜欢推荐算法团队用 Spark 离线训练推荐模型结果存入 Redis用户打开 APP 时毫秒级读取。商品搜索商品信息变更时Canal 实时更新 Elasticsearch 索引保证搜索结果最新。运营报表运营人员分析浏览→加购→支付转化率直接查询 ClickHouse秒级返回完全不干扰主业务库。理解大数据层最关键的一点是它和微服务业务层是物理隔离的数据单向流动。业务库的数据单向同步到大数据平台但大数据平台绝不反向写入业务库。这种设计确保了即使大数据平台做复杂查询把 CPU 打满了也不会影响用户正常下单——这就是电商系统稳定性的底线。写在最后架构的本质是什么我们从单体应用一路走到大数据层回头看看这条路阶段演进驱动因素1单体应用入门All in One2数据库分离数据需要共享3前后端分离客户端设备性能不足4分层架构代码职责混乱难以维护5SOA物理隔离服务互相影响稳定性差6微服务去 ESBESB 成为单点瓶颈7BFF多端适配前端调用太复杂8服务网格治理能力与业务代码解耦9大数据层数据价值需要被挖掘每一次架构演进本质上都在做同一件事将复杂性进行有序的分层、解耦与下沉。那些看起来过度设计的复杂架构其实都是一步步被真实业务场景逼出来的。没有一步是多余的也没有一步是凭空想象的。架构没有终点只有不断演进的起点。大家可以在评论区聊聊你们的系统现在处在哪个阶段又遇到了什么新的挑战下期预告为什么你的代码在笔记本上跑得飞快上了服务器反而变慢了我们在这篇文章里聊了电商系统的架构演进从单体一路走到了大数据层。但不知道你有没有想过一个问题所有这些微服务、BFF、大数据组件最终都跑在什么上面无论是订单服务还是 Flink 计算任务它们最终都要被 CPU 执行、在内存里暂存、从硬盘里读取数据。而CPU 的缓存一致性、内存的寻址方式、磁盘的 IO 模型这些计算机组成原理的基础知识直接决定了你的系统到底能扛多少 QPS。下一篇文章我们把视线从架构设计往下沉一层看看计算机硬件到底是怎么运行你的代码的。你会发现很多你写代码时遇到的诡异问题——比如为什么加了缓存反而更慢了、“为什么多线程程序有时候比单线程还慢”——答案都藏在计算机组成原理里。