前一段时间开发公司的大数据项目,做完后一直想去总结一下,确不知道从哪里开始.思来想去就从这个项目中让我最有成就感的一段说起.
在这个项目中,我的同时们开发了几个的spark的批处理工程,这些工程在最初的设计中是由hue调度的.但是计划赶不上变化,最终项目即将上线时发现生产上不允许使用cdh,所以这几个批处理工程怎么去定时启动成了一个问题.尤其是这几个项目要求有严格的先后执行顺序.所以想用linux的定时任务去执行shell很难写,并且也很难维护.
这里我想到了java可以开辟一个进程,然后用这个进程去启动外部程序的方式去解决问题.那就是Runtime.getRuntime()
Runtime.getRuntime().exec(shell)可以做很多事,比如去启动一个jar包,正好能够解决我现在的问题.进一步研究发现该方法会返回一个Process对象.该对象描述了这个子进程的很多状态.其中有一个waitFor()方法.可以在子进程未执行完之前阻塞掉当前线程.这个特点正好能解决我想要做的流程控制.每执行一个程序都可以将其阻塞.等执行完成后再执行下一个程序并继续阻塞.到这一步我这个功能基本开发完成.我这里使用了几个定时任务,在规定时间去启动那几个spark程序完成计算任务.
深入研究后发现Process对象有更多好用的东西,getInputStream()方法可以获取子进程中的标准输出流,(我们常用的System.out里面的数据会被getInputStream()给读取到).还有getErrorStream(),可以获取错误输出流(我们常用的System.err里面的数据会被getErrorStream()给读取到).利用这两个方法,我可以进一步的将子进程的执行日志记录到主进程中.方便后续排查问题.System里面还有一个变量System.in 我们可以通过Process.getOutputStream()向子进程中写入数据,而system.in则可以获取到这些数据.