在微服务架构中,服务之间的通信可能会由于网络问题、服务暂时不可用或其他临时问题而失败。为了提高系统的可用性和可靠性,引入重试机制是很有必要的。当 Zuul 向后端服务发起请求并遇到错误时,重试机制可以尝试重新发送请求,而不是立即将错误返回给客户端,这样可以减少因暂时性问题导致的请求失败。
注意,Zuul 1.x 的重试机制主要是基于 Ribbon 实现的。Ribbon 是 Netflix 开源的一个客户端负载均衡器,它可以和 Zuul 集成。当 Zuul 发起一个请求到后端服务时,如果请求失败(例如,返回 500 错误或者网络超时),根据配置的重试策略,Zuul 会尝试重新发送请求。
为了使用重试功能,需要引入如下依赖,如下:
<dependency> <groupId>org.springframework.retry</groupId> <artifactId>spring-retry</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency>
其中:
spring-retry 提供了重试功能所需的核心组件。
spring-boot-starter-aop 是 Spring Retry 所依赖的 AOP 功能,用于实现重试的切面。
在 Zuul 项目的 application.yml 中添加如下配置:
# Zuul 重试机制配置 zuul: # 【看这里】 # 开启重试机制 # 此配置告诉 Zuul 允许对路由请求进行重试 retryable: true # 路由配置 routes: service-order: path: /api/order/** service-id: service-order service-product: path: /api/product/** service-id: service-product # ribbon 相关配置 ribbon: # 【看这里】 MaxAutoRetries: 2 MaxAutoRetriesNextServer: 1 OkToRetryOnAllOperations: false # 读取超时时间,单位为毫秒,此处设置为 5 秒 ReadTimeout: 1000 # 连接超时时间,单位为毫秒,此处设置为 2 秒 ConnectTimeout: 2000 # 为所有服务配置统一规则,所有服务都使用轮训策略 NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule
配置说明:
ribbon.MaxAutoRetries:表示对当前服务实例的最大重试次数。
ribbon.MaxAutoRetriesNextServer:如果当前服务器重试失败,表示当切换到下一个服务实例时的最大重试次数。
ribbon.OkToRetryOnAllOperations:是否对所有操作进行重试,默认为 false,通常仅对幂等操作(如 GET 请求)进行重试,因为对于非幂等操作(如 POST 请求)的重试可能会导致副作用。
重启服务,重启后服务注册到 Eureka 如下图:
上图中,SERVICE-ORDER 启动了三个服务。
此时,使用浏览器访问 http://localhost:9000/api/order/order/1 地址(注意,需要参考 Netflix Zuul 主机属性配置章节,将 SERVICE-ORDER 模拟 2 秒),效果如下图:
SERVICE-ORDER 服务1:
SERVICE-ORDER 服务2:
SERVICE-ORDER 服务3:
同上图日志可知,首次请求到“SERVICE-ORDER 服务3”,重试 2 次;然后,再次请求到“SERVICE-ORDER 服务2”,同样重试了 2 次。
点击下载/查看本教程相关资料或者源代码。