背景
在使用ftp下载插件时,发现进行本地执行时可以正常,但当选择了远程执行并指定了远程服务器后发现出现了错误:从 FTP:User cannot log in. 获取文件时发生错误。根据错误信息可以判断是因为ftp登录不上的原因,至于具体的原因无法定位,为了一探究竟,于是便萌生了调试远程作业的想法,顺便深入了解一下了解kettle运行原理以及源码学习。
思路
carte服务器实际上就是一个web server,该web server 是基于 Jetty 这个嵌入式的开源 servlet 容器。这个web server主要是提供转换运行的环境,另外一个重要的功能通过提供servlet来在客户端、主服务器和从属服务器之间进行通讯和控制。主服务器和从属 服务器之间是通过httpClient来进行通讯的,通讯时传递的数据是xml格式。通过提供的servlet,可以实现启动、停止、暂停转换或者作业、 获得转换或者作业的状态、注册子服务器、获得子服务器的列表等等.
其实思路以及LZ使用的方法很简单:通过java代码在eclipse中启动一个Carte服务器,然后远程执行作业时指定服务器作为载体。
搭建Carte服务启动环境
首先创建一个普通的java project项目,如果没有kettle源码环境的话可以创建maven project,这样直接从中心仓库上面获得jar包以及源码。刚好LZ之前有编译过kettle源码且已 经作为项目导入了eclipse中,所以 源码以及相关kettle的jar包都已经有了。
创建了项目后,需要把相关的jar包加到java bulid path中,下面的jar包也可以从PDI工具的lib目录下获得:
把依赖包加入到项目中后,创建一个类来启动Carte服务:
public class CarteServer {
publicstaticvoid main(String[] args) throws Exception {
SlaveServerConfig config =new SlaveServerConfig("192.168.31.43", 7088, true);//ip与端口与通过Carte.bat启动时指定的参数一样
Carte.runCarte(config); //通过该静态方法启动carte
}
}
开始远程调试
- 启动carte服务,建好CarteServer类后,直接debug as --> java application,即可启动carte服务,在控制台可以看到以下信息:
2016/08/11 10:55:55 - Carte - 创建web服务监听器@地址: 192.168.31.43:7088
2016-08-11 10:55:55.912:INFO::jetty-6.1.26
2016-08-11 10:55:55.933:INFO::Started SocketConnector@192.168.31.43:7088
- 打开spoon工具,创建一个job,下面的job是从ftp服务器上下载文件:
- 因为作业用到了FTP下载插件,在源码中对应JobEntryFTP类,打开该类并在execute()方法中打上断点:
- 运行job,选择远程执行,选择上述类CarteServer中启动的服务器(要先在spoon工具中新建一个子服务器):
- 观察断点位置,看到已经进入了调试:
大功告成,至于ftp下载插件为什么在远程执行中错误另外说明。
远程执行流程
- 用户运行kettle作业并选择“远程执行”,触发org.pentaho.di.job.Job类的sendToSlaveServer方法
- 在sendToSlaveServer方法中,首先生成XML格式的作业元数据描述。
- 调用SlaveServer的sendXML()方法把这些元数据会被发送到远程的carte服务器。
- 服务器端AddJobServlet接收到请求后,进入doGet()方法通过元数据构造出Job实体并把作业保存到JobMap中。
- 在sendToSlaveServer方法中,把XML发送到carte服务器后,接着调用SlaveServer的execService()方法进行启动远程的job
- 此时服务器端StartJobServlet会接收到请求后,会给job(其实是一个Thread)做一堆初始化工作,最后调用job的start方法进行启动。