当前位置: 首页 > news >正文

聊聊druid连接池的监控

本文主要研究一下druid连接池的监控

init

com/alibaba/druid/pool/DruidDataSource.java

public void init() throws SQLException {//......registerMbean();//......
}

DruidDataSource的init方法会执行registerMbean

registerMbean

com/alibaba/druid/pool/DruidDataSource.java

    public void registerMbean() {if (!mbeanRegistered) {AccessController.doPrivileged(new PrivilegedAction<Object>() {@Overridepublic Object run() {ObjectName objectName = DruidDataSourceStatManager.addDataSource(DruidDataSource.this,DruidDataSource.this.name);DruidDataSource.this.setObjectName(objectName);DruidDataSource.this.mbeanRegistered = true;return null;}});}}

registerMbean会执行DruidDataSourceStatManager.addDataSource(DruidDataSource.this, DruidDataSource.this.name)

DruidDataSourceStatManager

com/alibaba/druid/stat/DruidDataSourceStatManager.java

    public static synchronized ObjectName addDataSource(Object dataSource, String name) {final Map<Object, ObjectName> instances = getInstances();MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer();synchronized (instances) {if (instances.size() == 0) {try {ObjectName objectName = new ObjectName(MBEAN_NAME);if (!mbeanServer.isRegistered(objectName)) {mbeanServer.registerMBean(instance, objectName);}} catch (JMException ex) {LOG.error("register mbean error", ex);}DruidStatService.registerMBean();}}ObjectName objectName = null;if (name != null) {try {objectName = new ObjectName("com.alibaba.druid:type=DruidDataSource,id=" + name);mbeanServer.registerMBean(dataSource, objectName);} catch (Throwable ex) {LOG.error("register mbean error", ex);objectName = null;}}if (objectName == null) {try {int id = System.identityHashCode(dataSource);objectName = new ObjectName("com.alibaba.druid:type=DruidDataSource,id=" + id);mbeanServer.registerMBean(dataSource, objectName);} catch (Throwable ex) {LOG.error("register mbean error", ex);objectName = null;}}instances.put(dataSource, objectName);return objectName;}

DruidDataSourceStatManager的addDataSource方法通过mbeanServer.registerMBean(dataSource, objectName)将DruidDataSource注册到mbeanServer中,而DruidDataSource则实现了DruidDataSourceMBean接口

DruidDataSourceMBean

public interface DruidDataSourceMBean extends DruidAbstractDataSourceMBean {long getResetCount();boolean isEnable();String getUrl();void shrink();int removeAbandoned();String dump();int getWaitThreadCount();int getLockQueueLength();long getNotEmptyWaitCount();int getNotEmptyWaitThreadCount();long getNotEmptySignalCount();long getNotEmptyWaitMillis();long getNotEmptyWaitNanos();void resetStat();boolean isResetStatEnable();void setResetStatEnable(boolean resetStatEnable);String getVersion();void setPoolPreparedStatements(boolean poolPreparedStatements);int getActivePeak();int getPoolingPeak();Date getActivePeakTime();Date getPoolingPeakTime();long getErrorCount();ObjectName getObjectName();void clearStatementCache() throws SQLException;long getDiscardCount();void setStatLoggerClassName(String className);long getTimeBetweenLogStatsMillis();void setTimeBetweenLogStatsMillis(long timeBetweenLogStatsMillis);void setConnectionProperties(String connectionProperties);int fill() throws SQLException;int fill(int toCount) throws SQLException;boolean isUseGlobalDataSourceStat();
}

DruidDataSourceMBean按jmx规范命名以MBean结尾,它定义了一系列的getter和操作方法,它还继承了DruidAbstractDataSourceMBean

DruidAbstractDataSourceMBean

com/alibaba/druid/pool/DruidAbstractDataSourceMBean.java

public interface DruidAbstractDataSourceMBean {int getLoginTimeout();String getDbType();String getName();int getInitialSize();String getUsername();String getUrl();String getDriverClassName();long getConnectCount();long getCloseCount();long getConnectErrorCount();int getPoolingCount();long getRecycleCount();int getActiveCount();long getCreateCount();long getDestroyCount();long getCreateTimespanMillis();long getCommitCount();long getRollbackCount();long getStartTransactionCount();int getQueryTimeout();int getTransactionQueryTimeout();String getValidationQuery();int getValidationQueryTimeout();int getMaxWaitThreadCount();long getTimeBetweenEvictionRunsMillis();long getMinEvictableIdleTimeMillis();boolean isRemoveAbandoned();long getRemoveAbandonedTimeoutMillis();List<String> getActiveConnectionStackTrace();List<String> getFilterClassNames();boolean isTestOnBorrow();void setTestOnBorrow(boolean testOnBorrow);boolean isTestOnReturn();boolean isTestWhileIdle();void setTestWhileIdle(boolean testWhileIdle);boolean isDefaultAutoCommit();Boolean getDefaultReadOnly();Integer getDefaultTransactionIsolation();String getDefaultCatalog();boolean isPoolPreparedStatements();boolean isSharePreparedStatements();long getMaxWait();int getMinIdle();int getMaxIdle();long getCreateErrorCount();int getMaxActive();void setMaxActive(int maxActive);long getTimeBetweenConnectErrorMillis();int getMaxOpenPreparedStatements();long getRemoveAbandonedCount();boolean isLogAbandoned();void setLogAbandoned(boolean logAbandoned);long getDupCloseCount();boolean isBreakAfterAcquireFailure();int getConnectionErrorRetryAttempts();int getMaxPoolPreparedStatementPerConnectionSize();void setMaxPoolPreparedStatementPerConnectionSize(int maxPoolPreparedStatementPerConnectionSize);String getProperties();int getRawDriverMinorVersion();int getRawDriverMajorVersion();Date getCreatedTime();String getValidConnectionCheckerClassName();long[] getTransactionHistogramValues();void setTransactionThresholdMillis(long transactionThresholdMillis);long getTransactionThresholdMillis();long getPreparedStatementCount();long getClosedPreparedStatementCount();long getCachedPreparedStatementCount();long getCachedPreparedStatementDeleteCount();long getCachedPreparedStatementAccessCount();long getCachedPreparedStatementMissCount();long getCachedPreparedStatementHitCount();boolean isUseOracleImplicitCache();void setUseOracleImplicitCache(boolean useOracleImplicitCache);int getDriverMajorVersion();int getDriverMinorVersion();String getExceptionSorterClassName();
}

DruidAbstractDataSourceMBean定义了暴露给jmx的一系列方法

getStatDataForMBean

com/alibaba/druid/pool/DruidDataSource.java

    public Map<String, Object> getStatDataForMBean() {try {Map<String, Object> map = new HashMap<String, Object>();// 0 - 4map.put("Name", this.getName());map.put("URL", this.getUrl());map.put("CreateCount", this.getCreateCount());map.put("DestroyCount", this.getDestroyCount());map.put("ConnectCount", this.getConnectCount());// 5 - 9map.put("CloseCount", this.getCloseCount());map.put("ActiveCount", this.getActiveCount());map.put("PoolingCount", this.getPoolingCount());map.put("LockQueueLength", this.getLockQueueLength());map.put("WaitThreadCount", this.getNotEmptyWaitThreadCount());// 10 - 14map.put("InitialSize", this.getInitialSize());map.put("MaxActive", this.getMaxActive());map.put("MinIdle", this.getMinIdle());map.put("PoolPreparedStatements", this.isPoolPreparedStatements());map.put("TestOnBorrow", this.isTestOnBorrow());// 15 - 19map.put("TestOnReturn", this.isTestOnReturn());map.put("MinEvictableIdleTimeMillis", this.minEvictableIdleTimeMillis);map.put("ConnectErrorCount", this.getConnectErrorCount());map.put("CreateTimespanMillis", this.getCreateTimespanMillis());map.put("DbType", this.dbTypeName);// 20 - 24map.put("ValidationQuery", this.getValidationQuery());map.put("ValidationQueryTimeout", this.getValidationQueryTimeout());map.put("DriverClassName", this.getDriverClassName());map.put("Username", this.getUsername());map.put("RemoveAbandonedCount", this.getRemoveAbandonedCount());// 25 - 29map.put("NotEmptyWaitCount", this.getNotEmptyWaitCount());map.put("NotEmptyWaitNanos", this.getNotEmptyWaitNanos());map.put("ErrorCount", this.getErrorCount());map.put("ReusePreparedStatementCount", this.getCachedPreparedStatementHitCount());map.put("StartTransactionCount", this.getStartTransactionCount());// 30 - 34map.put("CommitCount", this.getCommitCount());map.put("RollbackCount", this.getRollbackCount());map.put("LastError", JMXUtils.getErrorCompositeData(this.getLastError()));map.put("LastCreateError", JMXUtils.getErrorCompositeData(this.getLastCreateError()));map.put("PreparedStatementCacheDeleteCount", this.getCachedPreparedStatementDeleteCount());// 35 - 39map.put("PreparedStatementCacheAccessCount", this.getCachedPreparedStatementAccessCount());map.put("PreparedStatementCacheMissCount", this.getCachedPreparedStatementMissCount());map.put("PreparedStatementCacheHitCount", this.getCachedPreparedStatementHitCount());map.put("PreparedStatementCacheCurrentCount", this.getCachedPreparedStatementCount());map.put("Version", this.getVersion());// 40 -map.put("LastErrorTime", this.getLastErrorTime());map.put("LastCreateErrorTime", this.getLastCreateErrorTime());map.put("CreateErrorCount", this.getCreateErrorCount());map.put("DiscardCount", this.getDiscardCount());map.put("ExecuteQueryCount", this.getExecuteQueryCount());map.put("ExecuteUpdateCount", this.getExecuteUpdateCount());return map;} catch (JMException ex) {throw new IllegalStateException("getStatData error", ex);}}

DruidDataSource的getStatDataForMBean定义了给jmx的所有监控项

DruidDataSourceUtils

com/alibaba/druid/util/DruidDataSourceUtils.java

    public static Map<String, Object> getStatDataForMBean(Object druidDataSource) {if (druidDataSource.getClass() == DruidDataSource.class) {return ((DruidDataSource) druidDataSource).getStatDataForMBean();}try {Method method = druidDataSource.getClass().getMethod("getStatDataForMBean");Object obj = method.invoke(druidDataSource);return (Map<String, Object>) obj;} catch (Exception e) {LOG.error("getStatDataForMBean error", e);return null;}}

DruidDataSourceUtils提供了静态方法用于获取监控项

小结

DruidDataSource的init方法会执行registerMbean,把自身注册到mbeanServer,它实现了DruidDataSourceMBean接口;而DruidDataSourceUtils提供了静态方法用于获取监控项,它使用的是DruidDataSource的getStatDataForMBean方法(貌似没直接给到jmx),可以利用该方法把指标暴露给micrometer,之后就可以利用micrometer的集成能力输出到各个监控平台。

http://www.lryc.cn/news/178213.html

相关文章:

  • CentOS 7 安装 Docker 的详细步骤
  • 竞赛 基于深度学习的动物识别 - 卷积神经网络 机器视觉 图像识别
  • 数据结构之【泛型】
  • 华为ac无线侧命令行配置思路和步骤
  • 十六)Stable Diffusion教程:出图流程化
  • SpringBoot全局异常处理源码
  • 设计模式——7. 装饰者模式
  • 安卓玩机-----反编译apk 修改apk 去广告 去弹窗等操作中的一些常识
  • Hoeffing不等式
  • ffmpeg解复用指定pid转推udp
  • Vue组件通信方式
  • redis-设置从节点
  • k8s-实战——基于nfs实现动态存储
  • 【广州华锐互动】鱼类授精繁殖VR虚拟仿真实训系统
  • RocketMQ Promethus Exporter
  • Kafka收发消息核心参数详解
  • Springboot中Aop的使用
  • 创建vue3项目、链式调用、setup函数、ref函数、reactive函数、计算和监听属性、vue3的生命周期、torefs的使用、vue3的setup写法
  • 搭建好自己的PyPi服务器后怎么使用
  • Vue3 中使用provide和reject
  • 大数据flink篇之一-基础知识
  • No140.精选前端面试题,享受每天的挑战和学习
  • Oracle 11g_FusionOS_安装文档
  • Linux驱动实现IO模型
  • wsl2 更新报错问题解决记录
  • 突破算法迷宫:精选50道-算法刷题指南
  • 玩转Mysql系列 - 第26篇:聊聊mysql如何实现分布式锁?
  • linux 解压缩命令tar
  • OpenAI ChatGPT API 文档之 Embedding
  • Java常用类(二)