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版本控制和兼容性
- 服务监控:健康检查、指标收集、日志聚合
- 服务安全:认证、授权、传输加密
最佳实践
- 服务粒度:合理拆分服务,避免过度拆分
- 容错设计:实现断路器、重试、超时机制
- 配置管理:集中管理配置,支持动态更新
- 监控告警:建立完善的监控和告警体系
- 自动化部署:实现CI/CD流水线
- 文档管理:维护API文档和服务依赖关系
- 测试策略:单元测试、集成测试、契约测试
- 性能优化:缓存、连接池、异步处理
总结
Spring Cloud为微服务架构提供了完整的解决方案,通过各种组件的组合使用,可以构建出高可用、高性能的分布式系统。选择合适的组件和架构模式,对于微服务项目的成功至关重要。