使用 MBean 和 日志查看 Tomcat 线程池核心属性数据

文章目录

  • CustomTomcatThreadPoolMBean
  • CustomTomcatThreadPool


CustomTomcatThreadPoolMBean

com.qww.config;

public interface CustomTomcatThreadPoolMBean {
    String getStatus();
}

CustomTomcatThreadPool

package com.qww.config;

import com.alibaba.fastjson.JSON;
import org.apache.tomcat.util.threads.ThreadPoolExecutor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.context.WebServerApplicationContext;
import org.springframework.boot.web.embedded.tomcat.TomcatWebServer;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.management.InstanceAlreadyExistsException;
import javax.management.MBeanRegistrationException;
import javax.management.MBeanServer;
import javax.management.MalformedObjectNameException;
import javax.management.NotCompliantMBeanException;
import javax.management.ObjectName;
import java.lang.management.ManagementFactory;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
public class CustomTomcatThreadPool implements CustomTomcatThreadPoolMBean {

    private final static Logger logger = LoggerFactory.getLogger(CustomTomcatThreadPool.class);

    @Autowired
    WebServerApplicationContext webServerApplicationContext;

    @Override
    public String getStatus() {
        return buildStatus();
    }

    private String buildStatus() {
        logger.info("==>>: webServerApplicationContext:{} ", webServerApplicationContext);
        ThreadPoolExecutor executor = (ThreadPoolExecutor) ((TomcatWebServer) webServerApplicationContext.getWebServer())
                .getTomcat()
                .getConnector()
                .getProtocolHandler()
                .getExecutor();
        logger.info("==>>: 这行日志如果没有输出,就是上一行代码报错了。虽然报错,但由于当前线程[RMP TCP Connection(x)-ip]的特殊性,并不会在控制台打印堆栈");
        Map<String, String> returnMap = new LinkedHashMap<>();
        returnMap.put("核心线程数(corePoolSize)", String.valueOf(executor.getCorePoolSize()));
        returnMap.put("最大线程数(maximumPoolSize)", String.valueOf(executor.getMaximumPoolSize()));
        returnMap.put("活跃线程数(activeCount)", String.valueOf(executor.getActiveCount()));
        returnMap.put("池中当前线程数(poolSize)", String.valueOf(executor.getPoolSize()));
        returnMap.put("历史最大线程数(largestPoolSize)", String.valueOf(executor.getLargestPoolSize()));
        returnMap.put("工作队列任务数量(workQueue.size)", String.valueOf(executor.getQueue().size()));
        returnMap.put("线程允许空闲时间/s(keepAliveTime)", String.valueOf(executor.getKeepAliveTime(TimeUnit.SECONDS)));
        returnMap.put("核心线程数是否允许被回收(allowCoreThreadTimeOut)", String.valueOf(executor.allowsCoreThreadTimeOut()));
        returnMap.put("提交任务总数(submittedCount)", String.valueOf(executor.getSubmittedCount()));
        returnMap.put("历史执行任务的总数(近似值)(taskCount)", String.valueOf(executor.getTaskCount()));
        returnMap.put("历史完成任务的总数(近似值)(completedTaskCount)", String.valueOf(executor.getCompletedTaskCount()));
        returnMap.put("拒绝策略(ejectedExecutionHandler.class)", executor.getRejectedExecutionHandler().getClass().getCanonicalName());
        String res = JSON.toJSONString(returnMap);
        logger.info("==>>: {}", res);
        return res;
    }

    @PostConstruct
    public void post() {
        MBeanServer server = ManagementFactory.getPlatformMBeanServer();
        ObjectName objectName = null;
        try {
            objectName = new ObjectName("qww:type=CustomTomcatThreadPool");
        } catch (MalformedObjectNameException e) {
            e.printStackTrace();
        }
        try {
            // 这里的key 必须使用Spring 中注册的对象,也就是当前对象
            server.registerMBean(this, objectName);
        } catch (InstanceAlreadyExistsException | MBeanRegistrationException | NotCompliantMBeanException e) {
            e.printStackTrace();
        }
    }

}

你可能感兴趣的:(java,tomcat,java)