在《Java 如何调用 SPL 脚本》中我们介绍了在 Java 中可以部署集算器 JDBC 来调用本地 SPL 脚本,那如何能在 Java 中远程调用 SPL 脚本呢?这就是接下来要说的重点!
实现思路通过下图一目了然:
服务器是运行在 Java 平台上面向分析型的高性能数据库,作为高性能计算数据仓库,服务器可以在离线跑批、在线查询、多维分析和内存计算等方面提供高效的计算输出,帮助用户解决计算中的多种问题。
下面我们先来了解一下服务器的使用及配置,更多关于服务器的介绍可参考集算器在线文档《教程》服务器小节。
在集算器安装目录的 esProc\bin 路径下,可以找到 esprocs.exe 文件,可以直接运行它来启动或配置服务器。使用 esprocs 时,会自动在安装路径下加载所需的 jar 包,但是需要注意此时使用的配置文件 raqsoftConfig.xml 和 unitServer.xml 必须放置在集算器安装目录的 esProc\config 路径下。运行后,打开窗口如下:
在 esprocs.exe 执行时,窗口中会显示加载初始设定的信息,这些设定实际上是由配置文件 raqsoftConfig.xml 决定的。在右侧的菜单栏中点击 Options,可以配置服务器的相关信息,点击后弹出服务器配置窗口如下:
在页面中,可以配置授权文件、主路径、寻址路径、日期时间格式、默认字符编码、日志等级、文件缓存区字节数等信息。
下面我们继续来了解服务器的配置,在右侧的菜单栏中点击 Config,可以配置分机的相关信息,点击后在 Unit 页面中可以配置分机信息,如下:
Temp file timeout 设定临时文件的生命周期小时数;Check interval 必须设定为正值或 0,为检查过期的间隔秒数;Proxy timeout 为代理生命周期,即远程游标、任务空间的生命小时数。如果 Temp file timeout 或者 Proxy timeout 设定为 0,则不检查过期。
分机列表 Host list 中,可以配置本机上所有可能用来运行服务器的分机,配置它们的 IP 地址,在进程列表 Process list 中,可以为一个 IP 地址配置多个进程的端口 Port,其中第一个为主进程。服务器启动时,会自动在分机列表中,寻找有空闲进程的分机,然后再由分机将任务交由某个进程执行。需要注意的是,IP 地址需要是本机的真实 IP,在使用多网卡的情况下可以设定多个 IP。
分机配置中,Max task number 是该分机允许执行的最大作业数,而 Preferred task number 是该分机的适合作业数,当分机中使用了多个进程时,适合作业数就是分进程的总数。在 Partitions 一栏中,可以选择每个分机上所使用的分区。
服务器的 Enable clients 页面中可以设定客户端白名单,如下:
选定 Check clients 后,可以在 Clients hosts 列表中,设定允许调用服务器的 IP 地址白名单,不在设定范围中的 IP 地址将无法调用服务器执行计算。
服务器设定完成后,点击 OK,此时可以自动设定对应的配置文件 unitServer.xml 如下:
<?xml version="1.0" encoding="UTF-8"?> <SERVER Version="3"> <TempTimeOut>12</TempTimeOut> <Interval>1800</Interval> <ProxyTimeOut>12</ProxyTimeOut> <Hosts> <Host ip="192.168.107.1" maxTaskNum="8" preferredTaskNum="3"> <Partitions> <Partition name="0" path="d:/file/parallel/node1/0"> </Partition> <Partition name="1" path="d:/file/parallel/node1/1"> </Partition> </Partitions> <Units> <Unit port="8281"> </Unit> <Unit port="8282"> </Unit> </Units> </Host> </Hosts> <EnabledClients check="true"> <Host start="192.168.107.1" end="192.168.107.1"> </Host> </EnabledClients> </SERVER><?xml version="1.0" encoding="UTF-8"?> <SERVER Version="3"> <TempTimeOut>12</TempTimeOut> <Interval>1800</Interval> <ProxyTimeOut>12</ProxyTimeOut> <Hosts> <Host ip="192.168.107.1" maxTaskNum="8" preferredTaskNum="3"> <Partitions> <Partition name="0" path="d:/file/parallel/node1/0"> </Partition> <Partition name="1" path="d:/file/parallel/node1/1"> </Partition> </Partitions> <Units> <Unit port="8281"> </Unit> <Unit port="8282"> </Unit> </Units> </Host> </Hosts> <EnabledClients check="true"> <Host start="192.168.107.1" end="192.168.107.1"> </Host> </EnabledClients> </SERVER>
服务器配置完成后,在分机运行窗口中,点击 Start 即可开始运行服务器,需要停止服务可以点击 Stop,服务器停止后可以点击 Quit 退出。如果点击 Reset,服务将初始化重新启动,清除所有的全局变量以及内存区。
在分机启动时,设置的各个进程会同时启动,可以点击 Main 查看分机主进程的执行情况,或者点击对应的端口号查看分机的其它分进程执行页面。
在 Linux 系统中,可以运行 ServerConsole.sh 来启动服务器类:
打开的分机运行窗口和在 Windows 下是相同的:
此外,还可以在执行命令时添加 -p 参数,非图形启动服务器,此时服务器将直接执行:
将启动 JAVA 应用程序时加载集算器所需的 jar 包及配置文件放到项目中。需要注意的是,集算器 JDBC 所要求的 JDK 版本不得低于 1.6。
集算器 JDBC 类似一个不带物理表的数据库 JDBC 驱动,可以把它简单的看成是一个只有存储过程的数据库。另外,集算器 JDBC 是个完全嵌入式计算引擎,已经在 JDBC 中完成了所有运算,不象数据库那样 JDBC 只是个接口,实际运算在独立的数据库服务器完成。
如果在 web 应用项目下,可以把这些 jar 包放在 WEB-INF/lib 目录下。集算器 JDBC 需要三个基础 jar 包,都可以在 [安装目录]\esProc\lib 目录下找到:
dm.jar //集算器计算引擎及JDBC驱动包 icu4j_3_4_5.jar //处理国际化 jdom.jar //解析配置文件dm.jar //集算器计算引擎及JDBC驱动包 icu4j_3_4_5.jar //处理国际化 jdom.jar //解析配置文件
除了以上的必需 jar,还有一些为完成特定功能的 jar 包:
比如数据库作为数据源,那么还需要相应数据库的驱动 jar 包; 要读写 Office 文件,则需要加入 poi*.jar 和 xmlbeans.jar; 要使用绘制图形功能,则需要加入 SVG 图形处理相关的 jar 包,包括 batik*.jar、js.jar、pdf-transcoder.jar、xalan-2.6.0.jar、xercesImpl.jar、xml-apis.jar、xml-apis-ext.jar。
集算器还有个重要的配置文件 raqsoftConfig.xml,可以在 [安装目录]\esProc\config 下找到,需复制后放置在应用项目的类路径下,配置文件的名称不可改变。
在 raqsoftConfig.xml 文件中,配置了授权信息、集算器主路径、dfx 文件寻址路径、JDBC 远程访问的服务器地址等各类信息。我们先看下最基本的配置,即集算器授权文件和服务器地址的配置:
<?xml version="1.0" encoding=" UTF-8"?> <Config Version="2"> <Runtime> <Esproc> <!--集算器授权文件配置,可以是绝对路径,也可以是相对路径,使用相对路径时是相对于类路径--> <license>esproc.xml</license> <!--试用授权文件可从润乾公司官网中下载--> </Esproc> </Runtime> <JDBC> <!--配置JDBC需远程访问的服务器地址--> <Units> <!--为方便多机热备,可配置多台服务器地址,添加多个<Unit></Unit>节点--> <Unit>192.168.107.1:8281</Unit> </Units> </JDBC> </Config><?xml version="1.0" encoding=" UTF-8"?> <Config Version="2"> <Runtime> <Esproc> <!--集算器授权文件配置,可以是绝对路径,也可以是相对路径,使用相对路径时是相对于类路径--> <license>esproc.xml</license> <!--试用授权文件可从润乾公司官网中下载--> </Esproc> </Runtime> <JDBC> <!--配置JDBC需远程访问的服务器地址--> <Units> <!--为方便多机热备,可配置多台服务器地址,添加多个<Unit/>节点--> <Unit>192.168.107.1:8281</Unit> </Units> </JDBC> </Config>
接下来我们以访问服务器上的数据文件为例,介绍如何在 Java 中远程访问服务器。
Java 通过 SPL 不仅可以访问本地文件,还能远程访问服务器上的数据文件,其中包括 Txt、Excel、Json、Csv、Ctx 等多种类型的文件。
访问时可以通过绝对路径查文件位置,也可以通过相对路径查找。这里的绝对路径和相对路径都是会到服务器上去找。使用相对路径时,则是相对于服务器中 raqsoftConfig.xml 配置文件中的主目录,所以,首先我们来配置下服务器上的主目录:
在 raqsoftConfig.xml 文件的节点中添加以下节点:
<!--集算器主路径,该路径为单一的绝对路径--> <mainPath>D:\\mainFile</mainPath><!--集算器主路径,该路径为单一的绝对路径--> <mainPath>D:\\mainFile</mainPath>
我们把要调用的文件 employee.txt 放到服务器的主目录下面,Java 代码如下:
public void runSPL() throws ClassNotFoundException, SQLException{ Connection con = null; PreparedStatement st; ResultSet set ; //建立连接 Class.forName("com.esproc.jdbc.InternalDriver"); //onlyServer用于控制当前jdbc是否对服务器进行远程计算,为true表示远程计算;false时表示本地计算 //注意:属性值为false,当SPL语句使用call dfx或dfx时,会先使用本地计算,如未计算成功则会进行远程计算 con= DriverManager.getConnection("jdbc:esproc:local://?onlyServer=true"); //直接执行SPL语句,返回结果集 st = (PreparedStatement)con.createStatement(); ResultSet rs = st.executeQuery("$select * from employee.txt"); //简单处理结果集,将结果集中的字段名与数据输出 ResultSetMetaData rsmd = rs.getMetaData(); int colCount = rsmd.getColumnCount(); for ( int c = 1; c <= colCount;c++) { String title = rsmd.getColumnName(c); if( c > 1 ) { System.out.print("\t"); } else { System.out.print("\n"); } System.out.print(title); } while (rs.next()) { for(int c = 1; c<= colCount; c++) { if ( c > 1 ) { System.out.print("\t"); } else { System.out.print("\n"); } Object o = rs.getObject(c); System.out.print(o.toString()); } } //关闭连接 if (con!=null) { con.close(); } }public void runSPL() throws ClassNotFoundException, SQLException{ Connection con = null; PreparedStatement st; ResultSet set ; //建立连接 Class.forName("com.esproc.jdbc.InternalDriver"); //onlyServer用于控制当前jdbc是否对服务器进行远程计算,为true表示远程计算;false时表示本地计算 //注意:属性值为false,当SPL语句使用call dfx或dfx时,会先使用本地计算,如未计算成功则会进行远程计算 con= DriverManager.getConnection("jdbc:esproc:local://?onlyServer=true"); //直接执行SPL语句,返回结果集 st = (PreparedStatement)con.createStatement(); ResultSet rs = st.executeQuery("$select * from employee.txt"); //简单处理结果集,将结果集中的字段名与数据输出 ResultSetMetaData rsmd = rs.getMetaData(); int colCount = rsmd.getColumnCount(); for ( int c = 1; c <= colCount;c++) { String title = rsmd.getColumnName(c); if( c > 1 ) { System.out.print("\t"); } else { System.out.print("\n"); } System.out.print(title); } while (rs.next()) { for(int c = 1; c<= colCount; c++) { if ( c > 1 ) { System.out.print("\t"); } else { System.out.print("\n"); } Object o = rs.getObject(c); System.out.print(o.toString()); } } //关闭连接 if (con!=null) { con.close(); } }
执行结果:
通过上面的使用,相信您已经了解远程访问服务器的部署核心了吧,没错!Java 程序中调用服务器上的运算与调用本地的 SPL 运算操作步骤其实大体相同,总结下主要有如下三点区别:
1,部署服务器
2,JDBC 的 raqsoftConfig.xml 中添加服务器地址
3,在 JDBC 的 url 中添加 onlyServer 属性,属性值为 true,始终访问服务器进行远程计算;属性值为 false,进行本地计算,但当 SPL 语句为 call dfx 或 dfx 时,会先在本地计算,如未计算成功则会进行远程计算
到此,对于远程调用 SPL 脚本的介绍就完了,Java 中调用时更多 SPL 的用法可参见《Java 如何调用 SPL 脚本》这里就不再赘述了,当然,想要更深入的学习 SPL 的小伙伴儿还可以去官网上的在线教程中查看。