引言
大家好!近期,我踏上了一段深入学习Spring Cloud构建微服务应用的旅程。我从项目初始化开始,逐步搭建了一个具备服务注册与发现、客户端负载均衡以及声明式服务调用功能的基础微服务系统。本文旨在记录这一阶段的核心学习内容与实践成果,希望能为同样在探索Spring Cloud的朋友们提供一些参考。
项目源码已托管至GitHub: GitHub - Wilsoncyf/learning-spring-cloud: learning-spring-cloud
一、项目整体架构概览
在深入细节之前,我们先通过下图了解当前项目的整体架构:
当前项目模块: 本项目采用多模块Maven项目结构:
learning-spring-cloud-parent
: 父POM。microservice-eureka-server
: 服务注册与发现中心。microservice-order-service
: 订单服务 (多实例)。microservice-user-service
: 用户服务。microservice-api-gateway
: API网关/服务消费者。
二、奠定坚实基础:项目初始化与环境配置
万丈高楼平地起,一个规范的项目结构和可靠的环境是成功的开端。
- 多模块Maven项目搭建:我们采用多模块Maven项目结构 (
learning-spring-cloud-parent
),这有助于统一管理各微服务模块的依赖版本和插件配置,确保项目整体的规范性。 - 版本选型与管理:经过细致查证与官方文档确认,我们选定了兼容的 Spring Boot
3.3.0
与 Spring Cloud2023.0.5
(Leyton) 版本组合。所有依赖版本均通过父POM的<dependencyManagement>
进行集中管理。 - 构建一致性保障:
- 配置了
maven-compiler-plugin
的-parameters
编译参数,使得Spring MVC在处理请求映射时能正确获取方法参数名,从而简化了Controller层的代码。
- 配置了
三、服务治理核心:Eureka服务注册与发现
在微服务架构中,服务实例的动态变化使得服务间的相互定位成为关键。Eureka为此提供了优雅的解决方案。
- Eureka原理初探:我们探讨了Eureka Server与Client的工作机制,包括服务注册、心跳续约、注册表拉取与本地缓存、服务下线以及自我保护模式等核心概念。
- Eureka Server搭建 (
microservice-eureka-server
):- 成功部署了一个单节点的Eureka Server (运行于端口
8761
)。 - 通过
@EnableEurekaServer
注解启用其功能,并配置其不进行自我注册及关闭自我保护模式(便于开发调试)。 - Eureka Server的Web控制台已能正常访问,为后续服务注册做好准备。
- 成功部署了一个单节点的Eureka Server (运行于端口
- 服务提供者注册 (Eureka Client):
- 创建了两个微服务作为服务提供者:
microservice-order-service
(订单服务):部署了两个实例,分别运行于端口8081
和8091
。microservice-user-service
(用户服务):单实例运行于端口8082
。
- 这三个服务实例均通过引入
spring-cloud-starter-netflix-eureka-client
依赖,并正确配置spring.application.name
和eureka.client.service-url.defaultZone
,成功向Eureka Server注册,并在Eureka控制台上显示为UP
状态。 - 集成了Spring Boot Actuator,其
/actuator/health
端点自动为Eureka提供了健康检查信息。
- 创建了两个微服务作为服务提供者:
四、提升系统弹性:客户端负载均衡 (Spring Cloud LoadBalancer
)
当同一服务有多个实例时,如何有效地分发请求,避免单点过载,是提升系统弹性的关键。
- 负载均衡机制理解:区分了服务器端负载均衡与客户端负载均衡的原理与优缺点。Spring Cloud主要采用客户端负载均衡。
Spring Cloud LoadBalancer
实践:- 创建了
microservice-api-gateway
模块 (运行于端口8080
),作为服务消费者。 - 在其配置类中定义了一个使用
@LoadBalanced
注解的RestTemplate
Bean。 GatewayController
通过这个RestTemplate
,使用服务名(http://microservice-order-service/...
) 调用订单服务。- 成功验证:多次请求API网关后,通过观察订单服务两个实例(8081和8091)的控制台日志,确认请求被以轮询 (Round Robin) 的方式均匀分发,客户端负载均衡有效运作。
- 创建了
五、优雅的服务间调用:声明式客户端OpenFeign
为了简化服务间的调用代码,我们引入了OpenFeign。
- OpenFeign的优势与原理:学习了OpenFeign如何通过创建接口的动态代理,将HTTP调用转换为简单的Java方法调用,其与Eureka和服务负载均衡的无缝集成。
- 集成与改造:
- 在
microservice-api-gateway
中添加spring-cloud-starter-openfeign
依赖,并在主类上使用@EnableFeignClients
。 - 定义了
OrderServiceClient
Feign接口,声明对订单服务的调用。 GatewayController
改造为注入并使用OrderServiceClient
,代码显著简化。
- 在
- 功能验证与配置:
- 负载均衡:通过Feign客户端发起的调用,依然能够被
Spring Cloud LoadBalancer
自动进行负载均衡。 - 日志配置:成功配置了Feign的
Logger.Level.FULL
以及相应包的Logback日志级别,实现了详细的请求/响应日志输出,便于调试。 - 超时配置:学习并实践了如何通过
application.yml
为特定Feign客户端配置连接超时 (connectTimeout
) 和读取超时 (readTimeout
),并通过模拟下游服务慢响应成功验证了超时机制的触发。
- 负载均衡:通过Feign客户端发起的调用,依然能够被
学习心得与总结
本次阶段性学习,让我深刻体会到:
- 版本兼容性的重要性:Spring Boot与Spring Cloud各组件间存在严格的版本对应关系,务必参考官方文档。
- 实践与调试是王道:许多概念只有在动手搭建、遇到问题、分析日志、解决错误的过程中才能真正理解透彻。
- Spring Cloud的强大抽象:它将分布式系统中的复杂问题(如服务发现、负载均衡)通过简洁的注解和配置进行了优雅封装,极大地提升了开发效率。
展望未来
目前,我们的 microservice-api-gateway
模块主要承担了服务消费和简单聚合的角色。接下来,我们将深入学习 Spring Cloud Gateway 的核心功能,将其改造为一个功能更全面的、真正的API网关,探索其强大的动态路由、断言、过滤器等特性。
感谢阅读,期待在微服务的道路上继续探索与进步!