后端架构演进:一次从单体到云原生的真实旅程
开篇 · 为什么是这个话题?

2018年,我加入一家中型电商平台公司,负责后端系统的架构优化和技术选型。那时候我们的系统是一个典型的单体应用,部署在一台物理服务器上,用的 Spring Boot 构建,数据库是 MySQL 单点部署,接口通过 Nginx 做负载均衡。
随着业务增长,每天订单量从千级突破到万级,系统开始频繁出现响应慢、服务宕机等问题。运维团队疲于奔命地重启服务、扩容服务器;开发团队则天天改代码、加缓存、优化 SQL——但问题层出不穷,根本解决不了根本。
这让我意识到:我们不能再靠“修修补补”的方式来应对增长了,必须从根本上重构后端架构。
这篇文章,就是想和大家分享我亲身经历的一次从单体架构到微服务再到云原生架构的技术演进过程,聊聊我们在实际项目中遇到的问题、踩过的坑、以及走通的路径。
问题描述 · 单体架构带来的困境

项目背景
我们最初的产品形态是一个 B2C 的在线零售平台,前端是 Vue + PC 端 + 小程序三端并行。用户注册、商品展示、购物车、下单、支付、售后等所有功能都集中在同一个 Java Web 应用中。
面临的主要问题
性能瓶颈明显:每次大促活动或节假日促销期间,系统响应时间剧增,甚至出现超时和崩溃。
记得有一次双十一大促,凌晨流量激增,直接导致 JVM 内存溢出(OOM),日志满屏都是
OutOfMemoryError。那晚我们彻夜不眠地排查和修复。部署困难:每次发布新版本都需要停机几分钟,影响用户体验。而且一旦某个模块出错,整个系统都会受影响。
开发协作低效:多个开发团队在一个代码仓库里工作,经常发生冲突和错误合并,测试环境也难以完全隔离。
扩展性差:虽然上了 Tomcat 集群 + Redis 缓存,但核心逻辑耦合严重,无法按需横向扩展某些关键模块。
这些问题不是靠局部优化能彻底解决的。我们需要一场彻底的架构升级。
解决方案 · 从拆分开始,走向云原生

第一阶段:单体拆分为微服务(Spring Cloud)
我们决定尝试将系统拆解为几个相对独立的服务:
- 用户中心 service-user
- 商品中心 service-product
- 订单中心 service-order
- 支付中心 service-pay
- 日志中心 service-log
每个服务使用 Spring Boot + Spring Cloud Netflix 技术栈搭建,引入 Eureka 做服务注册发现,Ribbon 做客户端负载均衡,Feign 实现服务间调用。同时,用 Zuul 作为网关统一处理请求路由。
关键挑战与做法:
数据一致性问题
拆服务之后,数据也进行了分区。比如订单需要访问用户信息、库存信息,这时候如何保证一致性?我们采用本地事务 + 异步最终一致的方式,结合 RabbitMQ 做异步通知,部分场景使用分布式事务框架 Seata,但发现其在高并发下性能下降明显,后来逐渐改为事件驱动 + 补偿机制。
服务依赖复杂
刚上线时,一个简单的下单操作要经过五六个服务之间的调用链。一旦其中某一个服务故障,整个流程中断。于是我们引入 Hystrix 进行熔断降级,并结合 Sentinel 控制流量。后期替换为 Istio+Envoy 做服务治理。
配置管理混乱
多个服务需要不同配置,维护成本很高。我们引入了 Apollo 配置中心,统一管理多环境的配置文件。
效果:
- 系统可用性提升:单个服务故障不再影响整体
- 新功能迭代更快:各服务可以独立开发、部署
- 团队协作更顺畅:各组负责自己领域的服务
但也暴露了一些新的问题:比如服务治理成本上升、运维压力变大、弹性伸缩能力还不够……
第二阶段:容器化 & Kubernetes 上线
微服务解决了功能上的拆分问题,但部署效率仍然受限。每次部署都要人工登录服务器,执行脚本,容易出错。
我们决定拥抱容器化技术,逐步迁移到 Kubernetes 上运行。
主要动作:
- 所有服务打成 Docker 镜像,镜像通过 CI/CD 流水线自动构建
- 使用 Helm 管理服务的部署模板
- 自建 GitLab + Jenkins + Harbor 组成基础 DevOps 平台
- 在阿里云上部署 Kubernetes 集群,配合 SLB 和阿里云监控告警系统
关键经验分享:
- 镜像瘦身很重要:最开始用的是 JDK 的完整镜像,体积大且启动慢。后来换成了 AdoptOpenJDK 的精简版,再进一步用 JLink 定制自己的最小 JDK 包。
- Kubernetes 排错技巧:kubectl describe pod 是利器!刚开始的时候 Pod 一直 Pending,才发现是没有设置资源配额……教训惨痛。
- 健康检查不能少:给每个服务加上 /actuator/health 或 /health 端点,在 Kubernetes 中配置 liveness/readiness probe,避免服务挂而不自知。
第三阶段:全面转向云原生架构
到了2020年底,我们已经在 K8s 上跑了一年多微服务架构。这时候公司业务进入快速增长期,我们也开始思考如何让系统具备更强的弹性和可维护性。
于是我们决定全面引入云原生理念:
- 引入 Service Mesh,用 Istio 替代传统微服务框架中的熔断、限流、路由等功能
- 数据库主从分离 + 分库分表,读写分离
- 引入 Kafka 消费大量实时数据,如点击流、用户行为日志
- 使用 Prometheus + Grafana 监控整个集群状态
- 引入 ELK 做日志集中收集和分析
- 推广无状态设计,提升扩缩容灵活性
架构亮点:
- API Gateway + Auth 服务统一入口认证
- 每个服务使用 ConfigMap + Secret 做配置注入
- 基于标签做灰度发布、A/B 测试
- 借助阿里云 ACK 快速部署灾备节点
实例分享:
举个例子,我们曾经有一个热点商品秒杀场景,流量暴增几十倍。传统的做法是提前扩容几台服务器,预装应用。但在云原生环境中,我们结合 HPA(Horizontal Pod Autoscaler)实现了动态扩容,Kubernetes 根据 CPU 负载自动扩展实例数量。秒杀结束后,实例数又自动回收,极大节省了计算资源。
效果总结 · 架构升级后的变化
系统稳定性显著增强
- 服务异常对整体影响有限
- 部署失败不影响线上服务
- 有了完善的监控告警体系
研发效率提升
- 团队可以分工明确、快速迭代
- 新服务上线周期从一周缩短到半天内完成
成本控制更好
- 按需扩容,无需长期保留空闲服务器
- 日常运维自动化程度高,减少人力投入
架构更具前瞻性
- 支持灰度发布、A/B 测试等高级特性
- 为未来 AI 能力接入预留了足够空间
经验分享 · 给读者的几点建议
1. 架构演进没有银弹
我始终相信一句话:“没有最好的架构,只有最适合当前业务阶段的架构。”我们当年在选择是否拆服务时纠结了很久,直到业务量逼着我们必须做出改变。
所以如果你现在还在犹豫是否该拆微服务,请先问自己一个问题:
当前架构是否还能支撑未来6个月的增长?如果答案是否定的,那就该动了。
2. 不要盲目追求技术潮流
我见过太多团队为了“先进”而引入各种新技术,结果连最基本的 CI/CD 都没跑通。比如我们当时就曾被 Istio 的复杂性折磨过一段时间,学习曲线陡峭,初期调试成本高。
建议:
- 先建立好基本的 DevOps 和可观测性能力
- 循序渐进引入新技术,确保团队能驾驭
- 技术栈不宜过多,保持简单可控
3. 数据库永远是最难搞的部分
无论是分库分表、读写分离还是迁移,数据库总是最容易拖后腿的地方。我们当年拆服务最大的阻力就是“数据怎么拆?”“订单跨库怎么办?”
建议:
- 提前做好领域模型设计
- 善用数据库中间件(如 MyCat)
- 对于核心数据,考虑 CQRS + Event Sourcing 架构
4. 重视可观测性建设
微服务越多,系统越复杂,就越容易成为“黑盒子”。如果没有足够的日志、监控、追踪手段,排查问题会非常痛苦。
我们用了以下工具组合:
- Log:ELK(ElasticSearch + Logstash + Kibana)
- Metrics:Prometheus + Grafana
- Tracing:SkyWalking(也有 Zipkin、Jaeger 可选)
它们帮助我们快速定位问题,甚至能在用户报障之前就发现隐患。
5. 人比架构更重要
不管技术多么先进,团队的执行力才是关键。我在带团队时深刻体会到:
- 架构师不仅要懂技术,还要懂人心,知道如何推动团队落地
- 工程文化至关重要,定期 Code Review、文档沉淀、技术分享会都是加分项
- 建立责任制和复盘机制,每次出事后一定要做 Postmortem,防止重复踩坑
结语 · 不是一场终点,而是起点

回望这几年的技术演进,我最大的感触是:架构不是一个静态的设计图,而是一个持续优化的过程。
从一开始只能支持几百个并发的单体应用,到现在可以在高峰期扛住上万 QPS 的云原生系统,这条路走得不容易,但也收获满满。
今天写这篇文章,既是对自己职业生涯的一个小结,也是希望能给正在或者准备踏上架构升级之路的你一点启发。
如果你也在做类似的事情,欢迎留言交流,我们一起探索更好的架构之道。
——By 一位还在写代码的架构师

评论 0