【SpringCloud系列01】从单体到微服务:架构演进与SpringCloud全景图


个人主页:夏天拐跑了西瓜
专栏传送门:《大模型应用开发》、《Spring 生态全家桶体系化实战》
学习方向:Java 后端|AI‑Agent 大模型应用开发爱好者
⭐人生格言:路虽远,行则将至


封面图

本文是SpringCloud系列第一篇,带你搞懂微服务是什么、为什么要用微服务,以及SpringCloud全家桶都有哪些组件。文末附高频面试题。


一、为什么需要微服务?

作为Java开发者,相信你或多或少都遇到过这样的场景:

  • 项目刚上线时功能简单,一个war包打天下,部署快、改起来爽
  • 业务迭代半年后,模块越来越多,代码几十万行,改一行代码心惊胆战
  • 团队从3个人扩到10个人,大家都在同一个工程里提交代码,冲突不断
  • 大促期间想给订单模块加机器,结果只能整个应用一起扩容,浪费资源
  • 某个边缘功能出了OOM,整个系统跟着挂

如果你也遇到过以上任何一个问题,说明项目已经到了该考虑微服务的时候。

这篇文章不着急写代码,先从架构演进的历史聊起,搞清楚微服务的来龙去脉。


在这里插入图片描述

二、架构演进的三个阶段

软件架构不是银弹,而是随着业务规模逐步演化的。从互联网发展至今,后端架构大致经历了三个阶段:

2.1 单体架构(Monolithic)

什么是单体架构?

所有功能模块打包在一个工程里,最终生成一个jar或war包部署运行。比如一个电商项目,用户、商品、订单、支付、后台管理全写在一个项目里。

我早年参与过一个网约车项目,最开始乘客端、司机端、订单、消息、地图全在一个工程里,启动一次要3分钟,改个小功能也要全量部署。

单体架构的优点:

  • 开发简单,IDE跑起来就完事
  • 测试方便,本地启动就能调
  • 部署容易,一个包扔到Tomcat就行
  • 适合项目初期快速试错、MVP验证

单体架构的痛点(重点,面试常问):

痛点具体表现
复杂性高代码量从几万涨到几十万行,模块边界模糊,新人上手要几周
技术债务“不坏不修”,老代码没人敢动,人员流动后更是雪上加霜
部署困难改一行文案也要全量打包部署,上线窗口越缩越长,形成恶性循环
可靠性差一个小功能OOM,整个进程挂掉,所有功能都不能用
扩展受限订单模块需要扩容,但只能整个应用一起加机器,资源浪费
阻碍创新想把Spring MVC换成WebFlux?几十万行代码改不起;想试试Go写某个高性能模块?门都没有

一句话总结:小项目用单体真香,大项目用单体要命。


2.2 面向服务架构(SOA)

为了解决单体的问题,业界提出了SOA(Service-Oriented Architecture,面向服务架构)。

SOA的核心思想是:把系统拆分成多个服务,服务之间通过网络调用,用服务编排来实现业务流程。

SOA通常会引入ESB(企业服务总线)来做服务之间的通信和转换,常见的ESB有WebService、Dubbo(早期版本)等。

但SOA有个问题:它更多是传统企业级的架构思路,ESB本身很重,服务拆分粒度也比较粗,很多时候拆完发现还是个"大单体"。

可以说,SOA提出了很好的理念,但落地成本高,没有在互联网公司大规模流行开来。


2.3 微服务架构(Microservices)

微服务是SOA思想的一种更轻量、更彻底的实践。

微服务架构 = 80%的SOA服务思想 + 100%的组件化架构思想

Martin Fowler在2014年发表的《Microservices》一文中,给微服务下了这样的定义(大意):

微服务是一种架构风格,将单个应用程序开发为一组小型、独立的服务,每个服务运行在自己的进程中,服务间通过轻量级机制(通常是HTTP REST API)通信。这些服务围绕业务能力构建,通过自动化部署机制独立部署,可以用不同的编程语言编写,使用不同的数据存储技术。

打个通俗的比方:

  • 单体架构像一个大锅饭,所有人吃一锅菜,咸淡没法调
  • 微服务像自助餐,每个菜独立盛盘,想吃啥拿啥,凉了单独换

网上还有个很形象的"分封制"类比:

  • 服从天子命令 → 接受注册中心统一管理
  • 镇守疆土 → 各自负责一块业务
  • 随从作战 → 服务之间相互调用
  • 交纳贡献 → 共同分担系统流量

三、微服务的核心特性

一个真正的微服务架构,应该具备以下特点:

  1. 服务独立进程:每个服务跑在自己的JVM/容器里,互不影响
  2. 围绕业务拆分:按领域模型或业务能力拆分,不是按技术层拆分
  3. 轻量级通信:服务间用HTTP/REST、gRPC、消息队列等通信,不绑定语言
  4. 独立部署:每个服务可以单独上线,不依赖其他服务发布节奏
  5. 技术栈自由:Java写业务、Go写网关、Python写数据分析,各取所长
  6. 数据去中心化:每个服务管理自己的数据库,不共享数据库
  7. 自动化运维:服务多了必须靠自动化,CI/CD、容器化是标配

四、微服务的优缺点

4.1 优点

  1. 独立部署,低耦合:改订单服务不影响用户服务,上线风险小
  2. 易于开发维护:每个服务代码量少,业务聚焦,新人上手快
  3. 启动速度快:一个服务可能就几千行代码,启动几秒钟
  4. 按需伸缩:大促时只给订单、商品服务加实例,省成本
  5. 技术栈灵活:可以根据场景选最合适的技术,比如用AI推荐服务用Python
  6. 容错性好:一个服务挂了不会拖垮整个系统(配合熔断降级)
  7. 团队分工明确:两个披萨团队(6-10人)负责一个服务,职责清晰
  8. 代码复用:基础服务可以通过接口被多个上层服务复用

4.2 缺点(没有银弹)

微服务不是免费的午餐,它解决了单体的问题,但也引入了新的复杂度:

  1. 分布式系统复杂性

    • 网络是不可靠的(延迟、丢包、分区)
    • 服务调用链变长,排查问题困难
    • 需要处理超时、重试、幂等等问题
  2. 分布式事务难题

    • 每个服务有自己的数据库,跨服务事务不能用本地事务
    • 解决方案:2PC、TCC、本地消息表、Saga、最大努力通知
    • 业界主流是柔性事务 + 最终一致性(BASE理论)

    面试题:什么是BASE理论?

    • Basically Available(基本可用):故障时允许部分功能不可用,保证核心功能
    • Soft state(软状态):允许数据存在中间状态
    • Eventually consistent(最终一致性):一段时间后数据达到一致,不需要实时一致
  3. 接口调整成本高

    • 改一个服务的接口,所有调用方都要跟着改
    • 需要做好API版本管理,推荐用Swagger/YApi管理文档
  4. 测试难度陡增

    • 单元测试不够了,还要写集成测试、契约测试
    • 测一个功能可能要启动好几个服务
  5. 运维复杂度指数级上升

    • 几十个服务,配置管理、监控、告警、日志收集全是挑战
    • 需要一整套微服务治理平台
  6. 重复劳动

    • 每个服务都要有类似的工具类、配置
    • 多语言场景下,Java的common-jar没法给Go用

所以,不要为了微服务而微服务。 团队小、业务简单的时候,单体可能是更好的选择。


五、微服务设计四原则

  1. 单一职责原则
    一个服务只做一件事,把它做好。服务边界要清晰,不要把不相关的功能塞进来。

  2. 服务自治原则
    每个服务可以独立开发、测试、构建、部署、运行,对其他服务最小化依赖。

  3. 轻量级通信原则
    服务间调用要跨语言、跨平台,REST、gRPC、AMQP都是好选择,不要用太重的协议。

  4. 粒度适中原则
    没有标准答案,根据团队和业务情况调整。拆太细了调用链太长,拆太粗了又回到单体。随着业务演进逐步拆分,不要上来就追求完美。

我的经验:一开始宁粗勿细,粗了后面好拆,拆细了再合就麻烦了。


六、微服务生态全景

微服务不只是把代码拆开就完事了,它需要一整套基础设施支撑:

┌─────────────────────────────────────────────────────────┐
│                      客户端/前端                          │
└─────────────────────────────────────────────────────────┘
                              │
┌─────────────────────────────────────────────────────────┐
│                    服务网关 Gateway                       │
│        路由转发、鉴权、限流、灰度发布、A/B测试              │
└─────────────────────────────────────────────────────────┘
                              │
┌──────────┬──────────┬──────────┬──────────┬──────────┐
│  用户服务 │  商品服务 │  订单服务 │  支付服务 │  搜索服务 │
└──────────┴──────────┴──────────┴──────────┴──────────┘
       │            │            │            │
┌─────────────────────────────────────────────────────────┐
│  注册中心  │  配置中心  │  熔断限流  │  链路追踪  │  监控告警 │
└─────────────────────────────────────────────────────────┘
       │            │            │            │
┌─────────────────────────────────────────────────────────┐
│          消息队列  │  分布式事务  │  CI/CD  │  容器编排    │
└─────────────────────────────────────────────────────────┘

核心组件清单:

组件作用常见选型
服务注册发现服务地址登记与查询Nacos、Eureka、Consul、Zookeeper
负载均衡请求分发到多个实例Ribbon、LoadBalancer、Nginx
服务网关统一入口、鉴权、路由SpringCloud Gateway、Zuul、Kong
配置中心集中管理配置、热更新Nacos、Apollo、Spring Cloud Config
熔断限流防止服务雪崩、保护系统Sentinel、Hystrix、Resilience4j
远程调用服务间HTTP/RPC调用OpenFeign、Dubbo、RestTemplate
链路追踪排查分布式调用问题Sleuth+Zipkin、SkyWalking、Jaeger
消息队列异步解耦、削峰填谷RocketMQ、Kafka、RabbitMQ
分布式事务跨服务数据一致性Seata、本地消息表、Saga
监控告警指标监控、日志聚合Prometheus+Grafana、Admin、ELK

七、SpringCloud是什么?

聊完了微服务概念,我们终于可以进入正题了。

SpringCloud是Spring官方推出的微服务治理框架集合,它不是一个具体的框架,而是一系列框架的有机组合,利用Spring Boot的开发便利性,简化了分布式系统基础设施的开发。

简单说:SpringBoot帮你快速构建单个服务,SpringCloud帮你治理一堆服务。

7.1 SpringCloud vs Dubbo

这是面试经典题,直接给对比表:

对比维度SpringCloudDubbo
背景Netflix/Alibaba/Spring社区阿里开源,后捐给Apache
通信方式HTTP REST(Feign/RestTemplate)自有RPC协议(TCP长连接)
性能略低(HTTP+JSON)较高(二进制序列化+长连接)
功能完整度全家桶,覆盖微服务各方面主要专注服务调用和治理
生态丰富,与Spring无缝集成相对独立,需要自己整合其他组件
学习成本稍高(组件多)较低
适用场景快速迭代的互联网业务、多语言高性能、对延迟敏感的内部系统

现在更多是两者结合:用SpringCloud Alibaba生态,里面包含Dubbo作为RPC选项。

7.2 SpringCloud版本说明

SpringCloud的版本命名比较有意思,它不用数字版本号,而是用伦敦地铁站名按字母顺序命名:

  • Angel(最早版本)
  • Brixton
  • Camden
  • Dalston
  • Edgware
  • Finchley
  • Greenwich
  • Hoxton(SpringBoot 2.2.x/2.3.x,我们这个系列用这个版本)
  • Ilford(后来改名为2020.0.x,开始日历化版本)

从2020年开始,SpringCloud改用了日历版本号,格式为 YYYY.RELEASE,比如:

  • 2020.0.x(Ilford)
  • 2021.0.x(Jubilee)
  • 2022.0.x(Kilburn)
  • 2023.0.x(Leyton)
  • 2024.0.x 及更新版本

版本对应关系很重要,乱配版本会出各种奇奇怪怪的问题:

SpringCloud版本SpringBoot版本备注
Hoxton.SR32.2.x本系列使用,Netflix组件还在
2020.0.x2.4.x+移除大部分Netflix组件
2021.0.x2.6.x+-
2022.0.x3.0.x+支持SpringBoot 3,JDK17最低
2023.0.x3.2.x+-

💡 新手建议:不要上来就追最新版本,先从Hoxton + SpringBoot 2.2.x把组件原理搞懂,再升级新版本也不迟。

7.3 SpringCloud的"朝代"更替

SpringCloud发展到现在,经历了几个阶段:

第一代:SpringCloud Netflix(2015-2020)

  • 核心组件:Eureka、Ribbon、Hystrix、Zuul 1.x、Feign、Archaius
  • 问题:Netflix在2018年底宣布这些项目进入维护模式,不再开发新功能
  • Hystrix更早就停止了开发,Zuul 2.x一直跳票

第二代:SpringCloud Alibaba(2018至今,国内主流)

  • 核心组件:Nacos(注册+配置)、Sentinel(熔断限流)、Seata(分布式事务)
  • 额外组件:RocketMQ、Dubbo、OSS等
  • 优点:国内社区活跃、中文文档好、功能更强、经过阿里大流量验证
  • 现在国内互联网公司Java微服务,基本都是SpringCloud Alibaba那一套

第三代:SpringCloud官方原生(2020至今)

  • 用SpringCloud LoadBalancer替代Ribbon
  • 用SpringCloud Gateway替代Zuul
  • 用Spring Cloud Circuit Breaker统一熔断抽象(支持Resilience4J等)
  • 配置中心可以用Spring Cloud Consul或第三方

八、SpringCloud Alibaba核心组件

既然国内主流是Alibaba这套,我们有必要先了解下它的核心组件(后续会有专门文章详细讲):

组件作用替代Netflix的谁
Nacos服务注册发现 + 配置中心Eureka + Config
Sentinel流量控制、熔断降级、系统保护Hystrix
Seata分布式事务解决方案无对应
RocketMQ分布式消息队列无对应
Dubbo高性能RPC通信Feign(可选替代)
SpringCloud Stream消息驱动抽象层-

另外还有一些阿里云商业组件(ACM、OSS、SchedulerX、SMS等),个人学习可以不用管。


九、本系列学习路线

这个系列我们会从Netflix经典组件讲起,再过渡到Alibaba主流方案,最后做面试题汇总。打好基础再学新东西才稳。

学习顺序建议:

1. 微服务基础概念(这篇)
2. Eureka 注册中心 → 理解服务注册发现原理
3. RestTemplate + Ribbon → 服务调用与负载均衡
4. OpenFeign → 声明式调用
5. Hystrix → 熔断降级(理解原理,现在多用Sentinel)
6. Zuul/Gateway → 微服务网关
7. Config → 配置中心(理解思路,现在多用Nacos)
8. Sleuth + Zipkin → 链路追踪
9. SpringBoot Admin → 监控
10. Nacos、Sentinel、Seata(重点,面试高频)
11. 面试题汇总

十、高频面试题

1. 什么是微服务?优缺点是什么?

参考答案见上文第四部分,重点答出独立部署、低耦合、技术栈自由,以及分布式复杂性、事务、运维等缺点。

2. 微服务架构有哪些核心组件?

注册中心、配置中心、网关、负载均衡、熔断限流、远程调用、链路追踪、消息队列、监控等,结合表格回答。

3. SpringCloud和Dubbo有什么区别?

从通信协议(HTTP vs RPC)、性能、功能完整度、生态等角度对比,现在可以说两者不是替代关系,Dubbo可以整合到SpringCloud中使用。

4. SpringCloud和SpringBoot是什么关系?

SpringBoot专注快速构建单个应用,SpringCloud专注治理分布式服务,SpringCloud基于SpringBoot构建。

5. 什么是CAP定理?什么是BASE理论?

CAP:一致性、可用性、分区容错性,分布式系统只能同时满足两个;BASE是对AP的扩展,基本可用、软状态、最终一致性,微服务分布式事务常用。

6. 蓝绿部署和灰度发布有什么区别?

  • 蓝绿部署:准备两套相同环境,新版本部署在绿环境,测试OK后流量一次性切过去,蓝环境留作回滚
  • 灰度发布(金丝雀发布):先切一小部分流量到新版本,观察没问题再逐步放大,直到全量
  • 核心区别:蓝绿是一次性切换,灰度是渐进式迁移

7. 服务拆分会遇到什么问题?怎么解决?

分布式事务(Seata/最终一致性)、服务发现(Nacos)、网关(Gateway)、链路追踪(Sleuth/SkyWalking)、运维复杂度(Docker/K8s/CI/CD)。


总结

这篇文章我们讲了:

  • 架构从单体→SOA→微服务的演进过程
  • 微服务的特性、优缺点和设计原则
  • 微服务生态的核心组件
  • SpringCloud是什么、版本怎么选
  • Netflix和Alibaba两朝换代
  • 本系列学习路线

微服务不是银弹,不要为了拆而拆。但作为Java后端工程师,掌握SpringCloud生态是必备技能,无论是日常开发还是跳槽面试都用得上。

下一篇我们开始动手,搭建第一个Eureka注册中心,并把服务注册上去。


本系列代码会同步更新到GitHub,欢迎Star关注。如果文章对你有帮助,点个赞和关注就是对我最大的鼓励~

下一篇:【SpringCloud系列02】Eureka注册中心:单机与高可用集群搭建实战

更多推荐