项目场景:Springboot3.1.5 + SpringCloud2022.0.4 + spring-cloud-alibaba-dependencies2022.0.0.0 + Nacos2.2.3 beta + OpenFeign4.0.4
我个人利用空闲时间搭建了一套我认为符合我使用习惯的springboot项目,用来配置一些其他人给的demo进行测试检验
问题描述
我个人比较喜欢使用最新版的各类组件插件所以搭建项目时都是用了当前最新的版本,同样的使用最新版可能就会遇到很多奇葩问题,此处就不对搭建过程进行过多描述了,网上有很多的搭建流程
我采用的结构是base模块加上业务biz模块进行拼接
其中biz里面分为api biz start三个模块组件,展示结构如下图,feign的类是统一放在api目录下面的,业务代码放在biz中,start管理启动
APP 启动类代码:
@EnableDiscoveryClient
@EnableFeignClients(basePackages = {"com.wjn.**.feign"})
@MapperScan(basePackages = {"com.wjn.**.mapper"})
@SpringBootApplication(scanBasePackages = {"com"})
public class Auth {
public static void main(String[] args) {
SpringApplication.run(Auth.class, args);
}
}
项目可以完成启动 但是启动完通过Feign进行调用时出现奇怪问题
Cannot invoke “Object.hashCode()” because “key” is null
原因分析:
初看这个问题时 感觉是nacos没有配置好导致feign没扫描到。其实这些问题我已经在启动类都处理好了,网上各种查询问题解决方案 从nacos的配置到feign的配置等等还查到不能直接在com下声明要加一层包名等等:
最后查到新版feign已经移除ribbon所以要增加一个loadbalance依赖
最终问题就出现loadbalance上面了
解决方案:
最终的解决方式是增加loadbalance的配置:
import org.springframework.cloud.loadbalancer.core.RandomLoadBalancer;
import org.springframework.cloud.loadbalancer.core.ReactorServiceInstanceLoadBalancer;
import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier;
import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.core.env.Environment;
public class MyLoadBalancerConfig {
@Bean
public ReactorServiceInstanceLoadBalancer reactorServiceInstanceLoadBalancer(Environment environment, LoadBalancerClientFactory loadBalancerClientFactory) {
String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
//返回随机轮询负载均衡方式
return new RandomLoadBalancer(loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name);
}
}
问题就是没配置的时候 loadBalancerClientFactory.getLazyProvider参数name是null,feign调用的时候name是null所以才导致根据key获取服务列表的时候key为空空指针了,加完负载均衡的配置之后还需要在启动来加上负载均衡的配置 value值是要调用目标服务的服务名,多个服务就多个配置
@LoadBalancerClients(
@LoadBalancerClient(value = "ms-account", configuration = RandomBalancerConfig.class)
)