前言
"微服务"是近年来最火的概念,但也是被误解最深的概念。
很多人觉得微服务是"高大上"的代名词,动不动就拆。但实际上,微服务不是银弹,用错了反而是灾难。
这篇文章带你理性看待微服务,什么时候该用,什么时候不该用,一次讲清楚。
一、微服务是什么?
1.1 传统架构 vs 微服务架构
单体架构:
┌─────────────────────────────┐
│ 用户服务 │
│ 订单服务 │
│ 支付服务 │
│ 商品服务 │
│ ... │
│ (all in one) │
└─────────────────────────────┘
微服务架构:
┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
│ 用户服务 │ │ 订单服务 │ │ 支付服务 │ │ 商品服务 │
└────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘
│ │ │ │
└────────────┴────────────┴────────────┘
↓
┌──────────────┐
│ API 网关 │
└──────────────┘
1.2 微服务的核心特征
| 特征 | 说明 |
|---|---|
| 独立部署 | 每个服务独立打包、部署、升级 |
| 独立进程 | 每个服务运行在独立进程中 |
| 松耦合 | 服务间通过 API 通信,不直接依赖数据库 |
| 业务独立 | 每个服务负责一个完整的业务功能 |
二、什么时候该用微服务?
2.1 场景 1:团队规模大
信号:团队超过 10 人,多个团队同时开发一个应用。
问题:
- 代码合并冲突频繁
- 部署互相影响
- 没人敢改核心代码
解决方案:
团队A → 用户服务
团队B → 订单服务
团队C → 支付服务
2.2 场景 2:业务复杂
信号:单个应用代码超过 10 万行,模块间依赖混乱。
问题:
- 启动一次要 5 分钟
- 改一个小功能要重新部署整个应用
- 找不到代码在哪里
解决方案:按业务拆分,每个服务独立演进。
2.3 场景 3:需要高伸缩性
信号:不同模块压力差异大,比如秒杀时订单服务压力大,但用户服务压力小。
问题:
- 资源无法独立扩展
- 整体扩容成本高
解决方案:
订单服务:5 台机器
用户服务:2 台机器
商品服务:3 台机器
2.4 场景 4:技术多样性
信号:不同业务需要不同的技术栈。
问题:
- Python 做数据分析,Java 做交易,Go 做高并发
- 单体应用无法支持多语言
解决方案:每个服务用最合适的技术。
三、什么时候不该用微服务?
3.1 场景 1:团队规模小
信号:团队 3-5 个人,一个人负责多个模块。
问题:
- 维护成本高:每个服务都要部署、监控、运维
- 复杂度高:服务间调用链路复杂
- 收益小于投入
建议:单体 + 模块化,团队壮大了再考虑拆分。
3.2 场景 2:业务简单
信号:CRUD 为主,业务逻辑不复杂。
问题:
- 拆分了没收益,反而增加复杂度
- 过度设计
建议:
简单业务 → 单体应用
复杂业务 → 微服务
3.3 场景 3:初创公司
信号:产品还在验证期,业务方向不确定。
问题:
- 业务变化快,拆分后改造成本高
- 人手不够,运维不过来
- 急着上线,没时间搞基建
建议:单体 + 云原生,等业务稳定了再拆分。
3.4 场景 4:没有基础设施
信号:没有 CI/CD、没有监控、没有日志系统。
问题:
- 微服务需要完善的 DevOps 能力
- 拆分后问题定位更困难
- 只会更糟,不会更好
建议:先搭建基础设施,再考虑微服务。
四、微服务的代价
4.1 复杂度增加
| 单体 | 微服务 |
|---|---|
| 1 个应用 | 10+ 个服务 |
| 本地调用 | 远程调用(RPC/HTTP) |
| 1 个数据库 | 10+ 个数据库 |
| 1 份日志 | 分布式日志 |
4.2 运维成本
需要的基建:
✅ 容器编排(K8s)
✅ 服务注册与发现
✅ 配置中心
✅ 熔断限流
✅ 链路追踪
✅ 日志聚合
✅ 监控告警
✅ CI/CD 流水线
4.3 一致性问题
单体:直接操作数据库,事务简单
微服务:
用户服务 ──→ 订单服务 ──→ 支付服务
│ │ │
└──────────────┴──────────────┘
↓
分布式事务
(很难,很复杂)
五、微服务拆分策略
5.1 按业务拆分(推荐)
电商系统拆分:
├── user-service(用户服务)
├── product-service(商品服务)
├── order-service(订单服务)
├── payment-service(支付服务)
└── notification-service(通知服务)
原则:每个服务独立负责一个核心业务。
5.2 按团队拆分
团队A → 用户服务 + 订单服务
团队B → 商品服务 + 库存服务
团队C → 支付服务 + 财务服务
原则:谁开发,谁负责。
5.3 按读写拆分(CQRS)
├── order-query-service(订单查询)
└── order-command-service(订单写入)
原则:读和写分离,针对性优化。
5.4 拆分时机
✅ 可以拆:
- 团队超过 10 人
- 代码超过 10 万行
- 业务边界清晰
- 基础设施完善
❌ 不该拆:
- 团队 3-5 人
- 业务简单
- 还在探索期
- 没有 DevOps 能力
六、微服务最佳实践
6.1 API 设计
// RESTful API 设计
@RestController
@RequestMapping("/api/v1/orders")
public class OrderController {
// 创建订单
@PostMapping
public ResponseEntity<OrderDTO> create(@RequestBody @Valid CreateOrderRequest request) {
return ResponseEntity.ok(orderService.create(request));
}
// 查询订单
@GetMapping("/{id}")
public ResponseEntity<OrderDTO> getById(@PathVariable Long id) {
return ResponseEntity.ok(orderService.getById(id));
}
}
6.2 服务通信
# 服务注册与发现(Nacos)
spring:
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
# Feign 声明式调用
@FeignClient(name = "order-service")
public interface OrderClient {
@GetMapping("/api/v1/orders/{id}")
OrderDTO getById(@PathVariable("id") Long id);
}
6.3 熔断降级
// Sentinel 熔断降级
@SentinelResource(value = "getUser", fallback = "fallback")
public User getUser(Long id) {
return userFeignClient.getUser(id);
}
public User fallback(Long id, Throwable t) {
// 降级逻辑:返回默认值或缓存数据
return new User();
}
6.4 链路追踪
# SkyWalking 配置
spring:
cloud:
sleuth:
sampler:
probability: 1.0 # 100% 采样
七、决策流程图
开始
│
▼
团队规模 > 10人? ──否──→ 单体架构
│
是
▼
业务复杂度高? ──否──→ 单体架构
│
是
▼
有完善的基础设施? ──否──→ 先建基础设施
│
是
▼
业务方向稳定? ──否──→ 单体架构 + 模块化
│
是
▼
微服务架构 ✓
总结
微服务不是银弹,有代价有收益:
该用微服务: ✅ 团队规模大(10人+) ✅ 业务复杂 ✅ 需要高伸缩性 ✅ 技术多样性
不该用微服务: ❌ 团队规模小 ❌ 业务简单 ❌ 初创公司 ❌ 没有基础设施
记住:架构是为了业务服务的,不是为了技术而技术。
💡 互动:你们的项目用的是什么架构?有什么经验教训?评论区聊聊!