微服务架构:什么时候该用,什么时候不该用

5 阅读5分钟

前言

"微服务"是近年来最火的概念,但也是被误解最深的概念。

很多人觉得微服务是"高大上"的代名词,动不动就拆。但实际上,微服务不是银弹,用错了反而是灾难

这篇文章带你理性看待微服务,什么时候该用,什么时候不该用,一次讲清楚。


一、微服务是什么?

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 服务通信

# 服务注册与发现(Nacosspring:
  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人+) ✅ 业务复杂 ✅ 需要高伸缩性 ✅ 技术多样性

不该用微服务: ❌ 团队规模小 ❌ 业务简单 ❌ 初创公司 ❌ 没有基础设施

记住:架构是为了业务服务的,不是为了技术而技术。


💡 互动:你们的项目用的是什么架构?有什么经验教训?评论区聊聊!