web应用有一个功能菜单是系统升级,通过调用升级脚本,将新发布的war替换原来的tomcat的webapps下的应用,然后停掉tomcate,再重启tomcate。最初实现就是通过简单的用在web项目中通过Process调用这个upgrade.sh脚本文件的。
  
  但是这种实现方式出现了一个问题:javaweb应用是tomcate,作为upgrade.sh脚本的父进程,当这个upgrade.sh进程试图kill掉父进程并重启的时候,父进程被迫终止后,该子进程也无法继续执行。所以这种方式实现的升级功能总是失败。
  
  解决办法
  
  启动一个小应用,来执行Shell,那么这个应用一直以RMI方式监听来自Java应用的命令,根据相应的命令执行脚本。这样的话,用这个java进程去调用Shell命令杀死tomcate,并重启,以此达到系统升级的目的就不会有问题了。
  
  流程如下:
  
  这里写图片描述
  
  升级程序代码
  
  注册两个命令一个完成系统升级,一个完成Javaweb应用重启,这两个命令的本质就是调用底层的shell脚本完成相应的功能。
  
  import java.rmi.Naming;
  
  import java.rmi.registry.LocateRegistry;
  
  import org.apache.log4j.Logger;
  
  import org.apache.log4j.PropertyConfigurator;
  
  public class ToolkitListener {
  
  public static void main(String[] argv) {
  
  Logger logger =www.jpg521.com  Logger.getLogger(ToolkitListener.class);
  
  try {
  
  //初始化log4j
  
  PropertyConfigurator.configure(ClassLoader.getSystemClassLoader().getResource("log4j.properties"));
  
  // 启动RMI注册服务,指定端口为1099 (1099为默认端口)
  
  LocateRegistry.createRegistry(1099);
  
  //重启命令
  
  CmdInterface restartCmd = new CmdOfRestart("restart");
  
  Naming.rebind("restartCmd", restartCmd);
  
  //系统升级命令
  
  CmdInterface upgradeCmd = new CmdOfUpgrade("upgradeCmd");
  
  Naming.rebind("upgradeCmd", upgradeCmd);
  
  logger.info("Sensor ToolkitListener is ready.");
  
  } catch (Exception e) {
  
  logger.error("Sensor ToolkitListener is failed. " , e);
  
  RMI调用
  
  在Javaweb应用中,通过RMI的方式调用对应的对象的脚本执行方法。
  
  public static  www.wmyl88.com boolean rmiExecute(www.yuheng119.com/ String name, String var){
  
  if(name==null){
  
  return false;
  
  }
  
  //调用RMI的升级对象完成升级
  
  log.info("rmi object is "+name+",variable is:"+var);
  
  try {
  
  switch(name){
  
  case "upgradeCmd":
  
  CmdInterface cmdOfUpgrade = www.sb45475.com (CmdInterface) Naming.lookup("upgradeCmd");
  
  cmdOfUpgrade.setFileName(var);
  
  cmdOfUpgrade.excuteShell();
  
  return true;
  
  case "restartCmd":
  
  CmdInterface CmdOfRestart = (CmdInterface) Naming.lookup("restartCmd");
  
  CmdOfRestart.excuteShell();
  
  return true;
  
  default :
  
  return true;
  
  }
  
  } catch (MalformedURLException e) {
  
  log.error("RMI调用异常",e);;
  
  } catch (RemoteException e) {
  
  log.error("RMI调用异常",e);;
  
  } catch (NotBoundException e) {
  
  log.error("RMI调用异常",e);;
  
  }
  
  return false;
  
  升级文件校验
  
  Java web应用提供系统升级功能,由用户上传升级包,然后调用脚本完成升级。这个过程中需要对升级包进行校验,当前系统中维护了当前系统版本号和升级补丁版本号,上传升级文件中必须提供升级版本的信息,以及上次升级版本号。
  
  web端在启动升级脚本之前,必须进行升级版本验证,只有当前系统版本和补丁版本与升级包描述的上次升级版本和上次升级补丁版本一致时,才是正确的升级补丁包,才会执行升级。
  
  注意事项(一)
  
  升级脚本必须有足够的执行权限才能保证升级脚本能够正确的被执行,如果是新部署的服务器,可能会出现脚本文件权限不足导致升级执行无效。所以部署项目之后,首先需要修改相关脚本的权限,chmod 777 *给与足够权限,否则可能会出现升级无效的情况。这种情况下,将后台执行的shell命令拷贝出来在服务器上执行,很容易看到命令执行失败的原因是No permmition。
  
  注意事项(二)
  
  RMI注册的是本地IP和本地默认RMI端口,127.0.0.1:1099,所以/ect/hosts文件对RMI程序会有影响,项目中有一个IP设置的功能,系统初始化之前已经将服务器主机名称固定了,所以IP修改操作,也必须保证/ect/hosts文件中的主机名称和127.0.0.1的对应关系,否则IP变更后,RMI根据原来的hosts文件的IP查找主机名称时由于IP已经修改了,连接超时,导致升级操作无法进行。
  
  解决办法:IP修改操作的Shell脚本中,完成IP设置后,重置/ect/hosts文件为标准文件,在项目部署的/bin目录下定义一个standardhosts文件,每次IP设置重启网卡之前,重置下该文件内容:
  
  #update /etc/hosts
  
  cat /deploy_path/bin/standardhosts>/etc/hosts
  
  1
  
  2
  
  1
  
  2
  
  注意事项(三)
  
  编写启动该程序的脚本starttoolkit.sh 内容为Java -jar xxx.jar,保证它跟项目tomcate一起开机启动,添加到开机启动项文件tomcat中,以后台程序的方式启动:

开发整理-Javaweb应用的系统升级功能的更多相关文章

  1. IOS开发-OC学习-常用功能代码片段整理

    IOS开发-OC学习-常用功能代码片段整理 IOS开发中会频繁用到一些代码段,用来实现一些固定的功能.比如在文本框中输入完后要让键盘收回,这个需要用一个简单的让文本框失去第一响应者的身份来完成.或者是 ...

  2. 用Vue开发一个实时性时间转换功能,看这篇文章就够了

    前言 最近有一个说法,如果你看见某个网站的某个功能,你就大概能猜出背后的业务逻辑是怎么样的,以及你能动手开发一个一毛一样的功能,那么你的前端技能算是进阶中高级水平了.比如咱们今天要聊的这个话题:如何用 ...

  3. Salesforce 开发整理(五)代码开发最佳实践

    在Salesforce项目实施过程中,对项目代码的维护可以说占据极大的精力,无论是因为项目的迭代,还是需求的变更,甚至是项目组成员的变动,都不可避免的需要维护之前的老代码,而事实上,几乎没有任何一个项 ...

  4. 基于Asterisk的VoIP开发指南——(1)实现基本呼叫功能

    原文:基于Asterisk的VoIP开发指南--(1)实现基本呼叫功能 说明: 1.本文档探讨基于Asterisk如何实现VoIP的一些基本功能,包括基本呼叫功能的方案选取.主叫号码透传.如何编写As ...

  5. 20个开发人员非常有用的Java功能代码

    本文将为大家介绍20个对开发人员非常有用的Java功能代码.这20段代码,可以成为大家在今后的开发过程中,Java编程手册的重要部分. 1. 把Strings转换成int和把int转换成String ...

  6. 升讯威微信营销系统开发实践:(3)功能介绍与此项目推广过程的一些体会( 完整开源于 Github)

    GitHub:https://github.com/iccb1013/Sheng.WeixinConstruction因为个人精力时间有限,不会再对现有代码进行更新维护,不过微信接口比较稳定,经测试至 ...

  7. 升讯威微信营销系统开发实践:(1)功能概要与架构设计( 完整开源于 Github)

    GitHub:https://github.com/iccb1013/Sheng.WeixinConstruction因为个人精力时间有限,不会再对现有代码进行更新维护,不过微信接口比较稳定,经测试至 ...

  8. FastAdmin 开发学习给输入框加上清除功能

    FastAdmin 开发学习给输入框加上清除功能 在社区上有小伙伴询问如果给输入框加上清除功能,因为有时修重新搜索时需要将输入框的内容快速清除,所以这个功能对用户非常友好. 如上图所示这种. 我看了一 ...

  9. EBS开发附件上传和下载功能(转)

    原文地址: EBS开发附件上传和下载功能 上传 Oracle ERP二次开发中使用的方式有两种,一是通过标准功能,在系统管理员中定义即可,不用写代码,就可以使几乎任何Form具有附件功能,具体参考系统 ...

随机推荐

  1. vuex使用mapActions报错解决办法

    先贴上报错: vuex2增加了mapGetters和mapActions的方法,借助stage2的Object Rest Operator 所在通过 methods:{ ...mapActions([ ...

  2. 更新github上代码

    前面一篇已经实现首次上传代码到github了,本篇继续讲如何把本地更新的代码同步更新到github上 一.clone代码 1.把大神的代码clone到本地,或者clone自己github上的代码,使用 ...

  3. Tomcat_总结_02_单机多实例

    一.tomcat下载及环境变量配置 1.tomcat下载 下载地址:tomcat官网 2.环境变量配置 只用配置一个CATALINA_HOME就可以了 二.CATALINA_HOME 与 CATALI ...

  4. Java丨验证码图片去除干扰像素,方便验证码的识别

    1.先来看看效果: 原图 除去干扰像素后 2.解析代码: 1).读取文件夹里面的图片 String fileName = "picture"; BufferedImage img ...

  5. yahoo的30条优化规则

    1.尽量减少HTTP请求次数 终端用户响应的时间中,有80%用于下载各项内容.这部分时间包括下载页面中的图像.样式表.脚本.Flash等.通过减少页面中的元素可以减少HTTP请求的次数.这是提高网页速 ...

  6. 基于libRTMP的流媒体直播之 AAC、H264 推送

    这段时间在捣腾基于 RTMP 协议的流媒体直播框架,其间参考了众多博主的文章,剩下一些细节问题自行琢磨也算摸索出个门道,现将自己认为比较恼人的 AAC 音频帧的推送和解析.H264 码流的推送和解析以 ...

  7. bzoj 2850 巧克力王国 —— K-D树

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2850 只要暴力判断是否全选一个子树或全不选,如果都不是就进入查询: 要注意值有负,所以不是直 ...

  8. 影响Scala语言设计的因素列表

    Scala语言设计概述 Scala的设计受许多编程语言和研究思想的影响.事实上,仅很少的Scala的特点是全新的:大多数都已经被以另外的形式用在其他语言中了.Scala的革新主要来源于它是如何构造并放 ...

  9. RESTEasy常用注解

    一.@Path,标注资源类或方法的相对路径          Path参数的形式有三种:          1.固定值          2.纯正则表达式          3.固定值和正则表达式的混 ...

  10. java try catch 与 throws 使用场景以及怎么合理使用?

    对于如下场景,给出不同的看法: 其实我更多的疑问在于,自定义的方法里面java api抛出了异常,这个时候,我是需要捕获呢?还是我也继续往上抛. 比如,我这里定义了一个日期处理的方法,有两种对异常的处 ...