一、什么是微服务
1. 传统单体架构(对比理解)
一个项目所有功能写在同一个工程里:用户、订单、支付、商品、文件上传全部耦合在一起,打包成一个 war/jar 包部署。 痛点:
- 改一行订单代码,整个项目全量发布;
- 一处代码崩溃,整个系统宕机;
- 技术栈统一,不能单独给模块换框架;
- 团队大了代码冲突严重,编译、启动极慢;
- 扩容只能整体扩容,资源浪费。
2. 微服务定义
将单一单体应用,按业务领域拆分成多个独立、小型、自治的服务,每个服务只负责一类业务,独立开发、独立部署、独立扩容、独立技术栈,通过网络接口互相调用。
- 每个服务:单一职责(高内聚、低耦合)
- 服务之间:通过 HTTP/RPC 通信
- 数据:大多每个服务自有独立数据库(避免库耦合)
举个电商拆分例子: 单体 → 拆分为 用户服务、商品服务、订单服务、支付服务、购物车服务、物流服务、搜索服务、文件服务
二、微服务核心特征
- 单一业务职责 一个服务只做一件事,订单只管下单、退款、库存扣减,不处理用户登录。
- 独立部署 更新订单服务,只重启订单,不影响商品、支付。
- 独立进程 每个服务是单独进程,互不干扰,某服务故障不会连锁全站崩溃。
- 去中心化数据管理 各服务自有数据库,禁止跨服务连库;跨服务查数据只能调用接口。
- 轻量级通信 主流两种:
- RESTful HTTP(简单通用)
- RPC(Dubbo、gRPC,高性能内网调用)
- 技术栈灵活 用户服务用 SpringBoot Java,搜索服务可用 Go,数据分析可用 Python。
- 基础设施自动化 依赖容器 Docker、K8s、CI/CD 实现批量部署、弹性扩缩容。
三、微服务架构必备核心组件
一套完整微服务体系,离不开这几大模块:
1. 服务注册与发现(注册中心)
解决:服务地址不固定,消费者怎么找到提供者? 主流:Nacos、Eureka、Consul、etcd 流程: 服务启动 → 把 IP、端口注册到注册中心 消费者启动 → 从注册中心拉取所有可用服务列表
2. 配置中心
统一管理所有服务配置(数据库地址、开关、超时参数),不用每个服务改 yml 重启。 主流:Nacos、Apollo、Spring Cloud Config
3. API 网关(Gateway)
所有前端请求统一入口,做路由转发、鉴权、限流、跨域、日志、灰度发布。 主流:Spring Cloud Gateway、Kong、Sentinel Gateway 作用:屏蔽后端众多微服务,前端只对接网关一个地址。
4. 远程调用(RPC/HTTP 客户端)
服务之间内部调用工具:
- HTTP:OpenFeign
- RPC:Dubbo、gRPC
5. 服务熔断、降级、限流(容错组件)
防止某个服务卡顿拖垮整条链路(雪崩效应) 主流:Sentinel、Resilience4j、Hystrix
- 熔断:下游服务大量报错,直接切断调用,快速失败
- 降级:高峰期关闭非核心功能(商品详情关闭推荐)
- 限流:限制每秒请求量,保护服务不被打垮
6. 分布式事务
多服务操作同时成功 / 同时回滚(下单扣库存 + 扣余额) 方案:Seata(AT/TCC/SAGA)、本地消息表、可靠消息队列
7. 消息队列(异步解耦)
同步调用耦合高,用 MQ 异步通信,削峰、解耦、最终一致性 中间件:RocketMQ、RabbitMQ、Kafka 场景:下单后异步发通知、异步扣积分、异步生成物流单
8. 分布式链路追踪
排查跨服务调用慢、报错,记录完整调用链 工具:SkyWalking、Pinpoint、Zipkin、Jaeger
9. 容器编排 & 运维
Docker(打包服务环境)+ K8s(容器调度、自动扩缩容、自愈)
四、单体 vs 微服务优缺点对比
微服务优点
- 故障隔离:单个服务宕机不影响整体
- 独立迭代,小版本快速发布
- 按需扩容:订单高峰只扩容订单服务
- 团队并行开发,各司其职
- 技术栈自由,适配不同业务性能需求
微服务缺点(重点,不要盲目拆分)
-
架构复杂度大幅上升:要维护网关、注册中心、MQ、链路追踪等中间件
-
分布式带来一堆新问题:
- 分布式事务
- 分布式锁
- 接口调用超时、重试、数据一致性
- 跨服务日志排查困难
-
运维成本高:几十上百个服务,部署监控压力大
-
本地开发麻烦,需要启动一堆依赖服务
-
网络开销:服务间调用走网络,比本地方法调用慢
五、什么时候适合用微服务?什么时候别用
适合微服务场景
- 业务量大、并发高,单体扛不住扩容
- 多团队并行开发,代码经常冲突
- 不同模块迭代节奏完全不同(支付每月更,商品每周更)
- 部分模块需要高性能、更换技术栈
- 对可用性要求高,不能全站停机更新
不推荐微服务(先用单体)
- 小型项目、团队只有 1~3 人
- 业务简单,模块边界模糊,拆分后大量跨服务调用
- 无运维能力,不会部署中间件、容器
- 并发低、访问量小,单体完全够用
六、DDD 领域驱动设计:微服务拆分标准
微服务最难的是合理拆分,不能按层拆(Controller/Service 分开),要按业务领域拆分,DDD 是行业标准拆分思路:
- 界限上下文:一个独立业务域 = 一个微服务
- 聚合根:每个服务以核心实体为边界(订单聚合根 = 订单服务)
- 禁止跨服务直接操作数据库,所有数据交互走接口
错误拆分示例: 按技术分层拆分:Web 服务、Service 服务、DAO 服务(调用链极长,完全错误)
正确拆分: 用户域、商品域、订单域、支付域,每个域完整包含自身增删改查逻辑。
七、微服务常见落地架构分层
- 客户端层:小程序、APP、管理后台、前端页面
- 网关层:统一入口,路由、鉴权、限流
- 业务微服务层:用户 / 订单 / 商品等核心业务服务
- 公共基础服务层:文件存储、短信、日志、定时任务、第三方支付对接
- 中间件层:注册中心、配置中心、MQ、分布式缓存 Redis、链路追踪
- 存储层:MySQL 分库分表、Redis、ES、对象存储 OSS
八、微服务常见经典问题(面试高频)
- 服务雪崩:大量请求打到故障下游,连锁拖垮所有服务 → 熔断降级解决
- 分布式事务:跨服务数据一致性 → Seata、可靠消息队列
- 接口幂等:重复下单、重复支付造成脏数据 → 唯一请求 ID 防重
- 分布式锁:多服务同时操作库存超卖 → Redis 分布式锁、Zookeeper
- 服务版本兼容:接口升级不影响旧调用方 → 版本号、灰度发布
- 数据查询跨服务:不连其他库,通过 Feign 调用接口聚合数据
九、总结一句话
微服务是按业务领域拆分、独立自治、分布式协作的架构,用复杂度换取扩展性、可用性和团队并行效率;小项目优先单体,业务规模上来后再逐步拆分微服务,同时配套全套中间件与运维体系。