返回资源中心

微服务架构入门:从单体到微服务

课件一图讲解微服务架构小红学堂更新于 2026年8月28日280 次阅读

配合架构图一起看。我们用一个电商系统(包含商品、订单、搜索、推荐)作为例子,从最简单的做法出发,一步步看着它"长大",你就会自然明白:微服务是什么、为什么会出现、它对开发又意味着什么。 整个系统的成长,分成三个阶段(也就是架构图从上到下的三行):

image

阶段一句话适合的场景
① 单体应用所有功能打成一个包项目起步、用户少
② 集群同一个包复制好几份用户变多,单台扛不住
③ 微服务按功能拆成多个独立的小系统团队变大、业务变复杂

一句话先记住:架构不是越复杂越好,而是被业务"逼"出来的。


第一阶段:单体应用(Monolith)

对应架构图最上方那一行。

用户 ──▶ 前端(页面渲染) ──▶ 后端(商品/订单/搜索/推荐) ──▶ 数据库

它长什么样

  • 一个前端负责显示页面;
  • 一个后端程序,里面装着所有功能:商品、订单、搜索、推荐全在一起;
  • 一个数据库存所有数据。

打个比方:这就像一家夫妻店,老板一个人又收银、又上货、又记账,所有事一个人全包。

它的优点

  • ✅ 简单:一个项目、一份代码,打一个包就能上线。
  • ✅ 好调试:所有代码在一起,从头跟到尾很方便。
  • ✅ 开发快:不需要一堆额外的"配套设施"。

单体不是落后。小项目用单体,才是正确选择,不要一上来就嫌它"low"。

它的痛点(业务变大后开始难受)

  1. 改一行代码,整个系统都要重新部署——只改"推荐","商品""订单"也得跟着停机更新。
  2. 一处出 Bug,可能拖垮整个系统——"搜索"写了个死循环占满 CPU,"下单"也跟着崩。
  3. 没法只给"忙"的部分加资源——大促时只有"订单"压力大,但你只能整个一起加机器。
  4. 代码越来越大,团队互相踩脚——十几个人改同一个项目,天天冲突。

这些痛点,逼着我们走向下一阶段。


第二阶段:集群(Cluster)

对应架构图中间那一行,注意多了一个 nginx,后端也"叠"成了好几个。

用户 ──▶ 前端 ──▶ nginx(负载均衡) ──▶ 后端 × N(同一份代码的多个副本) ──▶ 数据库

要解决的问题:一台机器扛不住了

用户变多,一台服务器忙不过来。最直接的办法:把一模一样的后端复制几份,多开几台机器一起干活。 架构图里那几个"叠在一起的后端"框,就是同一份代码部署的多个副本。

那请求该发给哪一台?——这就是 nginx 干的事

nginx(负载均衡)就像银行大厅里的叫号员:后面开了 5 个窗口(5 个后端副本),客户(请求)来了,叫号员就把他分给当前最空的窗口,让每个窗口压力均摊。

"负载均衡"翻成大白话:把活儿尽量平均分给后面的多台机器,别让一台累死、其他闲死。

集群的好处

  • ✅ 能扛更多用户:不够就再加机器(这叫横向扩展)。
  • ✅ 更稳:挂了一台,nginx 自动把请求发给还活着的机器,用户基本无感。

集群没解决的问题(关键)

集群只是把"同一个夫妻店"开了好几家分店,每家分店还是什么都干。所以单体的痛点依然在:

  • 改一行代码,所有副本还是要一起重新部署;
  • "搜索"出问题,照样可能拖垮整台机器上的"订单";
  • "订单"压力大时,你只能把整个大包复制好几份,没法单独只扩"订单"。

于是我们想:能不能干脆把不同功能拆开? —— 这就是微服务。


第三阶段:微服务(Microservices)

对应架构图第三行 + 下半部分,元素最多。

核心思想(一句话)

把原来挤在一个大项目里的"商品、订单、搜索"……每个功能拆成一个独立的小程序,各自开发、各自部署、各自用自己的数据库。

还用开店打比方:从"什么都管的夫妻店",升级成"专业分工的连锁商场"——有专门管商品的部门、专门管订单的部门、专门管搜索的部门,各干各的,谁也不影响谁。

每一个这样的小程序,就叫一个服务(Service)

微服务好在哪

  • 独立部署:改了"推荐",只重新部署推荐服务,其他服务照常运行。
  • 故障隔离:"搜索"崩了,最多搜索用不了,"下单"还能正常进行。
  • 按需扩展:大促时只给"订单服务"多开几台,不浪费资源在闲着的服务上。
  • 团队解耦:商品组、订单组各管各的代码仓库,互不干扰。

代价:多了一堆"配套设施"

用户 ─▶ 前端 ─▶ nginx ─▶ 【网关 gateway】 ─▶ 商品服务 ─▶ 商品库
                              │              订单服务 ─▶ 订单库
                              │              搜索服务 ─▶ 搜索库
                              │
                       【注册中心】(nacos / eureka / zookeeper)

很多人以为"微服务 = 把代码拆开就完事了"。恰恰相反,拆开只是第一步,真正的工作量在下面这些配套设施上。 这也是为什么微服务对开发的要求更高。下面逐个认识它们。


1️⃣ 网关 Gateway —— 系统的大门 / 总前台

对应图中 gateway 网关

服务被拆成好多个后,前端犯难了:"我到底该调哪个服务?地址那么多怎么记?"于是在所有服务前面立一个统一入口,就是网关。

网关就像公司大楼的前台 + 保安:所有访客(请求)都先到前台,前台再告诉你"找商品去 3 楼,找订单去 5 楼",并帮你带路。

网关通常负责:

  • 统一入口:前端只需知道网关一个地址,不用记一堆服务地址;
  • 路由转发:根据请求路径,决定转给商品服务还是订单服务;
  • 统一鉴权:在大门口先检查"你有没有登录、有没有权限"(后面专门讲);
  • 还能做限流、日志等。

2️⃣ 注册中心 —— 服务的通讯录 / 大众点评

对应图中 注册中心,常用软件:nacos / eureka / zookeeper

服务那么多、数量还随时在变(大促时订单服务从 2 台变 10 台),网关怎么知道每个服务现在有哪些机器、地址是多少?答案:搞一个注册中心,让所有服务"上线来登记,下线来注销"。

注册中心就像一个实时更新的通讯录

  • 服务一启动,就主动告诉注册中心:"我是订单服务,地址是 192.168.x.x,我上线了!"(服务注册
  • 网关想找"订单服务"时,来注册中心查:"订单服务现在有哪几台可用?"(服务发现
  • 服务挂了,注册中心把它从名单划掉,不再给它发请求。

nacoseurekazookeeper 都是常用的注册中心软件,作用一样,选一个用即可,新手记住 nacos 最常用就行。

3️⃣ 服务之间怎么互相调用?—— Feign

对应图中"服务调用流程":请求方 ─ Feign ─ 响应方

业务经常需要跨服务协作。比如"下单"时,订单服务要去问商品服务:"这个商品还有库存吗?"在单体里这就是一次普通方法调用,现在两个服务在不同机器上,怎么调?这就用 Feign

Feign 让"调用别的服务"像"调用本地方法"一样简单:你只要声明一个接口,写上"我要调订单服务的这个方法",Feign 在底层帮你把它变成一次网络请求,你完全不用自己写复杂的网络代码

订单服务(请求方) ──Feign调用──▶ 商品服务(响应方)
        "请问商品123还有货吗?"
        ◀──────────────────────  "还有,剩 50 件"

一句话:Feign = 让远程调用看起来像本地调用的"翻译官"。

4️⃣ 服务调用出问题怎么办?—— Sentinel 熔断降级

对应图中右下角 Sentinel 熔断降级流程,以及调用图里的 sentinel 标注。

微服务最大的风险是服务之间会互相"传染故障"

订单服务要调商品服务,结果商品服务卡住了(比如数据库慢)。订单服务傻等,请求越积越多,自己也被拖垮;然后调订单服务的服务也跟着垮…… 像多米诺骨牌一样全倒了。这个现象叫 "雪崩"

为了防雪崩,用 Sentinel,它主要做两件事:

  • 熔断(断路):发现"商品服务"老是失败/超时,就暂时不调它了,直接快速返回。

就像家里电路短路,保险丝"啪"地跳闸,先断开这条线,免得烧了整间屋;过一会儿再试着合上看恢复没有。

  • 降级:被熔断后,不让用户对着报错干瞪眼,而是返回一个兜底的、能用的结果

就像奶茶店"芋圆"卖光了,店员说"给您换成同价位的椰果好吗?"——保证你有东西喝,体验不至于崩。

右下角那张流程图,描述的就是 Sentinel 在什么情况下触发熔断、怎么判断要不要降级、过多久尝试恢复的判断逻辑。现在只要记住两个核心:熔断 = 及时断开止损,降级 = 给个兜底结果。

5️⃣ 数据库也要拆 —— 各服务用各自的库

对应图中 商品库 / 订单库 / 搜索库

真正的微服务,连数据库都是分开的

  • 商品服务用商品库,订单服务用订单库,互不直接访问对方的库;
  • 好处:一个库压力大可单独优化/扩容,一个库挂了不连累其他服务;
  • 代价:以前一条 SQL 联表就能查的数据,现在可能要跨服务调用来拼。

原则:谁的数据谁管,别人想要数据,找它要(通过 Feign 调接口),而不是直接连它的库。


微服务对"开发"的真实影响

听起来微服务很好,那代价是什么?这一节回答这个问题。把这几点搞清楚,你才不会盲目崇拜微服务。

影响 1:要做公共 SDK / 公共模块

服务拆开后,很多东西是每个服务都要用的:统一的返回格式、通用工具类、公共实体、错误码、日志规范……如果每个服务各写一套,就会重复又不统一。所以要把这些公共的东西抽成一个公共 SDK(公共依赖包),让所有服务都引用它。

就像连锁店总部统一定制的"员工手册 + 工具箱",每家分店直接拿来用,保证大家做事方式一致。

影响 2:要做统一认证鉴权

单体时代,用户登录一次,信息就在一个程序里随便用。现在服务拆成好几个,"用户登录了没?有没有权限?"每个服务都要知道——总不能让用户在每个服务都登录一遍。所以需要统一认证鉴权

  • 用户在一个地方登录,拿到一张"通行证"(通常是 Token,如 JWT);
  • 之后每次请求都带着这张通行证;
  • 网关在大门口统一校验这张证,通过才放进来;服务之间也认这张证。

就像游乐园的手环:进门验一次票换成手环,之后园内所有项目都认这个手环,不用每个项目重新买票。

影响 3:部署和运维变复杂

  • 单体:1 个包,部署 1 次就好。
  • 微服务:N 个服务,每个都要单独部署、配置、监控,还要管它们之间的网络。

所以微服务几乎离不开这些工具:

  • Docker:把每个服务连同运行环境一起打包成标准"集装箱",到哪都能跑,不再有"我电脑上是好的呀"的问题;
  • Kubernetes(K8s):管理这一堆集装箱,负责自动部署、自动扩容、挂了自动拉起,相当于自动化的"码头调度系统";
  • 配置中心:把各服务配置集中管理(nacos 通常也兼这个活);
  • 监控 / 链路追踪:一个请求横跨好几个服务,出问题要能查出到底卡在哪一环。

总结一句:微服务把"开发的复杂度"降下来了(每个服务变小变简单),却把"运维和协作的复杂度"提上去了。

影响 4:调试和排错变难

单体里点点点就能跟完整个流程;微服务里一个请求可能经过 网关 → 订单服务 → 商品服务 → …… 出问题要在好几个服务的日志里来回找。所以前面说的"链路追踪"才那么重要。


总结:一张表带走

对比项单体应用集群微服务
代码组织全在一个项目全在一个项目(复制多份)按功能拆成多个项目
部署部署 1 个包部署同一个包多份每个服务独立部署
扩展整体扩整体复制扩想扩哪个扩哪个
故障影响一处挂全挂单台挂有备份故障被隔离在单个服务
数据库一个库一个库每个服务独立库
配套设施几乎不需要+ 负载均衡(nginx)+ 网关 + 注册中心 + Feign + Sentinel + 统一认证 + Docker/K8s
开发难度低~中高(配套多)
适合谁小项目/起步用户变多业务复杂、团队大

三句话收尾

  1. 架构是演进出来的,不是一开始就上微服务。 小项目用单体,别过度设计。
  2. 微服务的核心是"拆",但难点全在"拆完之后怎么协作"——网关、注册中心、调用、熔断、认证、部署,缺一不可。
  3. 没有最好的架构,只有最适合当前业务规模的架构。