可觀測性-Metrics-數(shù)據(jù)庫連接池HikariCP監(jiān)控教程
非SpringBoot環(huán)境
HikariCP
其內部提供了setMetricRegistry()
方法,讓我們可以注入MetricRegistry來實現(xiàn)對連接池指標的收集。
這樣我們可以較為方便的監(jiān)控連接池的運行狀態(tài)。
添加依賴
<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); // 創(chuàng)建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 | 當前總連接數(shù),包括空閑的連接和使用中的連接。(4 = 3 + 1)對應上面日志; Connections = activeConnection + idleConnections,會隨著連接使用情況變化。 |
hikaricp.connections.active | 正在使用中活躍連接數(shù) (1),會隨著連接使用情況變化。 |
hikaricp.connections.idle | 空閑連接數(shù) (3) ,會隨著連接使用情況變化。 |
hikaricp.connections.max | 最大連接數(shù) (10),初始配置。 |
hikaricp.connections.min | 最小連接數(shù) (3),初始配置。 |
hikaricp.connections.pending | 正在等待連接的線程數(shù)量(0)。重點:一般來說,這里應該都是0,如果存在這個數(shù)據(jù)并且時間較長要觸發(fā)告警,視情況加大最大連接數(shù)。 |
hikaricp.connections.acquire | 獲取每個連接需要時間,單位為ns。 |
hikaricp.connections.creation | 連接創(chuàng)建時間,單位為ms。 |
hikaricp.connections.timeout | 創(chuàng)建連接超時次數(shù)。 |
hikaricp.connections.usage | 連接從池中取出到返回的時間,單位為ms。即連接被業(yè)務占用時間(3.017s)。重點:這個時間長的話, 可能是慢SQL或者長事務導致連接被占用問題。 |
Spring Boot環(huán)境
手動
還是添加上面的依賴組件。
@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); // 創(chuàng)建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
作者是不愿意在連接池層去做這種監(jiān)控的事情的,應為會大大降低其性能。
注意:
- Sql記錄功能會導致性能下降,所以建議僅能用于開發(fā)、測試環(huán)境。
- 慢日志可以考慮通過事件類型,發(fā)送事件用于告警,關聯(lián)更多的上下文,在ORM層去做,例如在Mybatis的攔截器做。
總結
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
Spring Boot 中的 Spring Cloud Feign的原
Spring Cloud Feign 是 Spring Cloud 中的一個組件,它可以幫助我們實現(xiàn)聲明式的 REST 客戶,這篇文章主要介紹了Spring Boot 中的 Spring Cloud Feign,需要的朋友可以參考下2023-07-07Java xml出現(xiàn)錯誤 javax.xml.transform.TransformerException: java.
這篇文章主要介紹了Java xml出現(xiàn)錯誤 javax.xml.transform.TransformerException: java.lang.NullPointerException的相關資料,需要的朋友可以參考下2016-11-11如何通過RabbitMq實現(xiàn)動態(tài)定時任務詳解
工作中經(jīng)常會有定時任務的需求,常見的做法可以使用Timer、Quartz、Hangfire等組件,這次想嘗試下新的思路,使用RabbitMQ死信隊列的機制來實現(xiàn)定時任務,下面這篇文章主要給大家介紹了關于如何通過RabbitMq實現(xiàn)動態(tài)定時任務的相關資料,需要的朋友可以參考下2022-01-01Java實現(xiàn)儲存對象并按對象某屬性排序的幾種方法示例
這篇文章主要介紹了Java實現(xiàn)儲存對象并按對象某屬性排序的幾種方法,結合實例形式詳細分析了Java儲存對象并按對象某屬性排序的具體實現(xiàn)方法與操作注意事項,需要的朋友可以參考下2020-05-05go語言題解LeetCode88合并兩個有序數(shù)組示例
這篇文章主要為大家介紹了go語言題解LeetCode88合并兩個有序數(shù)組示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-12-12Java中Array、List、ArrayList的區(qū)別及說明
這篇文章主要介紹了Java中Array、List、ArrayList的區(qū)別及說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-07-07