同样的代码,开发环境生效,测试环境不生效,记一次问题排查过程和原因分析

我的公众号:IT周瑜

今天有同事遇到这样一个问题,有一个新增接口在本地和开发环境的swagger上都能看到,但是在测试环境的swagger上却看不到,并且确定测试环境是最新的代码,并重新构建和部署了。

按照同事的描述,首先我得确定是不是swagger的问题,我先检查我们平台组是否有对swagger做了改造,发现确实做了改造,但都是很久以前的提交记录了,最近并没有改动。

那有什么办法确定到底是不是swagger的问题呢?问题场景是测试环境swagger上没有看到接口信息,那这个接口到底生效没有呢?调用一下不就知道了,所以我调了一下,404了,所以并不是swagger的问题,而是这个接口本身就没有生效。

那这个接口为什么在测试环境不生效,本地和开发环境却生效呢?为了确认到底是不是代码问题,我把测试环境对应分支的代码在本地跑了起来,发现接口和swagger都是生效的,所以测试分支代码是没有问题的。

那是测试环境有问题?可是要排查环境问题更加毫无头绪,而且我们测试环境是K8S集群,问了运维同事,最近也没有做什么改动。

测试分支代码没有问题,测试环境也假设没有问题,那还有哪里可能会有问题呢?

Jar包!代码没有问题,但是打出来的Jar包到底对不对呢?于是我把测试环境的Jar下载下来,解压,找到问题接口所属Controller类的class文件,用IDEA反编译这个类,发现没错啊!是最新的代码啊!有那个接口啊!怎么明明有Controller,有接口,但接口却没有生效啊?

代码没问题,Jar包似乎也没问题,难道真是环境问题?可是环境问题也不太可能只针对某一个接口,其他接口都不受影响呀。

Jar包的静态代码确实没问题,那运行时的代码呢?这是有可能的,比如某个agent正好把这个接口的代码改掉了?带着这个猜想,我用arthas查看这个类,让我发现了一个惊天大秘密!怎么arthas查看到的代码和Jar包里的代码不一样!怎么arthas查到的类中没有那个接口?也就是说应用运行时的Controller类并不是前面看到的Jar包中的类。

明明类名包名都一样,怎么内容不一样?再仔细看看arthas,发现运行时的这个Controller类所属的Jar包是另外一个Jar包!

这里得解释一下我们微服务工程的目录结构,包含一个server模块和一个或多个core模块,现在问题微服务中就有两个core模块,我分别把它们叫做core1和core2。

回到前面的场景,相当于,在代码中,问题接口Controller类是在core1模块的,core2模块没有这个Controller,但是用arthas查看时,却发现这个Controller在core2,这是为什么?

紧接着,我查看Git提交记录,发现这个Controller本来是在core2的,是最近移动到了core1,并新增了这个出现问题的接口,是移动,并不是复制,所以现有的代码中core2是没有这个Controller类的,那为什么arthas查看到这个Controller在core2?

我接着解压测试环境中core2的jar包,发现这个jar包中确实有这个Controller,也就是当前微服务用到的两个core中都有这个Controller,包名类名都一样,但是内容不一样,core2中是旧版本,core1中是新版本,好了,现在问题的表面原因就是core1中新版本Controller没有生效,而旧版本的Controller生效了,这是因为它们两个类名一样,相当于beanName冲突了,所以只有其中一个生效,而此时旧版本胜出了,它生效了,从而导致新增的接口没有生效。

可是为什么明明现在core2的代码中没有这个Controller了,它对应的Jar中却还有呢?

真相呼之欲出,打包出问题了,是不是jenkons拉的分支被人改了?导致拉到的代码不对,导致打出来的包不对?检查jenkins,发现分支是对的,我直接下载解压jenkins页面上的打包结果,发现确实打出来的包是有问题的,那问题到底在哪?

正当没有头绪,盯着Jenkins的流水线配置发呆时,看到了mvn命令,不对劲!!!不对劲!!!,怎么只有install,没有clean参数啊,再对照开发环境,发现开发环境是有clean参数的,所以开发环境没有问题,测试环境没有clean,所以测试环境有问题!!!!!

到此,问题的根本原因找到了,因为打包时没有clean,由于core2只前有这个Controller,所以target目录下还有它编译出来的class文件,尽管后面把代码从core2移到了core1,但是target目录并没有发生变化,又因为没有clean,所以打出来的core2包中还有历史版本的Controller字节码,从而最终运行时覆盖了core1中的新版本Controller,从而导致新接口没有生效,从而导致swagger页面中没有看到新接口!

这就是解决问题的快乐!

我是IT周瑜,实践出真知,关注我,我将分享更多的实战干货!

相关推荐
也无晴也无风雨34 分钟前
深入剖析输入URL按下回车,浏览器做了什么
前端·后端·计算机网络
憨子周36 分钟前
2M的带宽怎么怎么设置tcp滑动窗口以及连接池
java·网络·网络协议·tcp/ip
霖雨2 小时前
使用Visual Studio Code 快速新建Net项目
java·ide·windows·vscode·编辑器
SRY122404192 小时前
javaSE面试题
java·开发语言·面试
Fiercezm3 小时前
JUC学习
java
无尽的大道3 小时前
Java 泛型详解:参数化类型的强大之处
java·开发语言
ZIM学编程3 小时前
Java基础Day-Sixteen
java·开发语言·windows
我不是星海3 小时前
1.集合体系补充(1)
java·数据结构
P.H. Infinity3 小时前
【RabbitMQ】07-业务幂等处理
java·rabbitmq·java-rabbitmq
爱吃土豆的程序员3 小时前
java XMLStreamConstants.CDATA 无法识别 <![CDATA[]]>
xml·java·cdata