最近公司生产环境(SpringBoot + Dubbo)中,消费端在service中,部分使用@Reference的接口,在方法中调用的时候出现NullPointerException。
日志显示如下内容:
<dubbo:reference singleton="true" interface="com.xxx.XxxxxDubboSerivce" uniqueServiceName="com.xxx.XxxxxDubboSerivce" filter="" listener="" generic="false" id="com.xxx.XxxxxDubboSerivce" />
其中缺少了object属性,正常日志应该类似如下:
<dubbo:reference object="com.alibaba.dubbo.common.bytecode@9f6e406" singleton="true" interface="com.xxx.XxxxxDubboSerivce" uniqueServiceName="com.xxx.XxxxxDubboSerivce" filter="" listener="" generic="false" id="com.xxx.XxxxxDubboSerivce" />
那么问题就转化为:为什么被@Reference注解的属性没有生成代理对象?
1,配置问题,dubbo.consumer.check=false,没什么问题,排除该原因。
2,网络抖动,导致消费端没有连接上zookeeper,经dubbo源码调试发现,此时object代理对象的生成不需要连接上zookeeper,排除该原因。
3,dubbo本地缓存问题,清除缓存,问题照样出现,排除该原因。
4,更换动态代理方式、使用懒加载、去除@Transactional改成编程式事务......
能够稍微和问题沾边的,都试了个遍,还是不行,快奔溃了,还是找不到原因。最后直接修改源码,ReferenceConfig.createProxy()中,跳过中间一大段逻辑,最后return (T) proxyFactory.getProxy(invoker),问题解决,正常生成代理对象。
此时再倒推,createProxy()方法中,Boolean c = check 修改为 Boolean c = false; 代理对象正常生成,不再出现空指针问题。而Boolean c = check中的check是由dubbo.consumer.check来控制的,为什么dubbo.consumer.check=false设置无效?
继续一步步向前修改调试源码,最终发现,某些工程中的application.yml中,需要在false上加上双引号,也就是dubbo.consumer.check="false"才能使得配置生效。
晕倒。
网友评论