微服务架构是当前后端开发的主流选择。它能提高团队的并行开发效率, 但也带来了分布式系统的固有问题。本文将系统介绍微服务的核心概念、 关键组件和技术选型。
单体 vs 微服务
| 维度 | 单体架构 | 微服务架构 |
|---|---|---|
| 部署 | 一次部署整个应用 | 每个服务独立部署 |
| 扩展 | 整体扩缩容 | 按需扩缩单个服务 |
| 技术栈 | 统一技术栈 | 每个服务可独立选型 |
| 开发效率 | 初期高,后期低 | 初期低,后期高 |
| 故障隔离 | 单点故障影响全局 | 故障隔离在单个服务 |
| 运维复杂度 | 低 | 高(需容器编排、监控等) |
选择建议:项目初期优先用模块化单体(Modular Monolith)。
当团队规模超过 20 人、或某些模块需要独立扩缩时,再考虑拆分微服务。
过早引入微服务是许多项目的失败原因。
服务拆分策略
领域驱动设计(DDD)是微服务拆分的核心方法论:
- 按业务能力拆分:每个服务对应一个业务领域(用户服务、订单服务、支付服务)
- 按限界上下文:每个上下文内的模型保持一致,上下文间通过接口通信
- 数据独立:每个服务有自己的数据库,不允许跨服务直接访问数据库
# 电商系统微服务拆分示例
.
├── user-service # 用户服务(注册、登录、个人信息)
├── product-service # 商品服务(商品信息、库存、分类)
├── order-service # 订单服务(下单、订单状态)
├── payment-service # 支付服务(支付、退款)
├── notification-service # 通知服务(短信、邮件、推送)
└── gateway-service # API 网关(统一入口、鉴权、限流)
服务间通信
同步通信:REST / gRPC
# REST — 简单通用,适合对外接口
POST /api/v1/orders
{ "user_id": 1, "product_id": 100, "quantity": 2 }
# gRPC — 高性能,适合内部服务通信
service OrderService {
rpc CreateOrder (CreateOrderReq) returns (CreateOrderResp);
}
message CreateOrderReq {
int64 user_id = 1;
int64 product_id = 2;
int32 quantity = 3;
}
异步通信:消息队列
# 订单创建后,通过消息队列通知其他服务
# 订单服务
def create_order(data):
order = save_to_db(data)
message_queue.publish("order.created", {
"order_id": order.id,
"user_id": order.user_id,
"amount": order.total,
})
return order
# 通知服务(消费者)
def on_order_created(event):
send_email(event["user_id"], f"订单 {event['order_id']} 已创建")
# 库存服务(消费者)
def on_order_created(event):
deduct_stock(event["order_id"])
服务发现与注册
在微服务中,服务实例动态变化,不能硬编码地址:
# Consul / Etcd / Nacos 注册中心
# 服务启动时注册
consul.register("order-service", host="10.0.1.5", port=8080)
# 调用时从注册中心获取地址
addresses = consul.discover("payment-service")
# → ["10.0.1.8:8080", "10.0.1.9:8080"]
# 配合健康检查自动剔除不健康的实例
API 网关
网关是微服务架构的入口,负责统一鉴权、限流、路由、日志:
# Nginx / Kong / APISIX 网关路由配置
# 根据 URL 路径路由到不同服务
/api/v1/users/** → user-service:8080
/api/v1/products/** → product-service:8080
/api/v1/orders/** → order-service:8080
/api/v1/payments/** → payment-service:8080
分布式链路追踪
在微服务中,一个请求可能经过多个服务,排查问题需要链路追踪:
# 使用 OpenTelemetry + Jaeger
# 在每个服务中配置 trace 上报
from opentelemetry import trace
from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor
app = FastAPI()
FastAPIInstrumentor.instrument_app(app)
# 每个请求生成唯一 TraceID,贯穿所有下游调用
# Jaeger UI 可查看完整调用链路和每个 Span 的耗时
分布式事务
跨服务的数据库操作无法使用传统的数据库事务,需要分布式事务方案:
# Saga 模式:每个步骤都有对应的补偿操作
# 下单流程
# 1. 订单服务:创建订单(状态:pending)
# 2. 库存服务:扣减库存
# └─ 失败 → 补偿:订单服务取消订单
# 3. 支付服务:扣款
# └─ 失败 → 补偿:库存服务恢复库存 → 订单服务取消订单
# 2PC 对于微服务来说太重,Saga 模式是更务实的选择
总结
微服务不是银弹。它解决了单体架构在大型团队中的效率问题, 但引入了分布式系统的复杂性(网络延迟、数据一致性、故障排查)。 关键决策在于把握好拆分的时机和粒度——宁可晚拆、浅拆,也不要为微服务而微服务。 对于大多数项目来说,模块化单体 + 合理拆分,才是务实的演进路径。
← 返回首页