如何輸出TOMCAT的配置參數

有時候咱們想獲取當前運行的Tomcat的各類參數,好比maxThreads、acceptThreadCount等。例以下面兩張圖:java

一、Http11Protocolapache

Http11Protocol.png

Http11Protocol.pngjson

一、Http11NioProtocolapi

Http11NioProtocol.png

Http11NioProtocol.pngtomcat

三、實現代碼框架

import com.google.common.collect.Maps;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.management.ObjectName;
import java.util.List;
import java.util.Map;


/**
 * Created by wangxindong on 2017/10/31.
 */
public class TomcatContainerMonitor {
    private static final Logger logger = LoggerFactory.getLogger(TomcatContainerMonitor.class);
    private static final String tomcatEmbedDomain = "Tomcat";
    private static final String tomcatDomain = "Catalina";

    private static final String bioProtocol="org.apache.coyote.http11.Http11Protocol";
    private static final String nioProtocol="org.apache.coyote.http11.Http11NioProtocol";

    public  Object doMonitor() {
        Map<String, Object> map = Maps.newHashMap();

        List<MBeanServer> mBeanServers = MBeanServerFactory.findMBeanServer(null);
        if (!mBeanServers.isEmpty()) {
            MBeanServer mBeanServer = mBeanServers.get(0);
            String domain = getTomcatDomian(mBeanServer);
            try {
                ObjectName[] objNames = (ObjectName[]) mBeanServer.getAttribute(new ObjectName(domain, "type", "Service"), "connectorNames");
                for (ObjectName on : objNames) {
                    Map<String, Object> connector = Maps.newHashMap();
                    Object protocol = mBeanServer.getAttribute(on, "protocol");
                    connector.put("protocol", protocol);
                    Object acceptCount = mBeanServer.getAttribute(on, "acceptCount");
                    connector.put("acceptCount", acceptCount);

                    Object connectionTimeout = mBeanServer.getAttribute(on, "connectionTimeout");
                    connector.put("connectionTimeout", connectionTimeout);

                    Object protocolHandlerClassName = mBeanServer.getAttribute(on, "protocolHandlerClassName");
                    connector.put("protocolHandlerClassName", protocolHandlerClassName);

                    Object enableLookups = mBeanServer.getAttribute(on, "enableLookups");
                    connector.put("enableLookups", enableLookups);

                    Object uriEncoding = mBeanServer.getAttribute(on, "URIEncoding");
                    connector.put("URIEncoding", uriEncoding);

                    Object useBodyEncodingForURI = mBeanServer.getAttribute(on, "useBodyEncodingForURI");
                    connector.put("useBodyEncodingForURI", useBodyEncodingForURI);

                    Object localPort = mBeanServer.getAttribute(on, "port");
                    map.put("connector-" + localPort, connector);

                    if (protocolHandlerClassName.toString().equals(nioProtocol)) {//NIO
                        String threadPoolONStr = domain + ":type=ThreadPool,name=\"http-nio-" + localPort + "\"";
                        ObjectName threadPoolON = new ObjectName(threadPoolONStr);
                        Map<String, Object> threadPoolMap = Maps.newHashMap();

                        Object maxConnections = mBeanServer.getAttribute(threadPoolON, "maxConnections");
                        threadPoolMap.put("maxConnections", maxConnections);

                        Object maxThreads = mBeanServer.getAttribute(threadPoolON, "maxThreads");
                        threadPoolMap.put("maxThreads", maxThreads);

                        Object minSpareThreads = mBeanServer.getAttribute(threadPoolON, "minSpareThreads");
                        threadPoolMap.put("minSpareThreads", minSpareThreads);

                        Object acceptorThreadCount = mBeanServer.getAttribute(threadPoolON, "acceptorThreadCount");
                        threadPoolMap.put("acceptorThreadCount", acceptorThreadCount);

                        Object pollerThreadCount = mBeanServer.getAttribute(threadPoolON, "pollerThreadCount");
                        threadPoolMap.put("pollerThreadCount", pollerThreadCount);

                        Object pollerThreadPriority = mBeanServer.getAttribute(threadPoolON, "pollerThreadPriority");
                        threadPoolMap.put("pollerThreadPriority", pollerThreadPriority);

                        connector.put("threadPool", threadPoolMap);
                    }else if(protocolHandlerClassName.toString().equals(bioProtocol)){
                        String threadPoolONStr = domain + ":type=ThreadPool,name=\"http-bio-" + localPort + "\"";
                        ObjectName threadPoolON = new ObjectName(threadPoolONStr);
                        Map<String, Object> threadPoolMap = Maps.newHashMap();

                        Object maxConnections = mBeanServer.getAttribute(threadPoolON, "maxConnections");
                        threadPoolMap.put("maxConnections", maxConnections);

                        Object maxThreads = mBeanServer.getAttribute(threadPoolON, "maxThreads");
                        threadPoolMap.put("maxThreads", maxThreads);

                        Object minSpareThreads = mBeanServer.getAttribute(threadPoolON, "minSpareThreads");
                        threadPoolMap.put("minSpareThreads", minSpareThreads);

                        Object acceptorThreadCount = mBeanServer.getAttribute(threadPoolON, "acceptorThreadCount");
                        threadPoolMap.put("acceptorThreadCount", acceptorThreadCount);

                        connector.put("threadPool", threadPoolMap);
                    }

                }
            } catch (Exception e) {
                logger.warn("獲取信息失敗", e);
            }
        }
        return map;
    }

    private  String getTomcatDomian(MBeanServer mBeanServer) {
        try {
            mBeanServer.getAttribute(new ObjectName(tomcatEmbedDomain, "type", "Service"), "connectorNames");
            return tomcatEmbedDomain;
        } catch (Exception e) {
            return tomcatDomain;
        }
    }

    @Test
    public void test(){
        TomcatContainerMonitor wcm = new TomcatContainerMonitor();
        wcm.doMonitor();
    }

}

獲取MAP對象經過json序列化輸出到頁面,如上面兩張圖。dom

四、須要依賴ide

<dependency>
  <groupId>com.alibaba</groupId>
  <artifactId>fastjson</artifactId>
  <version>1.2.39</version>
  <!--<scope>provided</scope>-->
</dependency>
<dependency>
  <groupId>com.google.collections</groupId>
  <artifactId>google-collections</artifactId>
  <version>1.0</version>
  <!--<scope>provided</scope>-->
</dependency>
<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>slf4j-api</artifactId>
  <version>1.7.20</version>
  <!--<scope>provided</scope>-->
</dependency>

五、原理總結工具

public abstract class LifecycleMBeanBase extends LifecycleBase
        implements MBeanRegistration {}

Tomcat對server.xml文件解析,解析出來的組件和容器都繼承了LifecycleMBeanBase類,其父類LifecycleBase實現了容器的生命週期管理,其接口MBeanRegistration由Java JMX(Java Management Extensions)框架提供,用於監聽JMX註冊事件;LifecycleMBeanBase的子類都遵循JMX標準,經過getObjectNameKeyProperties()抽象方法定義類的註冊名稱,並在每一個對象初始化(執行生命週期init方法)時註冊到MBeanServer中,MBeanServer給出了外部管理系統訪問JMX框架的接口,所以外部系統或工具能夠實時監控到MBean的各類數據信息。這就是咱們可以經過MBeanServer獲取到Tomcat各類配置信息的原理。google

參考資料:
http://www.fanyilun.me/2016/10/10/Tomcat%E7%9A%84%E5%90%AF%E5%8A%A8%E5%88%86%E6%9E%90/

相關文章
相關標籤/搜索