Feign远程调用失败问题

今天在调试代码的时候遇到了一个远程调用失败的问题,用Feign调用服务名时,无法从服务名解析成对应的URL。FeignClient接口如下:

@FeignClient("blogservice")
public interface BlogClient {

    @RequestMapping("/category/getCategoryListTest")
    List getCategoryList();

    @RequestMapping("/category/getNacosConfig")
    NacosConfigEntity getNacosConfig();

}

按理来说,FeignClient应该将"/blogservice/category/getNacosConfig"解析为Nacos中的blogservice服务,即“http://localhost:8888/category/getNacosConfig”,而我在调用时报错“nested exception is java.net.UnknownHostException”,且调用的URL显示的是服务名称,而不是真正的URL;在我显式指定了FeignClient对应的URL地址后,又能够成功访问了,说明确实出现了服务名解析问题。

//显式指定的方法,相当于写死URL,无法依靠负载均衡策略做分布式,没什么意义
@FeignClient(value = "blogservice", url = "http://localhost:8888/")

没道理啊,我另一个工程代码基本一模一样,调用没一点问题,于是我开始了对这个问题漫长的分析。

首先怀疑是负载均衡失效,Ribbon无法根据服务名寻找到正确的服务,以及它对应的URL。为了印证是负载均衡的问题,我用RestTemplate代替Feign来进行远程调用,同样用服务名来调用服务。这时报出了这样的错误“java.lang.IllegalStateException: No instances available for localhost”,意为没有找到对应的服务实例,而Nacos控制台的服务全部注册成功且健康无比,说明问题确实出现在负载均衡上。

接下来我继续使用RestTemplate,看看调整负载均衡策略是否能解决这个问题。于是我在RestTemplate上加入了@LoadBalanced开启负载均衡,并注入IRule中的随机策略。加入@LoadBalanced的RestTemplate会被加上一个loadBalancerInterceptor拦截器,在这个RestTemplate发起请求时,会将其拦住并寻找对应的实例地址,再根据负载均衡策略进行挑选。

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

    @Bean
    public IRule randomRule() {
        return new RandomRule();
    }

但是代码中IRule一直爆红,怎么都无法引入。IRule来自于“com.netflix.loadbalancer”中,虽然资料显示SpringCloudAlibaba是整合了Netflix相关组件的,但是SpringCloud新版本对于Netflix支持不是很友好,所以我自己引入了一个netflix-ribbon

        
            org.springframework.cloud
            spring-cloud-starter-netflix-ribbon
            2.2.10.RELEASE
        

这个时候IRule确实是不爆红了,再次调用接口还是显示没有服务实例。按理来说负载均衡策略应该已经生效了,数个服务实例也都正常运行,但还是没法正常调用,只能把思路转向另一个方向。

项目一开始的版本管理是SpringBoot 2.5.0 + SpringCloud 2020.0.3 + SpringCloud Alibaba 2.2.5.RELEASE,之前因为SpringBoot与SpringCloud版本有强对应关系,导致Nacos的无法正常启动,因此我调整过对应的版本很多次。但我在让SpringBoot和SpringCloud版本对应的时候,并没有管SpringCloud Alibaba的版本。于是我去搜索了一下他们三者的版本对应关系,果然一查发现SpringCloud Hoxton.SR8才能与SpringCloud Alibaba 2.2.5.RELEASE兼容,说明他们三者存在版本冲突问题。

发现这个问题后,我开始了漫长的排列组合,最后将所有版本回退,使用如下版本才正常了。

        Hoxton.SR8
        2.2.3.RELEASE
        2.3.2.RELEASE

RestTemplate调用正常后,我又用Feign进行远端调用也成功了,且负载均衡策略也正常运行。泪目,这问题是真坑啊。

你可能感兴趣的:(java,微服务)