ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

随Tomcat启动1个线程,并通过JMX不停服管理该线程起停

2021-09-29 20:02:23  阅读:150  来源: 互联网

标签:JMX Tomcat process void 线程 import logger public


第1步,创建TaskProcess,代码如下

package cn.xxx.xxxx;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.springframework.context.ApplicationContext;

import java.util.HashMap;
import java.util.Map;

public class TaskProcess extends Thread {

    private static final Log logger = LogFactory.getLog(TaskProcess.class);

    // 获取应用程序上下文环境,用于获取注入bean
    private ApplicationContext appCon;

    // 线程执行期间内存map
    static Map<String,String> processMap = new HashMap<String,String>();

    public TaskProcess(ApplicationContext con) {
        this.appCon = con;
    }

    public void run() {
        logger.info("线程启动。");
        long n=1;
        while(true){
            logger.info("线程第"+n+"次运行");
            processPunction(n);
            n++;
            try {
                //30秒执行1次
                Thread.sleep(30000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public void processPunction(long n) {
        try {
            //TODO
            //XXXMapper xxxMapper= (XXXMapper)appCon.getBean("xx.xx.xxxMapper");
            //List list = XXXMapper.select();
            //processMap.put(String.valueOf(n), list);
            logger.info("业务逻辑。。。。");
            processMap.put(String.valueOf(n),"线程第"+n+"次运行");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

第2步,创建 TaskManagerMBean,代码如下

package cn.xxx.xxxx;

public interface TaskManagerMBean{

    public void startNewProcess();

    public void restartProcess();

    public void showAliveProcess();
}

第3步,创建TaskManagerMBean的实现类TaskManager,代码如下

package cn.xxx.xxxx;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationContext;

import java.util.Map;

/**
 * jmx监控TaskProcess
 */
public class TaskManager implements TaskManagerMBean{

    private static final Log logger = LogFactory.getLog(TaskManager.class);

    private ApplicationContext con;

    private TaskProcess process;

    public TaskManager(ApplicationContext con , TaskProcess process ){
        this.con = con;
        this.process=process;
    }

    //启动新的线程
    public void startNewProcess() {
        if(!process.isAlive()){
            logger.info("启动新的线程。");
            process = new TaskProcess(con);
            process.start();
            long processId = process.getId();
            logger.info("线程--"+processId+"已启动。");
        }else{
            logger.info("线程已存在,请先停止原有线程");
        }
    }

    //重启
    public void restartProcess() {
        logger.info("停止原有线程中。。。");
        long processId = process.getId();
        process.stop();
        logger.info("线程--"+processId+"已停止");
        logger.info("重新启动线程中。。。");
        process = new TaskProcess(con);
        process.start();
        processId = process.getId();
        logger.info("已重新启动线程--"+processId);
    }

    //查看活的线程以及业务逻辑中有什么
    public void showAliveProcess(){
        if(process.isAlive()){
            long processId = process.getId();
            logger.info("线程--"+processId+"正常。");
            Map<String, String> processMap = process.processMap;
            logger.info("processMap--"+processMap);
        }else{
            logger.info("线程不存在");
        }
    }
}

第4步,创建上下文TaskServletContextContext,代码参考如下

package cn.xxx.xxxx;

import javax.servlet.ServletContext;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

public class TaskServletContextContext implements ApplicationContextAware {
  
  private static ApplicationContext springContext;

  public static ApplicationContext getApplicationContext() {
    return springContext;
  }

  public void setServletContext(ServletContext servletContext) {
    springContext = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
  }

  public static void setApplicationContext(WebApplicationContext context) {
    springContext = context;
  }

  public void setAttribute(String name, Object bean) {
    if ((springContext instanceof WebApplicationContext))
      ((WebApplicationContext)springContext).getServletContext().setAttribute(name, bean);
  }

  public void destroy() throws Exception {
    springContext = null;
  }

  public void setApplicationContext(ApplicationContext arg0)
    throws BeansException {
    springContext = arg0;
  }
}

第6步,创建随服务启动的Listener,代码参考如下

package cn.xxx.xxxx;

import javax.management.*;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletContextEvent;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationContext;


import java.lang.management.ManagementFactory;


public class TaskServletContextListener implements ServletContextListener{
	private static final Log logger = LogFactory.getLog(TaskServletContextListener.class);

	@Override
	public void contextInitialized(ServletContextEvent sce) {
		TaskServletContextContext tscc = new TaskServletContextContext();
		tscc.setServletContext(sce.getServletContext());
		ApplicationContext con = TaskServletContextContext.getApplicationContext();
		TaskProcess process = new TaskProcess (con);
		process.start();
		//启动jmx监控此线程
		startJmx(con,process);

	}

	public void startJmx(ApplicationContext con ,TaskProcess process){
		MBeanServer server = ManagementFactory.getPlatformMBeanServer();
		try {
			ObjectName name = new ObjectName("taskJmx:name=taskJmx");
			server.registerMBean(new TaskManager(con, process), name);
		} catch (MalformedObjectNameException e) {
			e.printStackTrace();
		} catch (NotCompliantMBeanException e) {
			e.printStackTrace();
		} catch (InstanceAlreadyExistsException e) {
			e.printStackTrace();
		} catch (MBeanRegistrationException e) {
			e.printStackTrace();
		}
	}

	@Override
	public void contextDestroyed(ServletContextEvent sce) {
		// TODO Auto-generated method stub
		
	}

}

第7步,web项目中web.xml的<web-app>节点增加如下配置上面的listener

<listener>
       <listener-class>cn.xx.xxxx.TaskServletContextListener</listener-class>
</listener>

第8步,启动tomcat,Tomcat版本:apache-tomcat-7.0.103

第9步,执行java安装目录下的jconsole.exe

C:\Java\jdk1.8.0_20\bin\jconsole.exe

第10步,查看mbean,连接到tomcart,可能提示不安全,点"不安全连接"即可

 第11步,选择MBean页签,找到第6步代码中的name,展开有操作,点击操作,右边显示按钮。点击方法即可

后台打印log: 

2021/09/29 19:53:23 [RMI TCP Connection(10)-127.0.0.1] INFO  cn.xxx.xxxx.TaskManager -线程--92正常。
2021/09/29 19:53:23 [RMI TCP Connection(10)-127.0.0.1] INFO  cn.xxx.xxxx.TaskManager -processMap--{1=线程第1次运行, 2=线程第2次运行, 3=线程第3次运行, 4=线程第4次运行, 5=线程第5次运行}

标签:JMX,Tomcat,process,void,线程,import,logger,public
来源: https://blog.csdn.net/nnqq517/article/details/120554305

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有