`
dong_1112
  • 浏览: 848 次
  • 性别: Icon_minigender_1
  • 来自: 济南
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

tomcat服务outOffMemory错误,自动重启服务

阅读更多
  整个重启服务思路如下:
    1、每个服务器定时(比如一分钟,可配置)监控本身内存使用情况(当然cpu使用情况也可以监控),若空闲率小于某个指定值(如20%)时就把系统运行参数(内存空闲率、线程信息、连接池信息、本身tomcat路径信息)记录到数据库表
    2、在业务tomcat服务之外另开一个服务,来定时(比如一分钟)检测数据表,看有没有内存空闲小某个指定值(如10%以下,可配置),若有则调用外部操作系统命令重启此tomcat服务。
   
二、tomcat相关脚本
    1、tomcat服务操作系统外部启动脚本startup.bat
d:
cd D:\Tomcat5.5\bin
D:\Java\jdk1.5.0_07\bin\java.exe -Xms128m -Xmx128m -Xmn64m -Dport=8000 -jar .\bootstrap.jar -Dcatalina.home=D:\Tomcat5.5 -Dcatalina.base=D:\Tomcat5.5  -Djava.endorsed.dirs=D:\Tomcat5.5\common\endorsed -Djava.io.tmpdir=D:\Tomcat5.5\temp  -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.util.logging.config.file=D:\Tomcat5.5\conf\logging.properties start
exit

    2、tomcat服务操作系统外部关闭脚本
d:
cd D:\Tomcat5.5\bin
D:\Java\jdk1.5.0_07\bin\java.exe  -jar .\bootstrap.jar stop
exit

三、监控代码简例

1、业务服务里运行信息记录代码及配置
  A、监控spring常量配置
    <bean id="memoryConstantConf" class="com.chinacti.commons.dao.ibatis.MemoryConstantConfig">
       <constructor-arg>
          <map>
     <entry key="8000">
         <value>D:/Tomcat5.5/bin</value>
       </entry>
       <entry key="9000">
         <value>D:/Tomcat5.5_ibatis/bin</value>
       </entry>
       <entry key="leFree">
         <value>20</value>
       </entry>
   </map>
       </constructor-arg>
    </bean>
   B、监控常量定义代码MemoryConstantConfig.java
//配置单例
public static MemoryConstantConfig instance = null;
public MemoryConstantConfig( Map info){
  monitorInfo = info;
 
  //设置当前tomcat路径
  String port = System.getProperty( "port" );//取得在当前tomcat启动脚本中设定的当前虚拟机的system属性
  String tomcatPath = (String)monitorInfo.get( port );
  this.setCurrentTomcatPath( tomcatPath );
 
  //设置监控的最小空闲率
  String leFree = (String)monitorInfo.get( "leFree" );
  int iLeFree = Integer.parseInt( leFree );
  this.setILeFree( iLeFree );
 
  //设置tomcat重启时间
  String tRestartMillis = (String)monitorInfo.get( "tomcatRestartMillis" );
  if( tRestartMillis == null ){
   tRestartMillis = "10000";
  }
  int iTRestartMillis = Integer.parseInt( tRestartMillis );
  this.setTomcatRestartMillis( iTRestartMillis );
 
  //设置apache重启时间
  String aRestartMillis = (String)monitorInfo.get( "apacheRestartMillis" );
  if( aRestartMillis == null ){
   aRestartMillis = "15000";
  }
  int iARestartMillis = Integer.parseInt( aRestartMillis );
  this.setApacheRestartMillis( iARestartMillis );
 
  instance = this;
}
public static MemoryConstantConfig getInstance(){
  return instance;
}

C、quarz job内存使用率记录代码简例
protected void executeInternal(JobExecutionContext arg0)
   throws JobExecutionException {
  try{
   log.info( "内存监控开始..." );
   //声明一个监控对象
   MemoryMonitor monitor = new MemoryMonitor();
  
   //获取当前连接池信息
            Context initCtx = new InitialContext();
         
         //获取连接池对象
         BasicDataSource ds = (BasicDataSource) initCtx.lookup("java:comp/env/jdbc/OracleDS");
  
   monitor.setDbcpActiveNum( ds.getNumActive() );
   monitor.setDbcpIdleNum( ds.getNumIdle() );
        
         //获取线程运行情况信息
         java.util.Iterator it = Thread.getAllStackTraces().values().iterator();
         StackTraceElement[] e = null;
         String stackInfoStr = "";
         int index = 0;
         while(it.hasNext()) {
             e = (StackTraceElement[])it.next();
             int num = index++;
             stackInfoStr += "Thread-" + num + ":" ;
             for (int i=0; i <e.length; i++) {
              stackInfoStr += e[i]+"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
             }
         }
         monitor.setThreadStack( stackInfoStr );
        
         //取得当前虚机的相关信息
   Runtime r = Runtime.getRuntime();
   double avail = r.totalMemory()/(1024*1000);
   double free = r.freeMemory()/(1024*1000);
   int pfree = new Double(((free / avail) * 100.000)).intValue();
   monitor.setFreeRate( pfree );
  
  
   String tomcatPath = MemoryConstantConfig.getInstance().getCurrentTomcatPath();
   if(tomcatPath == null || tomcatPath.trim().equals("") ){
    log.error( "current tomcatPath is null or empty!" );
   }
   monitor.setTomcatPath( tomcatPath  );
  
   int iLeFree = MemoryConstantConfig.getInstance().getILeFree();
   if( iLeFree < 0){
    log.error( "current iLeFree is less than 0" );
   }
  
         //获取内存运行情况信息,若内存空闲小于某个指定值时记录到数据库
   if( pfree < iLeFree ){
    log.error( "当前内存空闲率为:"+ pfree + "% 小于指定的最低监控空闲值:"+
      iLeFree + "% , 现记录到内存监控表里");
    monitorDao.insert( monitor );//记录到监控表里,运行ibatis dao
   }
            
   //销毁变量
   r = null;
   it = null;
   ds = null;
   monitor = null;
            log.info( "内存监控结束" );
  
  }catch(Exception ex){
   log.error( "用运行内存监控时出错" , ex);
   throw new JobExecutionException( "用运行内存监控时出错:"+ex.getMessage() );
  }
 

2、监控服务代码简例
  A、监控spring配置
<bean id="memoryMonitorJob"
  class="org.springframework.scheduling.quartz.JobDetailBean">
  <property name="jobClass">
   <value>com.chinacti.ibatis.service.MemoryMonitorJob</value>
  </property>
  <property name="jobDataAsMap">
   <map>
    <entry key="monitorDao">
     <ref bean="memoryMonitorDao" />
    </entry>
    <entry key="monitorInfo">
     <map>
       <entry key="8000">
         <value>D:/Tomcat5.5/bin</value>
       </entry>
       <entry key="9000">
         <value>D:/Tomcat5.5_ibatis/bin</value>
       </entry>
       <entry key="tomcatRestartMillis">
         <value>10000</value>
       </entry>
       <entry key="apacheRestartMillis">
         <value>15000</value>
       </entry>
       <entry key="leFree">
         <value>10</value>
       </entry>
     </map>
    </entry>
   </map>
  </property>
</bean>

B、监控服务quarz job代码
protected void executeInternal(JobExecutionContext arg0)
   throws JobExecutionException {
  try{
   log.info( "内存监控开始" );
           //删除30天前的内存监控对象
   monitorDao.delete30DaysBeforeMonitors();
  
   //取出各服务器的最近一个内存监控对象
   ArrayList<String> tomcatPaths = new ArrayList<String>();
   Set<String> keys = monitorInfo.keySet();
  
   for(String key : keys){
    if( !key.equalsIgnoreCase("leFree") && key.indexOf( "Millis" ) < 0 ){
     tomcatPaths.add( (String)monitorInfo.get(key) );
    }
   }
  
     //判断各服务器内存空闲率是否小于指定的空闲率,如果是则重启tomcat
     int leFree = Integer.parseInt( (String)monitorInfo.get( "leFree" ) );
     MemoryMonitor monitor;
     for(String tomcatPath : tomcatPaths){
      log.info( "监控的tomcat是"+tomcatPath );
     
      monitor = monitorDao.getCurrTomcatLatestMonitor( tomcatPath , leFree );
     
      //若不为空则表当前服务器内存空闲率已小于指定的,需重启
      if( monitor != null){
       restartService( monitor );
      }
     }
  
     log.info("内存监控结束");
   
  }catch(Exception ex){
   log.error( "用运行内存监控时出错" , ex);
   throw new JobExecutionException( "用运行内存监控时出错:"+ex.getMessage() );
  }
 
}

/**
  * 重启指定的服务器及做一些相关动作,如所有此次启动的服务器对应的监控记录失效、
  * 本次导致得启的监控记录重写备注信息
  * @param monitor
  * @throws Exception
  */
private void restartService( MemoryMonitor monitor ) throws Exception{
  log.error( "将重启tomcat服务,"+
    "服务器路径是:"+monitor.getTomcatPath()+
    "  当前空闲比率是:"+monitor.getFreeRate()+"%"+
    "  当前dbcpActive:"+monitor.getDbcpActiveNum()+
    "  当前dbcpIdle:"+monitor.getDbcpIdleNum());
  //关闭对应的服务器
  Runtime r = Runtime.getRuntime();
  String   stopPath   =   "cmd.exe   /c   start   /min   "   + monitor.getTomcatPath()+
            "/shutdown.bat";  

  r.exec( stopPath );
 
  //等待5秒钟关闭服务,然兵器重启对应的服务器
  int waitMillis = 10000;
  String waitMs;
  try{
    waitMs = (String)monitorInfo.get( "tomcatRestartMillis" ) ;
    if( waitMs != null ){
     waitMillis = Integer.parseInt(waitMs );
    }
    log.error( "开始等待服务关闭,等待"+waitMillis+"毫秒" );
    Thread.sleep(waitMillis);
    log.error( ""+waitMillis+"毫秒等待结束" );
     }catch(InterruptedException e){
      log.error( "",e );
     }
    
     String   startPath   =   "cmd.exe   /c   start   /min   "   + monitor.getTomcatPath()+
              "/startup.bat";
     r.exec( startPath );
 
     try{
      waitMs = (String)monitorInfo.get( "apacheRestartMillis" ) ;
    if( waitMs != null ){
     waitMillis = Integer.parseInt( waitMs );
    }else{
     waitMillis = 15000;
    }
    log.error( "开始等待服务启动,等待"+waitMillis+"毫秒" );
    Thread.sleep(waitMillis);
    log.error( ""+waitMillis+"毫秒等待结束" );
     }catch(InterruptedException e){
      log.error( "",e );
     }
 
  log.error( "重启完成" );
 
  //本次导致得启的监控记录重写备注信息为“已重启”
  String currDateTime = DateTime.getSysDateTimeString();
  monitor.setRemark( "已重启服务器,重启时间为:"+currDateTime );
  monitorDao.update(monitor);
 
  //所有此次启动的服务器对应的监控记录失效
  monitorDao.invalidMonitors( monitor.getTomcatPath() );
 
  //重启apache
  String   restartApachePath   =   "cmd.exe   /c   start   /min   "   +
              "h:/java/restartApache.bat";//"D:/Apache2.2/restartApache.bat";
        r.exec( restartApachePath );
        log.error( "apache重启完成" );
 
        //注销临时变量
        r = null;
        stopPath = null;
        startPath = null;
        waitMs = null;
        restartApachePath = null;
        monitor = null;
}


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics