由System.out.println引发的血案

问题描述

K线异动项目,之前是部署在虚拟机服务器上的,最近准备将其迁移到docker集群。这个项目有点特别,包含了Java和PHP两部分,Java实现前端http服务以及job任务,然后在job任务中,会调用PHP脚本来生成一些数据文件,并同步到资讯服务器上。

项目迁移到docker后,发现数据文件没有生成。因为项目距离最开始的开发已经有一段时间了,一些细节已经记不大清楚了,从线上服务器的日志来看,也没有看到什么报错信息(error日志里面没有内容),再加上发布后,Java程序只有一个可执行jar文件,不像PHP这样可以在线调试,因此这个问题解决起来比较麻烦。

最后,经过3个小时的排查(期间docker重新发布了N次,效率极低),终于发现,是因为docker容器中,PHP CLI的路径和配置文件中设置的不一致,导致Java调用PHP脚本没有成功导致的。

因为Java调用PHP脚本的代码,try/catch的catch里面,是直接将捕获到的异常信息输出到了控制台,类似这样:

1
2
3
4
5
6
try {
// 调用PHP脚本命令
} catch (Exception exp) {
// 直接将错误信息输出到控制台
System.out.println(e);
}

我们的logback日志里面是没有记录控制台输出信息的,因此日志中看不到这个异常,让我们误以为程序没有抛异常。

知道问题后,修改配置,将docker容器中的PHP CLI路径修正,即可解决问题。

总结

1、线上代码,不要用System.out.println()来输出你希望看到的日志信息,一定要通过日志工具(比如logback)记录到日志文件中!

2、日志的设计非常重要,否则线上环境一旦出现问题,你无法获取太多信息,会很难定位。