微服务架构详解
📅2026-07-06T06:00:00.000Z
微服务架构详解
微服务架构(Microservices Architecture)是当下后端开发中最主流的架构风格之一。它将一个大型应用拆分为多个独立的小型服务,每个服务围绕业务能力构建,可独立开发、部署和扩展。本文将带你从概念到实践,全面理解微服务架构。
单体架构 vs 微服务架构
单体架构(Monolithic)
所有功能模块运行在同一个进程中,代码共享同一个仓库、同一个数据库:
┌─────────────────────────────────────┐
│ 单体应用 │
│ ┌──────┐ ┌──────┐ ┌──────┐ │
│ │ 用户 │ │ 订单 │ │ 商品 │ │
│ │ 模块 │ │ 模块 │ │ 模块 │ │
│ └──────┘ └──────┘ └──────┘ │
│ │ │ │ │
│ └────────┼────────┘ │
│ │ │
│ ┌──────┴──────┐ │
│ │ 数据库 │ │
│ └─────────────┘ │
└─────────────────────────────────────┘微服务架构(Microservices)
每个业务模块独立为一个服务,拥有独立的数据库和部署流程:
┌──────────┐ ┌──────────┐ ┌──────────┐
│ 用户服务 │ │ 订单服务 │ │ 商品服务 │
│ ┌────┐ │ │ ┌────┐ │ │ ┌────┐ │
│ │ DB │ │ │ │ DB │ │ │ │ DB │ │
│ └────┘ │ │ └────┘ │ │ └────┘ │
└────┬─────┘ └────┬─────┘ └────┬─────┘
│ │ │
└──────────────┼──────────────┘
│
┌───────┴───────┐
│ API 网关 │
└───────┬───────┘
│
客户端| 维度 | 单体架构 | 微服务架构 |
|---|---|---|
| 部署 | 整体打包部署 | 每个服务独立部署 |
| 扩展 | 整体水平扩展 | 按需扩展特定服务 |
| 数据库 | 共享一个数据库 | 每个服务独立数据库 |
| 开发效率 | 初期快,后期慢 | 初期慢,后期快 |
| 技术栈 | 统一技术栈 | 每个服务可选用不同技术 |
| 运维复杂度 | 低 | 高 |
| 故障隔离 | 单点故障影响全局 | 故障隔离在单个服务内 |
微服务核心组件
服务注册与发现
服务实例动态变化(扩缩容、重启),需要一个中心化的注册中心来管理:
┌──────────────┐ 注册心跳 ┌──────────────┐
│ 用户服务实例 │ ───────────> │ │
│ 10.0.0.1:8080│ │ 注册中心 │
└──────────────┘ │ (Consul/ │
│ Nacos/Etcd) │
┌──────────────┐ 注册心跳 │ │
│ 用户服务实例 │ ───────────> │ │
│ 10.0.0.2:8080│ └──────┬───────┘
└──────────────┘ │
查询可用实例
┌──────────────┐ │
│ 订单服务 │ <──────────────────┘
└──────────────┘主流方案:
| 组件 | 语言 | 特点 |
|---|---|---|
| Consul | Go | 健康检查强,支持多数据中心 |
| Nacos | Java | 阿里开源,配置中心+注册中心一体 |
| Etcd | Go | 强一致性,Kubernetes 使用 |
| Eureka | Java | Netflix 出品,AP 设计 |
API 网关
网关是所有客户端请求的入口,负责路由、认证、限流、日志等:
客户端请求
│
▼
┌──────────────┐
│ API 网关 │ ← 统一鉴权、限流、日志、路由
│ (Kong/ │
│ APISIX/ │
│ Spring │
│ Gateway) │
└──┬───┬───┬──┘
│ │ │
▼ ▼ ▼
用户 订单 商品
服务 服务 服务网关核心功能:
- 路由转发:根据请求路径将流量转发到对应服务
- 身份认证:统一校验 JWT Token,避免每个服务重复鉴权
- 限流熔断:保护后端服务不被流量冲垮
- 日志监控:集中记录请求日志,便于排查问题
- 协议转换:HTTP 转 gRPC、WebSocket 等
服务间通信
微服务之间需要相互调用,主要分为两种模式:
同步通信(REST / gRPC)
// gRPC 服务定义 (proto)
service OrderService {
rpc CreateOrder(CreateOrderReq) returns (CreateOrderResp);
}
message CreateOrderReq {
int64 user_id = 1;
int64 product_id = 2;
int32 quantity = 3;
}# REST 调用示例
import requests
def get_user(user_id):
resp = requests.get(f"http://user-service/api/users/{user_id}")
return resp.json()异步通信(消息队列)
┌──────────┐ 发布事件 ┌──────────────┐ 消费事件 ┌──────────┐
│ 订单服务 │ ─────────> │ 消息队列 │ ─────────> │ 库存服务 │
│ │ │ (Kafka/ │ │ │
│"订单创建" │ │ RabbitMQ/ │ │"扣减库存" │
│ │ │ RocketMQ) │ │ │
└──────────┘ └──────────────┘ └──────────┘| 方式 | 协议 | 优点 | 缺点 |
|---|---|---|---|
| REST | HTTP/JSON | 简单通用,调试方便 | 性能一般,强耦合 |
| gRPC | HTTP/2 + Protobuf | 高性能,强类型 | 调试不便,浏览器不支持 |
| 消息队列 | AMQP / Kafka | 解耦,削峰,异步 | 增加复杂度,延迟高 |
微服务核心模式
服务熔断(Circuit Breaker)
当下游服务不可用时,快速失败而不是一直等待,防止级联故障:
正常状态
┌──────────────┐
│ │
│ CLOSED │ ── 请求失败达到阈值 ──> ┌──────────────┐
│ (正常调用) │ │ OPEN │
│ │ <── 超时后尝试恢复 ──── │ (直接拒绝) │
└──────────────┘ └──────┬───────┘
│
尝试请求成功 │
│
┌────────┴───────┐
│ HALF-OPEN │
│ (限流尝试) │
└────────────────┘三种状态:
- CLOSED:正常调用,统计失败率
- OPEN:失败率达到阈值,直接返回错误,不再调用下游
- HALF-OPEN:过一段时间后,允许少量请求试探,成功则回到 CLOSED,失败则继续 OPEN
分布式事务(Saga 模式)
微服务中每个服务有独立数据库,无法使用传统的数据库事务。Saga 通过本地事务 + 补偿操作实现最终一致性:
订单服务 库存服务 支付服务
│ │ │
│ 1. 创建订单(待支付) │ │
│─────────────────────>│ │
│ │ 2. 扣减库存 │
│ │─────────────────────>│
│ │ │ 3. 扣款
│ │ │──────┐
│ │ │<─────┘
│ │ │ 失败!
│ │ 4. 补偿:恢复库存 │
│ │<─────────────────────│
│ 5. 补偿:取消订单 │ │
│<─────────────────────│ │两种 Saga 实现方式:
| 方式 | 描述 | 优点 | 缺点 |
|---|---|---|---|
| 编排式 | 一个协调服务控制整个流程 | 流程清晰,易于管理 | 协调器成为单点 |
| choreography | 各服务通过事件驱动自行协作 | 松耦合,无单点 | 流程分散,难以追踪 |
CQRS(命令查询职责分离)
将读操作和写操作分离到不同的模型和服务中:
写请求 读请求
│ │
▼ ▼
┌─────────────┐ ┌─────────────┐
│ 命令服务 │ │ 查询服务 │
│ (写模型) │ │ (读模型) │
└──────┬──────┘ └──────▲──────┘
│ │
▼ │
┌─────────────┐ ┌──────────────┐
│ 写数据库 │ ──同步──> │ 读数据库 │
│ (MySQL) │ │ (Elasticsearch│
└─────────────┘ │ / Redis) │
└──────────────┘适用场景:
- 读写比例悬殊(读远多于写)
- 查询需要多表关联,写入只需单表
- 搜索、报表等复杂查询场景
分布式配置中心
将配置从代码中剥离,集中管理,支持动态刷新:
┌──────────────┐
│ 配置中心 │ ← 统一管理所有服务的配置
│ (Nacos/ │
│ Apollo/ │
│ Consul) │
└──┬───┬───┬──┘
│ │ │ 配置变更实时推送
▼ ▼ ▼
用户 订单 商品
服务 服务 服务微服务技术栈全景
| 层次 | 技术选型 |
|---|---|
| 服务框架 | Spring Cloud、Go-Kit、Go-Micro、Kratos |
| 注册中心 | Nacos、Consul、Etcd、Eureka |
| 配置中心 | Nacos、Apollo、Spring Cloud Config |
| API 网关 | Kong、APISIX、Spring Cloud Gateway、Traefik |
| 服务调用 | REST、gRPC、Dubbo |
| 消息队列 | Kafka、RabbitMQ、RocketMQ、Pulsar |
| 分布式事务 | Seata、Saga 模式、TCC |
| 链路追踪 | Jaeger、Zipkin、SkyWalking |
| 日志收集 | ELK(Elasticsearch + Logstash + Kibana)、Loki |
| 监控告警 | Prometheus + Grafana |
| 容器编排 | Docker + Kubernetes |
| 服务网格 | Istio、Linkerd |
容器化与 Kubernetes
微服务天然适合容器化部署。Kubernetes 提供了微服务所需的编排能力:
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: user-service
spec:
replicas: 3
selector:
matchLabels:
app: user-service
template:
metadata:
labels:
app: user-service
spec:
containers:
- name: user-service
image: user-service:1.0.0
ports:
- containerPort: 8080
env:
- name: DB_HOST
valueFrom:
configMapKeyRef:
name: user-service-config
key: db.host
---
apiVersion: v1
kind: Service
metadata:
name: user-service
spec:
selector:
app: user-service
ports:
- port: 8080
targetPort: 8080Kubernetes 与微服务的对应关系:
| Kubernetes 能力 | 微服务需求 |
|---|---|
| Service | 服务发现与负载均衡 |
| Deployment | 滚动更新、回滚 |
| ConfigMap / Secret | 配置管理 |
| HPA | 自动扩缩容 |
| Ingress | API 网关入口 |
| Namespace | 环境隔离 |
可观测性
微服务数量多、调用链复杂,必须建立完善的可观测性体系:
三大支柱
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ 日志 │ │ 指标 │ │ 链路追踪 │
│ (Logs) │ │ (Metrics) │ │ (Traces) │
├──────────────┤ ├──────────────┤ ├──────────────┤
│ 发生了什么 │ │ 系统状态如何 │ │ 请求经过了哪里 │
│ ELK / Loki │ │ Prometheus │ │ Jaeger / │
│ │ │ + Grafana │ │ SkyWalking │
└──────────────┘ └──────────────┘ └──────────────┘链路追踪示例
一个请求在微服务间的调用链路:
客户端 → API 网关 (10ms)
→ 用户服务 (30ms)
→ 数据库 (15ms)
→ Redis (5ms)
→ 订单服务 (50ms)
→ 库存服务 (20ms)
→ 数据库 (25ms)
─────────────────────────────────
总耗时: 90ms微服务拆分原则
从单体迁移到微服务,拆分是最大的挑战:
按业务边界拆分(DDD 领域驱动设计)
电商系统
├── 用户上下文(User Bounded Context)
│ ├── 注册登录
│ ├── 个人信息
│ └── 地址管理
├── 商品上下文(Product Bounded Context)
│ ├── 商品管理
│ ├── 分类管理
│ └── 库存管理
├── 订单上下文(Order Bounded Context)
│ ├── 购物车
│ ├── 下单
│ └── 订单查询
└── 支付上下文(Payment Bounded Context)
├── 支付
└── 退款拆分原则
- 单一职责:一个服务只做一件事,做好一件事
- 高内聚低耦合:服务内部强关联,服务之间弱依赖
- 数据独立:每个服务拥有自己的数据库,通过 API 访问其他服务的数据
- 按团队组织:一个团队负责一个或多个服务,减少跨团队协调
- 渐进式拆分:不要一次性拆完,从边缘模块开始,逐步迁移
微服务的挑战与对策
| 挑战 | 对策 |
|---|---|
| 分布式事务 | Saga 模式、TCC、最终一致性 |
| 服务间通信延迟 | 异步消息、缓存、批量操作 |
| 数据一致性 | 事件驱动、CQRS、补偿机制 |
| 调试困难 | 链路追踪、集中日志、统一 Trace ID |
| 运维复杂度 | 容器化、Kubernetes、CI/CD 自动化 |
| 网络不可靠 | 重试、熔断、超时、幂等设计 |
| 测试困难 | 契约测试(Pact)、端到端测试 |
| 团队协作 | API 文档先行、接口版本管理 |
什么时候不该用微服务
微服务不是银弹。以下场景不建议使用:
- 项目初期:业务不稳定,边界不清晰,频繁变更会导致微服务拆分成本极高
- 小团队:微服务增加运维负担,3-5 人的团队维护单体应用更高效
- 性能敏感场景:服务间网络调用增加延迟,高频交易等场景不适合
- 简单业务:CRUD 为主的内部管理系统,单体架构足够
小结
| 概念 | 要点 |
|---|---|
| 服务注册发现 | 注册中心管理服务实例,支持动态上下线 |
| API 网关 | 统一入口,路由、鉴权、限流、日志 |
| 服务通信 | 同步用 REST/gRPC,异步用消息队列 |
| 服务熔断 | 防止级联故障,三种状态:CLOSED / OPEN / HALF-OPEN |
| 分布式事务 | Saga 模式实现最终一致性,编排式 vs 事件驱动 |
| CQRS | 读写分离,适合读写比例悬殊的场景 |
| 可观测性 | 日志 + 指标 + 链路追踪,三大支柱缺一不可 |
| 容器化 | Docker + Kubernetes 是微服务部署的事实标准 |
| 拆分原则 | 按业务边界拆分,渐进式迁移,数据独立 |
微服务架构的核心思想是分而治之。它将复杂系统拆解为可独立演进的自治单元,在带来灵活性的同时,也引入了分布式系统的固有复杂性。是否采用微服务,取决于团队规模、业务复杂度和你对运维成本的承受能力。如果想进一步学习,推荐阅读 Martin Fowler 的微服务文章 和 《Designing Data-Intensive Applications》。