Spring Cloud 微服务:从入门到实践
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服务注册中心是微服务的“电话簿”。服务启动时向注册中心注册自己的网络地址其他服务通过查询注册中心来发现并调用目标服务。EurekaNetflix 开源的服务发现组件Spring Cloud Netflix 的核心。Nacos阿里巴巴开源的动态服务发现、配置和服务管理平台功能更全面。# Eureka Server 配置示例 server: port: 8761 eureka: client: register-with-eureka: false # 单机模式下自己不用注册自己 fetch-registry: false server: enable-self-preservation: false # 开发环境可关闭自我保护3.2 客户端负载均衡Ribbon / LoadBalancer当某个服务有多个实例时负载均衡器负责将请求合理地分发到不同的实例上以提高系统的吞吐量和可用性。RibbonNetflix 开源的客户端负载均衡器已进入维护模式。Spring Cloud LoadBalancerSpring Cloud 官方推出的负载均衡器是 Ribbon 的替代品。3.3 声明式服务调用OpenFeignOpenFeign 是一个声明式的 HTTP 客户端它使得编写 Web 服务客户端变得更加简单。你只需要创建一个接口并加上注解Feign 就会帮你处理请求的构造和发送。FeignClient(name user-service) public interface UserClient { GetMapping(/users/{id}) User getUserById(PathVariable(id) Long id); }3.4 服务容错与熔断Hystrix / Resilience4j / Sentinel在分布式环境中服务调用失败是常态。熔断器模式可以防止故障的连锁反应提高系统的弹性。HystrixNetflix 开源的熔断器组件已停止新功能开发。Resilience4j轻量级的容错库专为 Java 8 和函数式编程设计。Sentinel阿里巴巴开源的流量控制、熔断降级组件。3.5 服务网关Spring Cloud Gateway / ZuulAPI 网关是所有微服务的统一入口负责请求路由、负载均衡、认证授权、限流熔断、日志监控等跨横切面功能。Spring Cloud Gateway基于 Spring WebFlux 的反应式 API 网关性能优异。ZuulNetflix 开源的网关组件已进入维护模式。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。// 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。// UserController.java RestController RequestMapping(/users) public class UserController { GetMapping(/{id}) public User getUser(PathVariable Long id) { return new User(id, 张三, zhangsanexample.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。// 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); }