1. 什么是微服务架构?
微服务架构是一种将单一应用程序划分成一组小型、独立服务的设计风格。每个服务运行在自己的进程中,通过轻量级通信机制(通常是 HTTP RESTful API)进行协作。相比于传统的单体架构,微服务架构具有以下核心优势:
- 独立部署:每个服务可以独立开发、测试、部署和扩展。
- 技术异构:不同服务可以使用最适合其业务需求的技术栈。
- 弹性与容错:单个服务的故障不会导致整个系统崩溃。
- 团队自治:小型、跨职能的团队可以专注于一个或几个服务。
然而,微服务也带来了分布式系统固有的复杂性,如服务发现、配置管理、链路追踪、熔断降级等问题,这正是 Spring Cloud 要解决的。
2. Spring Cloud 简介
Spring Cloud 是基于 Spring Boot 的一套微服务架构综合解决方案。它整合了 Netflix OSS、Consul、Zookeeper 等开源组件,提供了构建分布式系统所需的一系列通用模式(如配置管理、服务发现、断路器、智能路由、微代理、控制总线等)的实现。
Spring Cloud 的核心设计理念是"约定优于配置",通过 Starter 依赖和自动配置,开发者可以快速搭建起生产可用的微服务基础设施。
3. Spring Cloud 核心组件
3.1 服务注册与发现:Eureka / Nacos
服务注册中心是微服务的"电话簿"。服务启动时向注册中心注册自己的网络地址,其他服务通过查询注册中心来发现并调用目标服务。
- Eureka:Netflix 开源的服务发现组件,Spring Cloud Netflix 的核心。
- Nacos:阿里巴巴开源的动态服务发现、配置和服务管理平台,功能更全面。
yaml
# Eureka Server 配置示例
server:
port: 8761
eureka:
client:
register-with-eureka: false # 单机模式下,自己不用注册自己
fetch-registry: false
server:
enable-self-preservation: false # 开发环境可关闭自我保护
3.2 客户端负载均衡:Ribbon / LoadBalancer
当某个服务有多个实例时,负载均衡器负责将请求合理地分发到不同的实例上,以提高系统的吞吐量和可用性。
- Ribbon:Netflix 开源的客户端负载均衡器,已进入维护模式。
- Spring Cloud LoadBalancer:Spring Cloud 官方推出的负载均衡器,是 Ribbon 的替代品。
3.3 声明式服务调用:OpenFeign
OpenFeign 是一个声明式的 HTTP 客户端,它使得编写 Web 服务客户端变得更加简单。你只需要创建一个接口并加上注解,Feign 就会帮你处理请求的构造和发送。
java
@FeignClient(name = "user-service")
public interface UserClient {
@GetMapping("/users/{id}")
User getUserById(@PathVariable("id") Long id);
}
3.4 服务容错与熔断:Hystrix / Resilience4j / Sentinel
在分布式环境中,服务调用失败是常态。熔断器模式可以防止故障的连锁反应,提高系统的弹性。
- Hystrix:Netflix 开源的熔断器组件(已停止新功能开发)。
- Resilience4j:轻量级的容错库,专为 Java 8 和函数式编程设计。
- Sentinel:阿里巴巴开源的流量控制、熔断降级组件。
3.5 服务网关:Spring Cloud Gateway / Zuul
API 网关是所有微服务的统一入口,负责请求路由、负载均衡、认证授权、限流熔断、日志监控等跨横切面功能。
- Spring Cloud Gateway:基于 Spring WebFlux 的反应式 API 网关,性能优异。
- Zuul:Netflix 开源的网关组件(已进入维护模式)。
3.6 分布式配置中心:Spring Cloud Config / Nacos Config
集中管理所有微服务的配置文件,支持动态刷新,无需重启服务即可更新配置。
3.7 分布式链路追踪:Sleuth & Zipkin
用于追踪一次请求在微服务集群中的完整调用路径,帮助定位性能瓶颈和排查问题。
4. 一个简单的 Spring Cloud 微服务示例
下面我们通过一个极简的示例,快速感受 Spring Cloud 的威力。我们将创建三个服务:
- eureka-server:服务注册中心。
- user-service:用户服务,提供用户信息。
- order-service:订单服务,通过 Feign 调用用户服务。
4.1 创建 Eureka Server
使用 Spring Initializr 创建项目,依赖选择 Eureka Server。
java
// EurekaServerApplication.java
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
4.2 创建 User Service
依赖选择 Eureka Discovery Client, Spring Web。
java
// UserController.java
@RestController
@RequestMapping("/users")
public class UserController {
@GetMapping("/{id}")
public User getUser(@PathVariable Long id) {
return new User(id, "张三", "zhangsan@example.com");
}
}
// User.java
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private Long id;
private String name;
private String email;
}
4.3 创建 Order Service
依赖选择 Eureka Discovery Client, OpenFeign, Spring Web。
java
// OrderController.java
@RestController
@RequestMapping("/orders")
public class OrderController {
@Autowired
private UserClient userClient;
@GetMapping("/{orderId}")
public Order getOrder(@PathVariable Long orderId) {
// 模拟订单信息
Order order = new Order(orderId, "商品A", 99.99);
// 通过 Feign 调用用户服务,获取下单用户信息
User user = userClient.getUserById(1L);
order.setUser(user);
return order;
}
}
// 使用 Feign 声明式调用
@FeignClient(name = "user-service")
public interface UserClient {
@GetMapping("/users/{id}")
User getUserById(@PathVariable("id") Long id);
}