工作中遇到一个本地环境偶尔连接不上开发或测试环境的问题,在此记录下排查流程和导致出现该问题的原因。
1.问题描述
正常项目启动成功会出现JVM的启动耗时,如下图:
代表着项目已经启动成功。
这个时候nacos上服务注册有两台,78是我本地ip
此时dubbo元数据中心也是两个
但是异常的是偶尔出现dubbo元数据中心注册不上去的问题:
项目日志到连接nacos就戛然而止,一直未出现JVM启动时间的日志
再看nacos上注册情况
服务注册是正常注册
元数据中心确只有一台
然后通过网关访问也会一直超时无法访问到本地的服务,但直接postman调用本地可以进入。相当于注册中心没注册上去。
2.问题定位
因为日志只有短短一行差别(后面看了源码才知道,其实dubbo有打印日志,但是dubbo日志有点特殊,Dubbo启动日志丢失问题-优快云博客),所以问题比较难定位。
所以这里我用了很蠢的方法(不熟悉dubbo的源码的小白),从springboot启动的时候断点
发现是初始化容器时时间过长,然后通过debug pause找到了死循环的地方。
AbstractServiceDiscovery.getRemoteMetadata这个方法一直在循环调用,然后我在这里发现获取元数据时候,参数里面的ip竟然不是dev环境的ip,这个ip指向的是test环境。
看到这个ip我心里就有猜想了,会不会是dubbo的缓存问题。
于是我把dubbo的本地缓存全部清理了。
然后重新启动,发现还是出现了上面的问题。
没办法只好继续往上层排查,最终在NacosServiceDiscovery.getInstances里面发现namingService缓存获取的地址是nacos的缓存。
于是清理了nacos缓存后发现,项目启动成功。
那到底是什么原因导致启动dev配置,确使用了test的缓存呢?
原因是因为我们开发偷懒,dev环境和test环境namespace的id一模一样,然后nacos读取缓存,又是根据namespace的id来定位的,所以导致两个环境的缓存串了。
3.解决方案
修改两个环境namespace为不同id