1. 程式人生 > >mongo-java應用監控

mongo-java應用監控

近期專案中需要監控mongo驅動的執行緒池的資訊。
類似mysql中有型別Druid 可以監控資料庫的執行緒池

參考mongo-driver驅動的文件:

文件上說明 有通過日誌監控 和通過jmx的mbean進行監控
我們這裡採用mbean監控

Monitoring
The driver uses JMX to create MXBeans that allow an application or end user to monitor various aspects of the driver.

The driver creates MXBean instances of
a single type: ConnectionPoolStatisticsMBean. The driver registers one ConnectionPoolStatisticsMBean instance per each server it connects to. For example, in the case of a replica set, the driver creates an instance per each non-hidden member of the replica set. Each MXBean instance is required to
be registered with a unique object name, which consists of a domain and a set of named properties. All MXBean instances created by the driver are under the domain "org.mongodb.driver". Instances of ConnectionPoolStatisticsMBean will have the following properties: clusterId: a client-generated unique identifier, required to
ensure object name uniqueness in situations where an application has multiple MongoClient instances connected to the same MongoDB server deployment host: the host name of the server port: the port on which the server is listening minSize: the minimum allowed size of the pool, including idle and in-use members maxSize: the maximum allowed size of the pool, including idle and in-use members size: the current size of the pool, including idle and and in-use members waitQueueSize: the current size of the wait queue for a connection from this pool checkedOutCount: the current count of connections that are currently in use

谷歌上對應的翻譯

監控
驅動程式使用JMX建立允許應用程式或終端使用者監視驅動程式各個方面的MXBean。

驅動程式建立單個型別的MXBean例項:ConnectionPoolStatisticsMBean。驅動程式為每個連線的伺服器註冊一個ConnectionPoolStatisticsMBean例項。例如,在副本集的情況下,驅動程式為副本集合中的每個非隱藏成員建立一個例項。

每個MXBean例項都需要註冊一個唯一的物件名稱,它由一個域和一組命名的屬性組成。由驅動程式建立的所有MXBean例項都位於域“org.mongodb.driver”下。 ConnectionPoolStatisticsMBean的例項將具有以下屬性:

clusterId:客戶端生成的唯一識別符號,用於在應用程式將多個MongoClient例項連線到相同的MongoDB伺服器部署的情況下確保物件名稱唯一性
主機:伺服器的主機名
port:伺服器正在偵聽的埠
minSize:池的最小允許大小,包括空閒和使用中的成員
maxSize:池的最大允許大小,包括空閒和正在使用的成員
size:池的當前大小,包括空閒和正在使用的成員
waitQueueSize:此池連線的等待佇列的當前大小
checkedOutCount:當前正在使用的連線的當前計數

這裡可以需要運用到jconsole 和jmx的知識。

首先建立一個監控日誌的核心程式碼
LogTask.java

package com.test.task;

import org.apache.log4j.Logger;

import javax.management.AttributeList;
import javax.management.MBeanServer;
import javax.management.ObjectInstance;
import javax.management.ObjectName;
import java.lang.management.ManagementFactory;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class LogTask {

    private int initialDelay = 3;

    private int period = 3;

    private Logger logger = Logger.getLogger(LogTask.class);

    private MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer();

    public void init() {
        logger.info("初始化mongo執行緒池監控日誌");
        ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(3);
        scheduledThreadPool.scheduleAtFixedRate(new Runnable() {

            public void run() {
                try {

                    Set<ObjectInstance> set = mbeanServer.queryMBeans(new ObjectName("org.mongodb.driver:type=ConnectionPool,*"), null);
                    for (ObjectInstance oi : set) {
                        String className = oi.getClassName();
                        if (className.contains("mongo")) {
                            ObjectName objectName = oi.getObjectName();
                            logger.info(objectName);
                            String[] attrs = new String[]{"CheckedOutCount", "Host", "Port",
                                    "MinSize", "MaxSize", "Size", "WaitQueueSize"};
                            for (String attr : attrs) {
                                logger.info(attr + "==" + mbeanServer.getAttribute(objectName, attr));
                            }
                        }

                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    logger.error("執行日誌列印失敗", e);
                }

            }
        }, initialDelay, period, TimeUnit.SECONDS);

    }


    public int getInitialDelay() {
        return initialDelay;
    }

    public void setInitialDelay(int initialDelay) {
        this.initialDelay = initialDelay;
    }

    public int getPeriod() {
        return period;
    }

    public void setPeriod(int period) {
        this.period = period;
    }
}