先说下项目背景,为了统一公司的schedule job,做了一个job的框架,定时任务统一接入到这个框架里面。
job框架用java开发,原理很简单,解析用户输入的crontab表达式,到了schedule的时间,用ProcessBuilder把用户的程序给带起来。
今天有同事反应,程序在本地可以正常运行,接入job框架后出现大量的SOA远程调用timeout。
第一反应是资源文件加载路径的问题,怀疑是不是读错了配置文件,再三检查发现一切无误。
打印线程堆栈后发现,所有的线程都卡死在了logback记日志的地方,大家都在等待一把锁,堆栈里面没能发现谁持有了这个锁对象。
从以下几点着手排查:
1. 怀疑是jar包冲突,job框架本身使用的logback版本和用户程序使用的logback版本冲突。于是一番折腾,无果。
2. 怀疑是SOA框架里面记日志的地方有冲突,再三check,还是无果。
然后发现用户的log配置,除了写磁盘以外,还会输出到console,于是改了下配置文件,不再输出到console,发现不再死锁。
于是赶紧的查了下jdk里面关于process的描述,摘录如下:
By default, the created subprocess does not have its own terminal or console. All its standard I/O (i.e. stdin, stdout, stderr) operations