开发者

可观测性-Metrics-数据库连接池HikariCP监控教程

目录
  • 非SpringBoot环境
    • 添加依赖
    • 示例
    • 指标详解
  • Spring Boot环境
    • 手动
    • 自动
  • 关于Sql日志记录和慢日志
    • 总结

      非SpringBoot环境

      HikariCP其内部提供了setMetricRegistry()方法,让我们可以注入MetricRegistry来实现对连接池指标的收集。

      这样我们可以较为方便的监控连接池的运行状态。

      添加依赖

          <dependency>
            <groupId>com.zaxxer</groupId>
            <artifactId>HikariCP</artifactId>
            <version>4.0.3</version>
          </dependency>
          <dependency>
             <groupId>mysql</groupId>
             <artifactId>mysql-connector-Java</artifactId>
          </dependency>
          <dependency>
            <groupId>io.micrometer</groupId>
            <artifactId>micrometer-core</artifawww.devze.comctId>
            <version>1.9.4</version>
          </dependency>

      示例

      		// hikari配置       
      		HikariConfig hikariConfig = new HikariConfig();
              hikariConfig.setJdbcUrl("jdbc:mysql://localhost:3306/laker?serverTimezone=GMT%2B8&characterEncoding=utf8&useSSL=false");
              hikariConfig.setUsername("root");
              hikariConfig.setPassword("123456");
              hikariConfig.setDriverClassName("com.mysql.jdbc.D编程客栈river");
              hikariConfig.setAutoCommit(true);
              hikariConfig.setPoolName("laker_poolName");
              hikariConfig.setMaximumPoolSize(10);
              hikariConfig.setMinimumIdle(3);
              // 创建HikariDataSource
              HikariDataSource dataSource = new HikariDataSource(hikariConfig);
              // 设置metric注册器 每10秒打印一次
              LoggingMeterRegistry loggingMeterRegistry = new LoggingMeterRegistry(new LoggingRegistryConfig() {
                  @Override
                  public String get(String key) {
                      return null;
                  }
                  @Override
                  public Duration step() {
                      return Duration.ofSeconds(10);
                  }
              }, Clock.SYSTEM);
              dataSource.setMetricRegistry(loggingMeterRegistry);
      
              // 测试 持有3秒连接后才释放
              Connection connection = dataSource.getConnection();
              TimeUnit.SECONDS.sleep(3);
              connection.close();

      结果:

      hikaricp.connections{pool=laker_poolName} value=4

      hikaricp.connections.active{pool=laker_poolName} value=1

      hikaricp.connections.idle{pool=laker_poolName} value=3

      hikaricp.connections.max{pool=laker_poolName} value=10

      hikaricp.connections.min{pool=laker_poolName} value=3

      hikaricp.connections.pending{pool=laker_poolName} value=0

      hikaricp.connections.acquire{pool=laker_poolName} throughput=0.1/s mean=0.0000581s max=0.0000581s

      hikaricp.connections.creation{pool=laker_poolName} throughput=0.3/s mean=0.006666666s max=0.007s

      hikaricp.connections.usage{pool=laker_poolName} throughput=0.1/s mean=3.017s max=3.017s

      指标详解

      对应的指标在com.zaxxer.hikari.metrics.PoolStats中。

      指标详解
      hikaricp.connections当前总连接数,包括空闲的连接和使用中的连接。(4 = 3 + 1)对应上面日志;

      Connections = activeConnection + idleConnections,会随着连接使用情况变化。

      hikaricp.connections.active正在使用中活跃连接数 (1),会随着连接使用情况变化。
      hikaricp.connections.idle空闲连接数 (3) ,会随着连接使用情况变化。
      hikaricp.connejsctions.max最大连接数 (10),初始配置。
      hikaricp.connections.min最小连接数 (3),初始配置。
      hikaricp.connections.pending正在等待连接的线程数量(0)。重点:一般来说,这里应该都是0,如果存在这个数据并且时间较长要触发告警,视情况加大最大连接数。
      hikaricp.connections.acquire获取每个连接需要时间,单位为ns。
      hikaricp.connections.creation连接创建时间,单位为ms。
      hikaricp.connections.timeout创建连接超时次数。
      hikaricp.connections.usage连接从池中取出到返回的时间,单位为ms。即连接被业务占用时间(3.017s)。重点:这个时间长的话,

      可能是慢SQL或者长事务导致连接被占用问题。

      Spring Boot环境

      手动

      还是添加上面的依赖组件。

      @Configuration
      public class DatasourceConfiguration {
          @Bean
          public DataSource primaryDataSource(MetricRegistry metricRegistry) {
      		HikariConfig hikariConfig = new HikariConfig();
              hikariConfig.setJdbcUrl("jdbc:mysql://localhost:3306/laker?serverTimezone=GMT%2B8&characterEncoding=utf8&useSSL=false");
              hikariConfig.setUsername("root");
              hikariConfig.setPassword("123456");
              hikariConfig.setDriverClassName("com.mysql.jdbc.Driver");
              hikariConfig.setAutoCommit(true);
              hikariConfig.setPoolName("laker_poolName");
              hikariConfig.setMaximumPoolSize(10);
              hikariConfig.setMinimumIdle(3);
              // 创建HikariDataSource
              HikariDataSource dataSource = new HikariDataSource(hikariConfig);
              dataSource.setMetricRegistry(loggingMeterRegistry);
              return dataSource;
          }
      }

      自动

      只需要添加如下依赖,内部会自动加上HikariCPmicrometer-core依赖http://www.devze.com,并自动配置注册器。

        <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

      原理,我们可以看这个类DataSourcePoolMetricsAutoConfiguration.java

      可观测性-Metrics-数据库连接池HikariCP监控教程

      关于Sql日志记录和慢日志

      可以看这个Issue:https://github.com/brettwooldridge/HikariCP/issues/57#issuecomment-354647631

      作者是不愿意在连接池层去做这种监控的事情的,应为会大大降低其性能。

      注意:

      • Sql记录功能会导致性能编程客栈下降,所以建议仅能用于开发、测试环境。
      • 慢日志可以考虑通过事件类型,发送事件用于告警,关联更多的上下文,在ORM层去做,例如在MyBATis的拦截器做。

      总结

      以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程客栈(www.devze.com)。

      0

      上一篇:

      下一篇:

      精彩评论

      暂无评论...
      验证码 换一张
      取 消

      最新开发

      开发排行榜