近两年项目回顾系列——基于Flex和RMI的自动化部署工具
上一篇博文《RMI初步》我们简单讲述了RMI的实现原理和demo,现在讲讲我们在某项目中基于Flex和RMI开发的自动化部署工具。
需求描述:
我们的项目部署主要包括两部分,jar包和Flex编译生成的swf文件,特别是swf文件可能文件较大,且在系统试运行期间部署可能非常频繁。如何将其快速地部署到几十台机器的集群上,且出错能迅速rollback回之前的版本将是我们面临的一个问题。后来我们开发了这样一个工具,大体思路是:使用adobe air开发成一个.exe格式的工具,安装后可以快速将本机的文件上传到该软件的server上(此server相对各个集群机器而言是RMI的Client),然后server使用RMI迅速同步到集群的各个机器上。其中包括简单的版本管理,使用“年月日+自增的版本号”作为版本管理,出现问题可迅速回退到之前版本。
所用技术:
Flex+BlazeDS+Spring+RMI
主要代码:
FileUpServer.java,在集群的每个节点机器上运行,监听远端的调用。
package com.dc.rmi.server; import java.net.MalformedURLException; import java.rmi.Naming; import java.rmi.RemoteException; import java.rmi.registry.LocateRegistry; import org.apache.log4j.Logger; import com.dc.rmi.config.RmiConfig; /** * 文件上传主程序 * */ public class FileUpServer { public static Logger log = Logger.getLogger(FileUpServer.class); /** * server主程序 * @param args * @throws RemoteException * @throws MalformedURLException * @throws Exception */ public static void main(String[] args) throws MalformedURLException, RemoteException, Exception { //1.==创建并安装安全管理器 if(System.getSecurityManager()==null){ System.setSecurityManager(new RMISecurityManager()); } try{ //==1.定义远程对象 FileUpRemoteImpl fur=new FileUpRemoteImpl(); LocateRegistry.createRegistry(12345); //==2.注册远程对象 String url = "//"+RmiConfig.getRemoteParam("remote_server_ip")+":"+RmiConfig.getRemoteParam("remote_server_port")+"/"+RmiConfig.getRemoteParam("remote_server_name"); Naming.rebind(url, fur); log.debug("server is starting on "+RmiConfig.getRemoteParam("remote_server_ip")+":"+RmiConfig.getRemoteParam("remote_server_port")+"/"+RmiConfig.getRemoteParam("remote_server_name")+" ......"); }catch(MalformedURLException ex){ ex.printStackTrace(); throw new Exception("URL出错,可能是一下原因【URL协议、格式或者路径错误】、【jar问题】.详细信息【"+ex.getMessage()+"】"); }catch(RemoteException ex){ ex.printStackTrace(); throw new Exception("URL出错,可能是一下原因【通信失败(远程服务器不可达、拒绝连接或连接被关闭等)】、【参数按引用传递失败或者返回值无法正常编组解编组】、【协议错误】.详细信息【"+ex.getMessage()+"】"); }catch(Exception ex){ ex.printStackTrace(); throw new Exception("其他错误:"+ex.getMessage()); } } }
我们Flex应用调用的程序:
FileUpClient.java,Flex端将本地文件上传到tomcat的对应版本目录下,然后选择“版本同步”时,将每个版本目录下的文件调用此方法来同步到各个集群机器上:
/** * 上传文件到服务器 * @param rsIp * @param rsPort * @param rsName * @param filePath * @param fileContent * @return * @throws Exception */ public static boolean upFile2Server(String rsIp,String rsPort,String rsName,String filePath,byte[] fileContent)throws Exception{ try{ String url = "//"+rsIp+":"+rsPort+"/"+rsName; //获取远程对象 FileUpRemote fur = (FileUpRemote) Naming.lookup(url); //读取文件 fur.upFile(filePath, fileContent); }catch(MalformedURLException ex){ ex.printStackTrace(); throw new Exception("URL出错,可能是一下原因【URL协议、格式或者路径错误】、【jar问题】.详细信息【"+ex.getMessage()+"】"); }catch(RemoteException ex){ ex.printStackTrace(); throw new Exception("URL出错,可能是一下原因【通信失败(远程服务器不可达、拒绝连接或连接被关闭等)】、【参数按引用传递失败或者返回值无法正常编组解编组】、【协议错误】.详细信息【"+ex.getMessage()+"】"); }catch(NotBoundException ex){ ex.printStackTrace(); throw new Exception("URL出错,可能是一下原因【通信失败(远程服务器不可达、拒绝连接或连接被关闭等)】、【参数按引用传递失败或者返回值无法正常编组解编组】、【协议错误】.详细信息【"+ex.getMessage()+"】"); }catch(Exception ex){ ex.printStackTrace(); throw new Exception("其他错误:"+ex.getMessage()); } return true; }
Flex前端的代码就不上了,来一个演示效果吧:(编译时没有加style、skin皮肤,比较丑)
选择一个文件,比如,我们选择D盘下的一个web.xml文件,拖到右侧待上传的框中,点击【文件上传】
点击【文件上传】,将会把一个文件上传到tomcat
点击【转到服务器同步】显示已经在项目的server.xml中配置好的远程服务器信息,点击【文件同步】,将会把tomcat下的20130530_7版本覆盖远端机器的20120126_2版本。
OK,目前基本上是这样一个情况,经过测试,可靠性不错,目前已经可以使用了。剩下来的是加上皮肤文件、css,调一调排版,打扮漂亮一些,让工具更加易用:), 同时准备在服务端起一个timer,定时(如每隔1分钟)检测是否有新版本,有则同步到所有的集群机器上。这样的话,我们以后的版本发布只用上传swf和jar包。
至此,RMI的讨论和学习暂时告一段落,欢迎交流。