非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</artifactid> <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.driver"); 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.connections.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; } }
自动
只需要添加如下依赖,内部会自动加上hikaricp
和micrometer-core
依赖,并自动配置注册器。
<dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-actuator</artifactid> </dependency>
原理,我们可以看这个类datasourcepoolmetricsautoconfiguration.java
关于sql日志记录和慢日志
可以看这个issue:https://github.com/brettwooldridge/hikaricp/issues/57#issuecomment-354647631
作者是不愿意在连接池层去做这种监控的事情的,应为会大大降低其性能。
注意:
- sql记录功能会导致性能下降,所以建议仅能用于开发、测试环境。
- 慢日志可以考虑通过事件类型,发送事件用于告警,关联更多的上下文,在orm层去做,例如在mybatis的拦截器做。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论