Spring Cloud

Spring Cloud

概述

Spring Cloud是一套基于Spring Boot的微服务开发工具集,为分布式系统开发提供了配置管理、服务发现、断路器、智能路由、微代理、控制总线、全局锁、决策竞选、分布式会话和集群状态管理等功能。

核心组件

服务注册与发现

  • Eureka:Netflix开源的服务注册中心
  • Consul:HashiCorp开源的服务网格解决方案
  • Zookeeper:Apache开源的分布式协调服务
  • Nacos:阿里巴巴开源的动态服务发现和配置管理平台

配置管理

  • Spring Cloud Config:集中化的外部配置管理
  • Consul Config:基于Consul的配置管理
  • Nacos Config:基于Nacos的配置管理

负载均衡

  • Ribbon:客户端负载均衡器
  • Spring Cloud LoadBalancer:新一代负载均衡器

服务调用

  • OpenFeign:声明式HTTP客户端
  • RestTemplate:传统的HTTP客户端

断路器

  • Hystrix:Netflix开源的断路器(已进入维护模式)
  • Resilience4j:新一代容错库
  • Sentinel:阿里巴巴开源的流量控制组件

网关

  • Spring Cloud Gateway:基于WebFlux的API网关
  • Zuul:Netflix开源的API网关(已进入维护模式)

服务注册与发现示例

Eureka Server

java
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServerApplication.class, args);
    }
}
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServerApplication.class, args);
    }
}
yaml
# application.yml
server:
  port: 8761

eureka:
  instance:
    hostname: localhost
  client:
    register-with-eureka: false
    fetch-registry: false
    service-url:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
# application.yml
server:
  port: 8761

eureka:
  instance:
    hostname: localhost
  client:
    register-with-eureka: false
    fetch-registry: false
    service-url:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

Eureka Client

java
@SpringBootApplication
@EnableEurekaClient
public class UserServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(UserServiceApplication.class, args);
    }
}
@SpringBootApplication
@EnableEurekaClient
public class UserServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(UserServiceApplication.class, args);
    }
}
yaml
# application.yml
spring:
  application:
    name: user-service

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
  instance:
    prefer-ip-address: true
# application.yml
spring:
  application:
    name: user-service

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
  instance:
    prefer-ip-address: true

配置管理示例

Config Server

java
@SpringBootApplication
@EnableConfigServer
public class ConfigServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConfigServerApplication.class, args);
    }
}
@SpringBootApplication
@EnableConfigServer
public class ConfigServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConfigServerApplication.class, args);
    }
}
yaml
# application.yml
server:
  port: 8888

spring:
  cloud:
    config:
      server:
        git:
          uri: https://github.com/your-org/config-repo
          search-paths: '{application}'
# application.yml
server:
  port: 8888

spring:
  cloud:
    config:
      server:
        git:
          uri: https://github.com/your-org/config-repo
          search-paths: '{application}'

Config Client

yaml
# bootstrap.yml
spring:
  application:
    name: user-service
  cloud:
    config:
      uri: http://localhost:8888
      profile: dev
# bootstrap.yml
spring:
  application:
    name: user-service
  cloud:
    config:
      uri: http://localhost:8888
      profile: dev

服务调用示例

OpenFeign

java
@FeignClient(name = "user-service")
public interface UserServiceClient {
    
    @GetMapping("/users/{id}")
    User getUserById(@PathVariable("id") Long id);
    
    @PostMapping("/users")
    User createUser(@RequestBody User user);
}

@RestController
public class OrderController {
    
    @Autowired
    private UserServiceClient userServiceClient;
    
    @GetMapping("/orders/{id}")
    public Order getOrder(@PathVariable Long id) {
        // 调用用户服务
        User user = userServiceClient.getUserById(id);
        // 构建订单信息
        return buildOrder(user);
    }
}
@FeignClient(name = "user-service")
public interface UserServiceClient {
    
    @GetMapping("/users/{id}")
    User getUserById(@PathVariable("id") Long id);
    
    @PostMapping("/users")
    User createUser(@RequestBody User user);
}

@RestController
public class OrderController {
    
    @Autowired
    private UserServiceClient userServiceClient;
    
    @GetMapping("/orders/{id}")
    public Order getOrder(@PathVariable Long id) {
        // 调用用户服务
        User user = userServiceClient.getUserById(id);
        // 构建订单信息
        return buildOrder(user);
    }
}

负载均衡配置

java
@Configuration
public class LoadBalancerConfig {
    
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

@Service
public class OrderService {
    
    @Autowired
    private RestTemplate restTemplate;
    
    public User getUserById(Long id) {
        return restTemplate.getForObject("http://user-service/users/" + id, User.class);
    }
}
@Configuration
public class LoadBalancerConfig {
    
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

@Service
public class OrderService {
    
    @Autowired
    private RestTemplate restTemplate;
    
    public User getUserById(Long id) {
        return restTemplate.getForObject("http://user-service/users/" + id, User.class);
    }
}

断路器示例

Resilience4j

xml
<dependency>
    <groupId>io.github.resilience4j</groupId>
    <artifactId>resilience4j-spring-boot2</artifactId>
</dependency>
<dependency>
    <groupId>io.github.resilience4j</groupId>
    <artifactId>resilience4j-spring-boot2</artifactId>
</dependency>
java
@Service
public class UserService {
    
    @CircuitBreaker(name = "user-service", fallbackMethod = "fallbackUser")
    @Retry(name = "user-service")
    @TimeLimiter(name = "user-service")
    public CompletableFuture<User> getUserById(Long id) {
        return CompletableFuture.supplyAsync(() -> {
            // 调用远程服务
            return userServiceClient.getUserById(id);
        });
    }
    
    public CompletableFuture<User> fallbackUser(Long id, Exception ex) {
        return CompletableFuture.completedFuture(new User(id, "Unknown", "[email protected]"));
    }
}
@Service
public class UserService {
    
    @CircuitBreaker(name = "user-service", fallbackMethod = "fallbackUser")
    @Retry(name = "user-service")
    @TimeLimiter(name = "user-service")
    public CompletableFuture<User> getUserById(Long id) {
        return CompletableFuture.supplyAsync(() -> {
            // 调用远程服务
            return userServiceClient.getUserById(id);
        });
    }
    
    public CompletableFuture<User> fallbackUser(Long id, Exception ex) {
        return CompletableFuture.completedFuture(new User(id, "Unknown", "[email protected]"));
    }
}
yaml
# application.yml
resilience4j:
  circuitbreaker:
    instances:
      user-service:
        sliding-window-size: 10
        minimum-number-of-calls: 5
        failure-rate-threshold: 50
        wait-duration-in-open-state: 30s
  retry:
    instances:
      user-service:
        max-attempts: 3
        wait-duration: 1s
  timelimiter:
    instances:
      user-service:
        timeout-duration: 3s
# application.yml
resilience4j:
  circuitbreaker:
    instances:
      user-service:
        sliding-window-size: 10
        minimum-number-of-calls: 5
        failure-rate-threshold: 50
        wait-duration-in-open-state: 30s
  retry:
    instances:
      user-service:
        max-attempts: 3
        wait-duration: 1s
  timelimiter:
    instances:
      user-service:
        timeout-duration: 3s

API网关示例

Spring Cloud Gateway

java
@SpringBootApplication
public class GatewayApplication {
    public static void main(String[] args) {
        SpringApplication.run(GatewayApplication.class, args);
    }
}
@SpringBootApplication
public class GatewayApplication {
    public static void main(String[] args) {
        SpringApplication.run(GatewayApplication.class, args);
    }
}
yaml
# application.yml
spring:
  cloud:
    gateway:
      routes:
        - id: user-service
          uri: lb://user-service
          predicates:
            - Path=/api/users/**
          filters:
            - StripPrefix=1
        - id: order-service
          uri: lb://order-service
          predicates:
            - Path=/api/orders/**
          filters:
            - StripPrefix=1
            - AddRequestHeader=X-Request-Source, Gateway
# application.yml
spring:
  cloud:
    gateway:
      routes:
        - id: user-service
          uri: lb://user-service
          predicates:
            - Path=/api/users/**
          filters:
            - StripPrefix=1
        - id: order-service
          uri: lb://order-service
          predicates:
            - Path=/api/orders/**
          filters:
            - StripPrefix=1
            - AddRequestHeader=X-Request-Source, Gateway

自定义过滤器

java
@Component
public class AuthGatewayFilterFactory extends AbstractGatewayFilterFactory<AuthGatewayFilterFactory.Config> {
    
    public AuthGatewayFilterFactory() {
        super(Config.class);
    }
    
    @Override
    public GatewayFilter apply(Config config) {
        return (exchange, chain) -> {
            ServerHttpRequest request = exchange.getRequest();
            
            // 验证token
            String token = request.getHeaders().getFirst("Authorization");
            if (!isValidToken(token)) {
                ServerHttpResponse response = exchange.getResponse();
                response.setStatusCode(HttpStatus.UNAUTHORIZED);
                return response.setComplete();
            }
            
            return chain.filter(exchange);
        };
    }
    
    private boolean isValidToken(String token) {
        // 实际的token验证逻辑
        return token != null && token.startsWith("Bearer ");
    }
    
    public static class Config {
        // 配置属性
    }
}
@Component
public class AuthGatewayFilterFactory extends AbstractGatewayFilterFactory<AuthGatewayFilterFactory.Config> {
    
    public AuthGatewayFilterFactory() {
        super(Config.class);
    }
    
    @Override
    public GatewayFilter apply(Config config) {
        return (exchange, chain) -> {
            ServerHttpRequest request = exchange.getRequest();
            
            // 验证token
            String token = request.getHeaders().getFirst("Authorization");
            if (!isValidToken(token)) {
                ServerHttpResponse response = exchange.getResponse();
                response.setStatusCode(HttpStatus.UNAUTHORIZED);
                return response.setComplete();
            }
            
            return chain.filter(exchange);
        };
    }
    
    private boolean isValidToken(String token) {
        // 实际的token验证逻辑
        return token != null && token.startsWith("Bearer ");
    }
    
    public static class Config {
        // 配置属性
    }
}

分布式追踪

Spring Cloud Sleuth

xml
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-sleuth-zipkin</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-sleuth-zipkin</artifactId>
</dependency>
yaml
# application.yml
spring:
  sleuth:
    sampler:
      probability: 1.0  # 采样率
  zipkin:
    base-url: http://localhost:9411
# application.yml
spring:
  sleuth:
    sampler:
      probability: 1.0  # 采样率
  zipkin:
    base-url: http://localhost:9411

微服务架构模式

1. 服务拆分原则

  • 单一职责:每个服务只负责一个业务功能
  • 高内聚低耦合:服务内部高度相关,服务间松散耦合
  • 数据独立:每个服务拥有独立的数据存储
  • 接口稳定:服务间通过稳定的API通信

2. 数据一致性

  • 最终一致性:通过事件驱动实现数据同步
  • Saga模式:分布式事务的补偿机制
  • CQRS:命令查询职责分离

3. 服务治理

  • 服务版本管理:API版本控制和兼容性
  • 服务监控:健康检查、指标收集、日志聚合
  • 服务安全:认证、授权、传输加密

最佳实践

  1. 服务粒度:合理拆分服务,避免过度拆分
  2. 容错设计:实现断路器、重试、超时机制
  3. 配置管理:集中管理配置,支持动态更新
  4. 监控告警:建立完善的监控和告警体系
  5. 自动化部署:实现CI/CD流水线
  6. 文档管理:维护API文档和服务依赖关系
  7. 测试策略:单元测试、集成测试、契约测试
  8. 性能优化:缓存、连接池、异步处理

总结

Spring Cloud为微服务架构提供了完整的解决方案,通过各种组件的组合使用,可以构建出高可用、高性能的分布式系统。选择合适的组件和架构模式,对于微服务项目的成功至关重要。