Skip to content
第 7 章 架构 ⏱ 11 分钟阅读

第 7 章:微服务入门 ​

学习目标 ​

  • 理解单体架构的痛点和微服务的价值
  • 掌握微服务的核心特征
  • 区分微服务 vs SOA vs Serverless
  • 识别"为了拆而拆"的常见坑

一、单体架构的痛点 ​

text
巨型单体(Monolith)
├── 用户模块
├── 商品模块
├── 订单模块
├── 支付模块
└── 库存模块
所有功能 → 一个 WAR/JAR → 一个 Tomcat/JVM
java
// 单体时代的代码结构
com.example.ecommerce
├── controller
├── service
└── dao
// 所有人提交同一个 Git 仓库,改一行代码全团队等部署

单体三大痛点:

  1. 编译慢:代码膨胀到 100 万行,改 5 行代码编译 10 分钟
  2. 部署慢:一个 bug 修复也要全量发布,凌晨 3 点才能上线
  3. 扩展难:商品模块要扩 10 倍,只能整个应用扩,浪费资源

⚠️ 坑 1:"等拆成微服务,这些问题就解决了" — 拆完数据库还是同一台,事务更乱,反而更糟。先优化单体,瓶颈明确再拆。

二、微服务定义 ​

Martin Fowler 2014 年提出:

一组小型服务,每个服务独立部署,围绕业务能力组织,去中心化,轻量级通信。

text
微服务架构
├── 用户服务(Spring Boot)
├── 商品服务(Spring Boot)
├── 订单服务(Spring Boot)
└── 支付服务(Spring Boot)
每个服务 = 独立进程 + 独立部署 + 独立数据库
java
// 订单服务调用支付服务(远程调用)
@Service
public class OrderService {
    @Resourceprivate PaymentClient paymentClient;   // Feign 客户端

    public void pay(OrderId orderId) {
        Order order = orderRepository.findById(orderId);
        PaymentResult result = paymentClient.pay(order.id(), order.amount());
        if (result.success()) {
            order.markPaid();
        }
    }
}

三、微服务的核心特征 ​

特征说明
独立部署一个服务一个进程,独立扩缩容
围绕业务能力按业务边界切分,不是按技术层
去中心化数据去中心(库),治理去中心(技术栈)
轻量通信HTTP/REST 或 gRPC,不用 ESB
故障隔离一个服务挂掉不影响其他
数据隔离一个服务一个数据库
java
// 数据隔离:每个服务独立数据库
public class OrderApplication {
    @Bean
    public DataSource orderDataSource() {
        return DataSourceBuilder.create()
            .url("jdbc:mysql://order-db:3306/order_db")
            .username("order_user")
            .password("xxx")
            .build();
    }
}

⚠️ 坑 2:"每个服务一个数据库" ≠ "每张表一个数据库"。服务边界 = 数据库边界,不要让订单服务和库存服务共享一个 MySQL 实例。

四、微服务 vs SOA vs Serverless ​

维度单体SOA微服务Serverless
颗粒度整个应用业务模块业务能力函数
通信内部调用ESBHTTP/gRPC事件
部署一起多个各自独立各自独立
适用小团队大企业转型互联网流量波动大
java
// Serverless 示例:AWS Lambda
public class OrderPlacedHandler implements RequestHandler<OrderEvent, String> {
    @Override
    public String handleRequest(OrderEvent event, Context context) {
        // 发送邮件
        emailService.send(event.getBuyerEmail(), "订单已创建");
        return "ok";
    }
}

五、什么时候应该拆微服务? ​

text
✅ 适合拆
├── 团队 50+ 人,代码冲突严重
├── 业务复杂,需要频繁独立发布
├── 部分模块扩展需求(秒杀、推荐)
└── 多语言栈(Go / Python / Java)

❌ 暂不建议拆
├── 团队 < 10 人
├── 业务早期,需求频繁变
├── 一致性要求极高(金融核心)
└── 没有 DevOps 能力

⚠️ 坑 3:创业公司 5 人团队上来就拆 10 个微服务,光治理就耗光精力。先单体 + 模块化,业务稳定再拆。

六、微服务的代价 ​

text
分布式带来的复杂度:
├── 服务发现(几十个服务怎么找)
├── 配置管理(配置分散在各服务)
├── 链路追踪(请求跨 5 个服务怎么追)
├── 分布式事务(下单 + 扣库存怎么一致)
├── 熔断降级(下游挂了怎么处理)
├── API 网关(统一入口)
└── 监控告警(几十个服务的健康度)
java
// 这些问题累加成本很高
@Component
public class DistributedTracingConfig {
    @Bean
    public Tracer tracer() {
        return new ZipkinTracer();
    }
}

没有 3-5 人的 SRE 团队,不要贸然上微服务。

本章小结 ​

维度单体微服务
部署一起独立
数据库共享各自独立
通信内部调用HTTP/gRPC
故障全局隔离
复杂度低高
适用早期成熟

动手练习 ​

  1. 单体切分:把一个单体电商项目拆成 user/product/order/payment 四个 Spring Boot 应用
  2. 数据库隔离:为每个服务申请独立数据库,演示跨服务调用时不能直接连对方库
  3. REST 调用:用 OpenFeign 写一个 OrderClient 调用支付服务的 /api/payments
  4. 压测对比:对一个服务压测,观察独立部署 vs 整体部署的扩容差异

下一章:第 8 章:微服务拆分 →

本站基于 VitePress 构建 · 由 StackHub 团队维护