背景
本周上线发布了一个小功能,功能很小,就是增加了一个if判断,可以简单理解为下面的情况。
private static final String PREFIX = "xxx";
private boolean valid(String input) {
// 原有逻辑不变
if (input.startsWith("xxx")) {
return false;
}
return true;
}
这段代码相当简单,但是线上运行时,偶尔会发现返回不符合预期。
排查
阶段1:根据日志获取到对应的实际数据,通过main函数方式运行,发现符合预期,代码本身没有问题。
阶段2:分析不符合预期发生的时间,该代码位于一个定时scheduler job中,任务每2分钟执行一次,但是发生问题的时间点并非连续,应用部署在4台机器上,怀疑和某台机器有关系。
阶段3:查看当天上线操作流程,应用原有3台机器,当天正常部署发布了最新代码。部署以后,为提升应用处理性能,做了一个机器扩容,增加到4台机器,所以当天增加的这台机器可能就是问题所在,有可能代码不是最新的。
阶段4:验证猜测。
step1. 登录机器,获取到部署的jar包,解压后获取到对应的class文件。
unzip xxx.jar
step2.反编译class文件。
如果可以下载文件到本地,那么可以利用图形化的工具jad-gui方式,或者直接拖入intellij IDEA。
如果在linux机器上,可以借助jad命令,该程序需要安装。
当然,还有java自带的命令javap,也可以用于反编译,关于javap命令参考:
通过示例代码,可以运行下面的命令,查看当前class文件中是否有对应的private static final String PREFIX变量声明。
javap -private xxx.class
阶段5: 重新部署解决,怀疑该问题还是由于部署和扩容同时进行,可能导致扩容的时候还是部署的旧代码导致的。