NacosRule规则导致spring-retry失败踩坑

简介

本文记录springcloud使用RestTemplate请求测试服务重试过程中, 配置NacosRule 权重规则导致spring-retry执行失败踩坑经历

重试是一种容错机制,如果请求后台服务出错,或者服务器故障,会向另一台服务器重试访问

背景

测试springcloud重试机制通过引入spring-retry能够自动请求超时重试其他可用节点。

        <!--ribbon使用spring的重试机制-->
        <dependency>
            <groupId>org.springframework.retry</groupId>
            <artifactId>spring-retry</artifactId>
        </dependency>

  • 测试配置
    • 消费端: 请求超时设置为3秒
    • 提供者7072: 线程睡眠5秒响应 (模拟业务执行超时,触发消费端重试)
    • 提供者7070: 正常响应

问题

使用ribbon得默认策略可以正常使用。但是使用NacosRule作为ribbon负载均衡策略情况下,会出现概率性失效。报错如下
在这里插入图片描述

分析:

通过控制台RetryTemplate有执行日志,说明retry机制是有被触发。连接超时报错,说明第二次可能依然选择了"有故障的节点", 通过观察正常情况日志,服务提供者,默认使用1:1策略,并不是严格交替执行,而是整体保证1:1请求分发。因此可能重试时候取到的将能够出问题的7072服务,因此导致重试依然报错,为了验证假设,将故障服务权重提高到1000,几乎必现。
在这里插入图片描述
原始日志无法显示ribbon实际选择的实例. 自定义RibbonLoadBalancerClient扩展默认实现输入日志。也印证结论

public class CustomRibbonLoadBalancerClient extends RibbonLoadBalancerClient {
    private static final Logger LOGGER = LoggerFactory.getLogger(CustomRibbonLoadBalancerClient.class);
    public CustomRibbonLoadBalancerClient(SpringClientFactory clientFactory) {
        super(clientFactory);
    }

    @Override
    public <T> T execute(String serviceId, ServiceInstance serviceInstance, LoadBalancerRequest<T> request) throws IOException {
        Server server = null;
        if (serviceInstance instanceof RibbonServer) {
            server = ((RibbonServer) serviceInstance).getServer();
            LOGGER.info("请求实际地址:{}", server.getHostPort());
        }

        return super.execute(serviceId, serviceInstance, request);
    }
}

在这里插入图片描述

结论

导致spring-retry失败原因,并不是spring-retry bug.而是NacosRule本身机制导致的。

  • 建议
    线上环境如果开启重试机制不建议使用NacosRule作为ribbon的负载均衡策略, 尽量采用可轮询负载均衡策略。保证触发spring-retry ribbon获取到的是新的节点。因为出现超时的服务,可能出现的服务异常,短时间内再次请求可能依然存在问题。切换不同的实例重试更能够保证高可用。(参考ngnix机制)

源码分析

LoadBalancerAutoConfiguration.RetryInterceptorAutoConfiguration#restTemplateCustomizer 配置拦截器

在这里插入图片描述

RetryLoadBalancerInterceptor

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值