从单体到云原生:我在后端架构升级中的实战与思考
开篇:为什么我决定聊聊这个话题

大概是在2018年,我参与了一个电商项目的开发。那个时候我们用的还是传统的MVC架构,把所有的业务逻辑都写在一个Spring Boot项目里,数据库也是典型的MySQL主从架构。系统上线初期表现还不错,接口响应快、部署简单,团队协作起来也顺手。但随着用户增长和功能越来越多,问题开始接踵而至。
那几年,我亲历了整个系统的架构演变,从最初的单体架构,到微服务化改造,再到后来全面拥抱云原生。这个过程其实并不轻松,中间踩过不少坑,也做过很多错误的判断和选择。不过正因如此,我才有了更多沉淀和反思的机会。
今天想跟你聊一聊这段经历,希望你能从中看到一些真实的成长轨迹,也能少走一点弯路。
那个让团队抓狂的单体时代

我们的系统最开始部署在两台阿里云ECS上,前面一个Nginx做负载均衡,后端是一个打包好的WAR包,跑在Tomcat上。刚开始用户不多的时候,这套方案完全没问题,接口响应时间都在50ms以内。
但好景不长,随着促销活动越来越多,订单量激增。我们每天都要处理数万笔交易,同时还要面对高并发的访问请求。
第一个大问题就是部署效率低。当时每次上线都需要把代码编译成JAR包,再通过脚本上传到服务器并重启应用。一旦有紧急修复bug的情况,往往需要停机几分钟才能更新完成。这在电商场景下几乎不可接受。
第二个是模块耦合严重。用户中心、商品中心、订单中心、库存中心……这些看似独立的功能都被揉在一个项目里面,修改一处可能会影响到另一处的功能。我记得有一次只是改了个优惠券的计算逻辑,结果把支付流程搞崩了,真是“牵一发而动全身”。
第三个问题就是性能瓶颈。由于所有服务都在同一个进程中运行,数据库连接池有限,缓存机制也没有很好地拆分,经常会出现某个功能调用量太大导致整个系统变慢甚至超时。我们尝试过扩容,但效果并不明显,因为本质上并没有解决资源争用的问题。
最崩溃的一次,是双十一大促前的一个晚上,系统在压测时突然卡死。我们查日志发现数据库连接池被打满了,Redis也有多个线程阻塞。那一晚我和两位同事一边盯监控一边改代码,最后硬是临时调整了几个核心参数才撑住。
那时候我就在想:这真的能长久吗?
架构演进的第一步:拆!拆!拆!
经过几次大的事故之后,我们终于意识到必须重构系统架构。我们做了几件事:
1. 模块解耦 + 微服务化
第一步是拆服务。我们用了DDD(领域驱动设计)的方法,重新梳理了各个模块之间的边界。比如:
- 用户中心被拆成了独立的服务,负责登录注册、权限校验
- 商品服务专注于SKU管理、分类和搜索
- 订单服务则只处理下单、支付、售后相关的流程
- 还有消息中心、优惠券中心、支付网关……
每个服务都有自己的数据库表结构,使用Spring Cloud + Feign做内部通信,并通过Ribbon实现服务发现和负载均衡。刚开始大家还不太习惯这种模式,但慢慢地就尝到了甜头。
举个例子,在没有拆之前,如果用户服务挂了,整个系统都会受到影响;而拆开之后,即使某个子服务出问题,其他部分依然可以正常运行。
2. 引入API网关
为了统一入口,我们加了一层Spring Cloud Gateway作为网关。网关的主要职责包括:
- 路由转发(根据路径匹配对应的服务)
- 鉴权(Token验证、权限拦截)
- 限流熔断(防止某个服务被流量压垮)
- 日志记录
这一层的存在大大简化了后续的扩展性。比如我们要做一个风控插件,直接在网关做就可以了,不需要改动每个业务服务。
3. 统一日志 & 监控体系
以前我们在排查线上问题时,常常要登录每一台机器去查看日志文件。后来我们引入了ELK栈(Elasticsearch + Logstash + Kibana),配合Filebeat来采集日志。
此外,还接入了Prometheus+Grafana进行指标监控,对每个服务的TPS、RT、CPU内存等指标做了实时看板。这对后续的性能优化帮助非常大。
上云?不如说我们“拥抱”了云原生
虽然我们的微服务架构已经初具规模,但运维依然是个痛点。特别是在双十一期间,手动扩缩容成本太高,而且效率低下。
于是我们开始调研是否可以把整个系统迁移到Kubernetes集群上。这一步其实是个分水岭,因为它不仅是一次部署方式的改变,更是架构思维上的跃迁。
Kubernetes带来的好处
我们最终选择了阿里云ACK(Kubernetes服务)。迁移过程中主要做了以下几个方面的工作:
- 把原来的每个Spring Boot应用打包为Docker镜像
- 使用Helm Chart管理应用配置(如环境变量、副本数量等)
- 用Service暴露服务内部通信,配合Ingress做外部路由
- 用ConfigMap存储配置文件,避免硬编码
- 使用HPA自动扩缩容策略,根据CPU或请求量动态调节Pod数量
这个过程最大的转变,是我们开始从“关注主机”转变为“关注服务”。以前我们会关心某台ECS是否还在跑,现在更关心的是某个Deployment的状态是否Ready。
数据库和中间件的变化
在这个阶段我们也对数据库做了一些优化,主要是以下几点:
- 每个服务都有独立的数据库实例,减少跨库查询
- 对核心数据做了分库分表(比如订单按用户ID哈希分片)
- Redis做了集群化部署,提升稳定性
- 使用RocketMQ代替本地事务消息,确保最终一致性
值得一提的是,这些变化并不是一开始就设计好的,而是随着业务发展逐步迭代出来的。比如一开始我们以为用一张大表就能搞定,结果后来数据量上来之后根本扛不住查询压力,只能临时加上分区索引、读写分离、最后不得已才分库分表。
所以我的建议是:数据库架构的设计一定不能滞后于业务增长,否则后期代价会非常高。
真正体会到“云原生”的力量
真正让我觉得“值了”的事情,是在一次突发的线上故障中。
当时我们刚做完秒杀活动上线,流量突然暴增了五倍。由于我们已经启用了HPA策略,Kubernetes自动拉起了数十个Pod来处理请求。再加上Redis Cluster的自动主从切换,以及RocketMQ的削峰填谷能力,整个系统居然稳住了!
那次事件让我真切感受到云原生所带来的弹性和韧性。如果还是以前那种单机部署模式,估计早就炸了。
更重要的是,我们现在可以在CI/CD平台上一键发布新版本,无需人工介入。我们用了Jenkins + GitLab CI做流水线,结合阿里云容器镜像仓库,实现了自动构建、自动测试、自动部署。
一些经验教训和小故事
在这几年的架构演进中,我也积累了不少心得,有些是踩过的坑,有些是偶然的顿悟。
1. 别急着拆服务,先搞清楚业务边界
我见过很多团队还没弄清楚业务是怎么流转的,就开始盲目地拆服务。结果拆完之后又发现某些业务需要频繁调用另一个服务,导致大量不必要的网络通信。
所以在做微服务之前,一定要花时间梳理清楚你的领域模型和上下文边界。DDD确实不是银弹,但在划分服务边界的阶段特别有用。
2. 接口设计比你想的更重要
刚开始我们没太在意接口的设计,很多时候都是临时写几个RESTful接口,传点JSON数据就完了。结果后面维护越来越麻烦,比如字段名不一致、返回格式混乱、状态码随意……
后来我们规范了接口协议,定义了统一的成功失败结构体,加了全局异常处理器,并且用Swagger UI自动生成文档。这些工作虽然看起来“不够技术”,但对整个团队的协同效率影响极大。
3. 监控是你的眼睛
有一次我们把一个服务的QPS限制配错了,结果导致下游服务疯狂报错。如果没有APM系统和链路追踪工具(如SkyWalking),我们可能要花好几个小时才能定位到问题源头。
我建议你至少要做到这几个层面的监控:
- 服务本身的指标(CPU、内存、线程、GC次数)
- 接口级别的延迟和成功率(可以用Micrometer + Prometheus)
- 分布式链路追踪(Zipkin或SkyWalking)
4. 云原生不是终点,而是起点
别指望一上Kubernetes就能解决所有问题。真正的云原生不仅仅是用Docker和K8s部署,更重要的是具备弹性、自动化、可观测性、松耦合等理念。
比如你可以考虑使用Service Mesh(如Istio)来做更细粒度的服务治理,或者引入Serverless架构来应对突发流量。
最后的话:给后端工程师的几点建议
如果你也在经历或准备进行类似的技术升级,我有几点建议想送给你:
✅ 保持架构的灵活性
架构一定是服务于业务的,不要为了“时髦”而过度设计。哪怕你现在是一个简单的Web应用,也可以预留出未来微服务化的可能性,比如提前定义好清晰的接口边界和数据模型。
✅ 多动手,少争论
有时候我们在开会讨论架构的时候,往往陷入“理论上谁更好”的争论中。与其纸上谈兵,不如找个沙盒环境试试。比如你可以用Minikube快速搭建一个小集群,实际跑一下看看性能差异。
✅ 学会抽象与封装
后端开发不仅是写CRUD接口,更重要的是如何把复杂的业务逻辑抽象成可复用的组件。比如我现在写一个优惠券系统,一定会把它设计成可以支持多种规则引擎的模块,而不是每次都重复开发。
✅ 关注性能与可用性
一个好的架构不仅要能支撑日常流量,更要在极端情况下表现出色。比如在分布式系统中,你要理解CAP定理,知道在高可用和一致性之间如何取舍;在数据库设计中,你要明白什么情况下需要牺牲范式来换取查询性能。
✅ 和运维、前端多沟通
后端不是一个孤立的世界。很多时候我们写的接口好不好,直接影响前端渲染速度。而运维同学对生产环境的敏感程度远高于我们。多站在对方角度看问题,你会发现很多意想不到的优化空间。
结语:架构是不断演进的艺术
如今,我已经离开那个电商项目多年,但它在我职业生涯中的印记却一直都在。它教会我如何面对复杂系统的挑战,也让我明白了“稳定”这两个字背后的重量。
从最初的那个单体应用,到如今的云原生架构,我们走过了不少弯路,但也收获了无数宝贵的实践经验。我始终相信,好的架构不是一开始设计出来的,而是在一次次问题与迭代中打磨出来的。
如果你也正在经历类似的转型过程,我想对你说一句话:
别怕折腾,别怕犯错,架构的演进从来都不是一场短跑,而是一场马拉松。
愿你在架构之路上越走越远,写出更优雅、更稳定的后端系统。

评论 0