在《Java 如何调用 SPL 脚本》中我们介绍了在 Java 中可以部署集算器 JDBC 来调用本地 SPL 脚本,那如何能在 Java 中远程调用 SPL 脚本呢?这就是接下来要说的重点!
实现思路通过下图一目了然:
部署服务器
服务器是运行在 Java 平台上面向分析型的高性能数据库,作为高性能计算数据仓库,服务器可以在离线跑批、在线查询、多维分析和内存计算等方面提供高效的计算输出,帮助用户解决计算中的多种问题。
下面我们先来了解一下服务器的使用及配置,更多关于服务器的介绍可参考集算器在线文档《教程》服务器小节。
1. 服务器配置
在集算器安装目录的 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>
2. 运行服务器
服务器配置完成后,在分机运行窗口中,点击 Start 即可开始运行服务器,需要停止服务可以点击 Stop,服务器停止后可以点击 Quit 退出。如果点击 Reset,服务将初始化重新启动,清除所有的全局变量以及内存区。
在分机启动时,设置的各个进程会同时启动,可以点击 Main 查看分机主进程的执行情况,或者点击对应的端口号查看分机的其它分进程执行页面。
在 Linux 系统中,可以运行 ServerConsole.sh 来启动服务器类:
打开的分机运行窗口和在 Windows 下是相同的:
此外,还可以在执行命令时添加 -p 参数,非图形启动服务器,此时服务器将直接执行:
部署集算器 JDBC
将启动 JAVA 应用程序时加载集算器所需的 jar 包及配置文件放到项目中。需要注意的是,集算器 JDBC 所要求的 JDK 版本不得低于 1.6。
1. 加载驱动 jar
集算器 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。
2. 部署 raqsoftConfig.xml
集算器还有个重要的配置文件 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 中远程访问服务器。
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 的小伙伴儿还可以去官网上的在线教程中查看。