Java实现监控tomcat线程池

import jodd.util.StringUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import java.lang.management.ManagementFactory;
import java.net.InetAddress;
import java.util.HashSet;
import java.util.Set;

/**
 * tomcat线程池监控
 *
 * @author huchenfei
 * @version 1.0
 * @class TomcatThreadPoolMonitorJob
 * @date 2021/1/2 20:15
 * @description
 */
@EnableScheduling
@Service
public class TomcatThreadPoolMonitorJob {

    private final static Logger LOCAL_LOGGER = LoggerFactory.getLogger(TomcatThreadPoolMonitorJob.class);

    private static final String MONITOR_PREFIX = "tomcat_threadPool.";

    private static MBeanServer mbeanServer;

    private static ObjectName objectName = null;

    static {
        try {
            objectName = new ObjectName("Catalina:type=ThreadPool,*");
            mbeanServer = getMBeanServer();
        } catch (MalformedObjectNameException e) {
            // ii
        }
    }

    @Scheduled(cron = "0 0/1 * * * ?")
    public void execute() {
        try {

            // collect thread metrics
            Set<ObjectName> connectorNames = getObjectNames(objectName);
            InetAddress localHost = InetAddress.getLocalHost();
            String hostName = localHost.getHostName().replace('.', '_');
            String host = hostName + ":";
            for (ObjectName connectorName : connectorNames) {
                // only check one
                String subType = connectorName.getKeyProperty("subType");
                if (StringUtil.isNotEmpty(subType) || !isTomcatServer(connectorName.getDomain())) {
                    continue;
                }

                String name = ObjectName.unquote(connectorName.getKeyProperty("name"));
                // 基本不使用的协议
                if (name.startsWith("ajp")) {
                    continue;
                }

                String monitorPort = String.valueOf(mbeanServer.getAttribute(connectorName, "port"));
                String prefix = MONITOR_PREFIX + host + monitorPort + ".";

                int currentThreadsBusy = (Integer) mbeanServer.getAttribute(connectorName, "currentThreadsBusy");
                LOCAL_LOGGER.info("tomcat.thread.pool.busyCount {}", currentThreadsBusy);

                int currentThreadCount = (Integer) mbeanServer.getAttribute(connectorName, "currentThreadCount");
                LOCAL_LOGGER.info("tomcat.thread.pool.currentCount {}", currentThreadCount);

                int minSpareThreads = (Integer) mbeanServer.getAttribute(connectorName, "minSpareThreads");
                LOCAL_LOGGER.info("tomcat.thread.pool.spareCount {}", minSpareThreads);

                int maxThreads = (Integer) mbeanServer.getAttribute(connectorName, "maxThreads");
                LOCAL_LOGGER.info("tomcat.thread.pool.maxCount {}", maxThreads);
            }
        } catch (Exception e) {
            LOCAL_LOGGER.error("Exception occur when getting connector global stats: ", e);
        }
    }

    public Set<ObjectName> getObjectNames(ObjectName objectName) {
        if (objectName == null) {
            return new HashSet<>();
        }
        Set<ObjectName> objectNames = mbeanServer.queryNames(objectName, null);
        if (objectNames != null && !objectNames.isEmpty()) {
            return objectNames;
        }
        return new HashSet<>();
    }

    public static MBeanServer getMBeanServer() {
        MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
        if (MBeanServerFactory.findMBeanServer(null).size() > 0) {
            mBeanServer = MBeanServerFactory.findMBeanServer(null).get(0);
        }
        return mBeanServer;
    }

    private boolean isTomcatServer(String domain) {
        if (StringUtil.isEmpty(domain)) {
            return false;
        }
        return StringUtils.equalsIgnoreCase("tomcat", domain) ||
                StringUtils.equalsIgnoreCase("catalina", domain);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值