远程发布的设计和实现
在实施门户部署时,部分客户会有内外网都要的需求,即内容信息维护在内网完成,内网用户可以通过内网直接访问门户,但同时需要加门户发布到外网,供Internet上用户访问,内外网的信息需要保持同步。
第一步需要将动态的门户页面全部发布成静态html页面(可参考我的另外一篇日志《门户站点静态发布的设计与实现》,访问地址:http://infinite.iteye.com/blog/390687);
第二步还需要将第一步发布出来的静态html页面以及相关的图片、js、css文件等远超发布到外网服务器,同时外网访问出于性能考虑,可能需要做负载均衡,还需要远超发布时能支持发布至多台外网服务器上。
以下具体讲述下第二步远程发布的设计思路和具体实现。主要将借助开源组织apache的common-net.jar包的FTPClient类。
一、 编写远超发布配置信息文件
配置信息需要包含有外网服务器的ftp访问地址、用户名、密码,以及内网服务器需要上传至外网服务器的目录信息。格式如下:
<ftpServer url="192.168.0.31" userName="root" password="password"> <filePath localDir="d:/。。。/webapp/html" remoteDir="temp/html"/> <filePath localDir="d:/ 。。。/webapp/core" remoteDir="temp/core"/> <filePath localDir="d:/ 。。。/webapp/model" remoteDir="temp/model"/> <filter-pattern>index,articleList</filter-pattern> </ftpServer> |
二、 解析配置文件,创建FTP连接
根据上面配置文件ftpServer的信息,可创建一个FTPClient连接。代码参考如下:
private void connect2FtpServer(String url, String user, String pwd) throws SocketException, IOException { this.ftp = new FTPClient(); ftp.connect(url); ftp.login(user, pwd); int reply = ftp.getReplyCode(); if (!FTPReply.isPositiveCompletion(reply)) { ftp.disconnect(); } this.remoteRoot = ftp.printWorkingDirectory(); } |
三、 上传文件(夹)
创建了FTP连接后,就可以利用该连接进行文件的ftp上传操作。这里有几点需要注意:
1、按本地上传的文件夹的目录结构,在外网服务器上对应的文件夹下创建一模一样的目录结构。
/** * 在上传文件夹的过程中,如果服务器的目标目录中和上传文件夹的目录有区别 则创建各级目录。 * @param remoteDir * @param relativePath */ private void makeDirectory(String remoteDir, String relativePath) { try { ftp.changeWorkingDirectory(this.remoteRoot); // 先切换到根目录下 relativePath = remoteDir + "/" + relativePath; String[] dir = relativePath.split("/");// 目录分级 for (int i = 0; i < dir.length; i++) { if (!ftp.changeWorkingDirectory(dir[i])) {// 是否有子目录dir[i] ftp.makeDirectory(dir[i]); } ftp]);.changeWorkingDirectory(dir[i } } catch (Exception e) { log.error("在ftp服务器上创建相应目录时候出错", e); } } |
2、过滤掉无需重复上传的文件。如何过滤规则可以根据需要制定。比如,配置文件里可加入<filter-pattern>index,articleList</filter-pattern>的匹配配置,表示文件名包含index或者articleList字样的文件每次都要上传;还可以根据文件的最后修改时间来判断是否需要上传该文件(比如三小时内修改过的文件上传,其余不上传,可结合第四步的定时机制)。
指定好了上传目录,上传文件很简单,只需简单的调用FTPClinet的storeFile方法。可参考下面代码:
String fileName = file.getName(); // 本地文件名 FileInputStream input = new FileInputStream(file); ftp.storeFile(fileName, input); |
四、 定时远程发布到外网服务器
通过上面三个步骤,已经可以将内网服务器的文件顺利发布至外网服务器,但是我们还是需要做一定的优化。
首先什么时候触发远程发布。为了保证内外网信息实时同步,最理想的方式就是内网内容一更新,即触发远程发布,将更新内容发布至外网服务器。但这样导致的性能问题非常严重。因为存在多个内容维护的管理员,可能每个人都在做远程发布,这就需要多个ftp连接,非常耗费资源,且相互间还会影响彼此的上传速度。
针对上面问题,使用定时远程发布可以带来比较好的性能提升。这需要在本地(即内网服务器)上创建一个守护进程,由它不停的检测本地需要上传的目录,发现有更新且到达定时时间(比如15分钟),则启动远程发布。否则不启动。这样可保证始终只有一个ftp连接,多个管理员同时更新内容不会相互影响彼此上传速度。只不过这样一定程度上了牺牲内容的实时更新(会稍微有所延迟)。