Skip to content

微服务架构落地,Spring Cloud 全家桶组件总览

把一个巨型单体应用拆成几十个微服务,听起来很酷。但真正落地时,你会发现问题才刚刚开始:服务之间怎么通信?配置怎么管理?服务挂了怎么办?

这就是 Spring Cloud 全家桶要解决的问题。


从一个问题开始

假设你负责重构一个电商系统,从单体拆成微服务架构:

┌─────────────────────────────────────────────────────────┐
│                      单体应用                            │
│  ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐      │
│  │ 用户模块 │ │ 订单模块 │ │ 商品模块 │ │ 支付模块 │      │
│  └─────────┘ └─────────┘ └─────────┘ └─────────┘      │
└─────────────────────────────────────────────────────────┘
                           ↓ 拆分
┌──────────┐  ┌──────────┐  ┌──────────┐  ┌──────────┐
│ 用户服务  │  │ 订单服务  │  │ 商品服务  │  │ 支付服务  │
└──────────┘  └──────────┘  └──────────┘  └──────────┘

拆分后,你面临的问题:

  1. 服务发现:订单服务怎么知道用户服务的地址?
  2. 负载均衡:多个用户服务实例,订单服务该调用哪个?
  3. 配置管理:几十个服务,每个都要独立配置,怎么管?
  4. 流量控制:双十一流量暴涨,怎么限流?
  5. 链路追踪:请求经过 5 个服务,出问题了怎么定位?
  6. 服务通信:服务间调用,用 HTTP 还是 RPC?

Spring Cloud 全家桶,就是这些问题的标准答案。


组件全景图

                          ┌─────────────────┐
                          │   API 网关      │
                          │  (Gateway)      │
                          └────────┬────────┘

           ┌───────────────────────┼───────────────────────┐
           │                       │                       │
           ▼                       ▼                       ▼
    ┌─────────────┐        ┌─────────────┐        ┌─────────────┐
    │  用户服务    │◄──────►│  订单服务    │◄──────►│  商品服务    │
    │  :8081      │        │  :8082      │        │  :8083      │
    └──────┬──────┘        └──────┬──────┘        └──────┬──────┘
           │                      │                      │
           └──────────────────────┼──────────────────────┘

                          ┌───────▼───────┐
                          │  注册中心      │
                          │  (Nacos)      │
                          └───────┬───────┘

                          ┌───────▼───────┐
                          │  配置中心      │
                          │  (Nacos)      │
                          └───────┬───────┘

                          ┌───────▼───────┐
                          │  限流熔断      │
                          │  (Sentinel)    │
                          └───────┬───────┘

                          ┌───────▼───────┐
                          │  链路追踪      │
                          │  (Zipkin)     │
                          └───────────────┘

核心组件详解

一、服务注册与发现

解决问题:服务如何知道其他服务的地址?

Nacos(推荐)

阿里的开源产品,同时支持注册中心配置中心

yaml
spring:
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
        namespace: dev
        group: DEFAULT_GROUP
      config:
        server-addr: 127.0.0.1:8848
        file-extension: yaml
java
@SpringBootApplication
@EnableDiscoveryClient  // 开启服务注册
public class UserApplication {
    public static void main(String[] args) {
        SpringApplication.run(UserApplication.class, args);
    }
}

核心特性

  • 支持临时实例和持久实例
  • 支持命名空间隔离
  • 提供控制台管理界面
  • 集成配置中心,一站式解决方案

二、声明式 HTTP 客户端

解决问题:服务间 HTTP 调用如何更简单?

OpenFeign

用注解的方式调用 HTTP 接口,像调用本地方法一样简单。

java
@FeignClient(name = "user-service", path = "/users")
public interface UserClient {
    
    @GetMapping("/{id}")
    User getUser(@PathVariable Long id);
    
    @GetMapping("/list")
    List<User> getUsers(@RequestParam List<Long> ids);
}
java
@RestController
@RequestMapping("/orders")
public class OrderController {
    
    @Autowired
    private UserClient userClient;
    
    @GetMapping("/{orderId}")
    public Order getOrder(@PathVariable Long orderId) {
        // 调用用户服务获取用户信息
        User user = userClient.getUser(order.getUserId());
        return order;
    }
}

核心特性

  • 基于注解声明式定义 RESTful 接口
  • 集成 Ribbon,自动负载均衡
  • 支持 Hystrix 熔断(可切换为 Sentinel)
  • 支持请求/响应压缩
  • 支持日志打印

三、统一网关

解决问题:外部请求如何统一入口?

Spring Cloud Gateway

异步非阻塞的网关,性能比 Zuul 更优。

yaml
spring:
  cloud:
    gateway:
      routes:
        - id: user-service
          uri: lb://user-service
          predicates:
            - Path=/api/users/**
          filters:
            - StripPrefix=1
            - name: RequestRateLimiter
              args:
                redis-rate-limiter.replenishRate: 100
                redis-rate-limiter.burstCapacity: 200

核心特性

  • 异步非阻塞模型,性能优秀
  • 内置多种路由断言(Path、Header、Query 等)
  • 支持自定义过滤器
  • 集成限流、熔断
  • 支持动态路由

四、限流与熔断

解决问题:服务挂了怎么办?怎么防止雪崩?

Sentinel

阿里的流量防卫兵,专注于流量控制和熔断降级。

java
@RestController
@RequestMapping("/order")
public class OrderController {
    
    @GetMapping("/create")
    @SentinelResource(value = "createOrder",
        blockHandler = "createOrderBlockHandler",
        fallback = "createOrderFallback")
    public Result<Order> createOrder(@RequestParam Long userId) {
        // 业务逻辑
        return Result.ok(orderService.create(userId));
    }
    
    // 限流处理
    public Result<Order> createOrderBlockHandler(Long userId, BlockException e) {
        return Result.fail("访问太频繁,请稍后再试");
    }
    
    // 降级处理
    public Result<Order> createOrderFallback(Long userId, Throwable e) {
        return Result.fail("服务繁忙,请稍后再试");
    }
}

核心特性

  • 流量控制(QPS、并发数)
  • 熔断降级(RT、异常比例、异常数)
  • 系统自适应保护
  • 热点参数限流
  • 规则持久化

五、配置中心

解决问题:配置如何集中管理?如何实现热更新?

Nacos Config

配置管理的五把钥匙:命名空间(Namespace)、分组(Group)、Data ID、配置内容、配置版本

yaml
#  bootstrap.yml
spring:
  application:
    name: order-service
  cloud:
    nacos:
      config:
        server-addr: 127.0.0.1:8848
        namespace: dev
        group: ORDER_GROUP
        file-extension: yaml
        refresh-enabled: true
  profiles:
    active: prod

Data ID 完整命名规则:${spring.application.name}-${spring.profiles.active}.${file-extension}

例如:order-service-prod.yaml

核心特性

  • 配置热更新(@RefreshScope)
  • 配置变更监听
  • 配置版本管理
  • 配置回滚
  • 共享配置

六、链路追踪

解决问题:请求跨多个服务,如何追踪调用链路?

Sleuth + Zipkin

Spring Cloud 提供的分布式追踪解决方案。

yaml
spring:
  zipkin:
    base-url: http://localhost:9411
  sleuth:
    sampler:
      probability: 1.0
java
@RestController
@RequestMapping("/api/orders")
public class OrderController {
    
    @Autowired
    private OrderService orderService;
    
    @GetMapping("/{id}")
    public Order getOrder(@PathVariable Long id) {
        return orderService.getById(id);
    }
}

在 Zipkin 控制台,你可以看到这样的调用链路:

[order-service] 
    ├─► [user-service] 
    │       └─► [database]
    ├─► [product-service] 
    │       └─► [redis cache]
    └─► [payment-service] 
            └─► [third-party-api]

七、消息总线

解决问题:配置变更后,如何让所有服务自动刷新?

Spring Cloud Bus

基于 MQ 的消息广播,用于通知配置变更。

yaml
# application.yml
spring:
  cloud:
    bus:
      enabled: true
      trace:
        enabled: true
  rabbitmq:
    host: localhost
    port: 5672
bash
# 触发所有服务刷新配置
curl -X POST http://localhost:8848/nacos/v1/cs/configs?dataId=order-service.yaml&group=DEFAULT_GROUP&content=...

八、分布式事务

解决问题:跨服务的数据一致性如何保证?

Seata

阿里巴巴开源的分布式事务解决方案,支持 AT、TCC、Saga 模式。

java
@GlobalTransactional
public void createOrder(OrderDTO orderDTO) {
    // 1. 创建订单
    Order order = new Order();
    order.setUserId(orderDTO.getUserId());
    order.setAmount(orderDTO.getAmount());
    orderMapper.insert(order);
    
    // 2. 扣减库存(远程调用)
    productClient.deductStock(orderDTO.getProductId(), orderDTO.getQuantity());
    
    // 3. 扣减余额(远程调用)
    accountClient.deductBalance(orderDTO.getUserId(), orderDTO.getAmount());
}

技术选型建议

场景推荐方案原因
注册中心Nacos功能全面,配置中心合一
配置中心Nacos Config与注册中心统一,维护成本低
网关Gateway异步非阻塞,性能优秀
服务调用OpenFeign声明式调用,开发效率高
限流熔断Sentinel功能完善,控制台友好
链路追踪Sleuth + Zipkin集成简单,可视化清晰
分布式事务SeataAT 模式对业务无侵入

总结

Spring Cloud 全家桶解决了微服务架构的四大核心问题:

  1. 服务通信:OpenFeign 让服务调用像本地方法一样简单
  2. 服务治理:Nacos 让服务注册、配置、发现一体化
  3. 流量控制:Sentinel 提供了全方位的流量防护
  4. 问题定位:Sleuth + Zipkin 让分布式追踪成为可能

没有银弹。微服务架构带来了灵活性,也带来了复杂度。Spring Cloud 全家桶能帮你降低这种复杂度,但前提是你理解每个组件的设计初衷和适用场景。

基于 VitePress 构建