0
# JMX Management and Monitoring
1
2
Runtime monitoring and management capabilities through JMX beans, providing pool statistics and runtime configuration changes.
3
4
## Capabilities
5
6
### Pool Statistics and Monitoring
7
8
Monitor real-time pool statistics through the HikariPoolMXBean interface.
9
10
```java { .api }
11
/**
12
* JMX management bean interface for pool monitoring and control
13
*/
14
public interface HikariPoolMXBean {
15
/**
16
* Get the number of currently idle connections in the pool
17
* @return the number of idle connections
18
*/
19
int getIdleConnections();
20
21
/**
22
* Get the number of currently active (in-use) connections
23
* @return the number of active connections
24
*/
25
int getActiveConnections();
26
27
/**
28
* Get the total number of connections in the pool (idle + active)
29
* @return the total number of connections
30
*/
31
int getTotalConnections();
32
33
/**
34
* Get the number of threads currently awaiting a connection from the pool
35
* @return the number of threads awaiting connection
36
*/
37
int getThreadsAwaitingConnection();
38
}
39
```
40
41
**Usage Examples:**
42
43
```java
44
// Access through HikariDataSource
45
HikariDataSource dataSource = new HikariDataSource(config);
46
HikariPoolMXBean poolBean = dataSource.getHikariPoolMXBean();
47
48
if (poolBean != null) {
49
// Monitor pool health
50
int active = poolBean.getActiveConnections();
51
int idle = poolBean.getIdleConnections();
52
int total = poolBean.getTotalConnections();
53
int waiting = poolBean.getThreadsAwaitingConnection();
54
55
System.out.println("Pool Statistics:");
56
System.out.println(" Active: " + active);
57
System.out.println(" Idle: " + idle);
58
System.out.println(" Total: " + total);
59
System.out.println(" Waiting threads: " + waiting);
60
61
// Check pool utilization
62
double utilization = (double) active / total * 100;
63
if (utilization > 80) {
64
System.out.println("High pool utilization: " + utilization + "%");
65
}
66
}
67
```
68
69
### Pool Control Operations
70
71
Control pool behavior through management operations.
72
73
```java { .api }
74
/**
75
* Perform a "soft" eviction of idle connections. Connections that are currently in use
76
* will not be evicted, only idle connections will be removed from the pool.
77
*/
78
void softEvictConnections();
79
80
/**
81
* Suspend allocation of connections from the pool. All callers to getConnection()
82
* will block indefinitely until resumePool() is called.
83
*/
84
void suspendPool();
85
86
/**
87
* Resume allocation of connections from the pool after a call to suspendPool().
88
*/
89
void resumePool();
90
```
91
92
**Usage Examples:**
93
94
```java
95
HikariPoolMXBean poolBean = dataSource.getHikariPoolMXBean();
96
97
// Evict idle connections (useful for maintenance)
98
poolBean.softEvictConnections();
99
100
// Suspend pool for maintenance
101
poolBean.suspendPool();
102
try {
103
// Perform database maintenance operations
104
performDatabaseMaintenance();
105
} finally {
106
// Always resume the pool
107
poolBean.resumePool();
108
}
109
110
// Graceful pool drain for shutdown
111
poolBean.suspendPool();
112
// Wait for active connections to finish
113
while (poolBean.getActiveConnections() > 0) {
114
Thread.sleep(100);
115
}
116
poolBean.softEvictConnections();
117
```
118
119
### Runtime Configuration Management
120
121
Modify pool configuration at runtime through the HikariConfigMXBean interface.
122
123
```java { .api }
124
/**
125
* JMX management bean interface for runtime configuration changes
126
*/
127
public interface HikariConfigMXBean {
128
/**
129
* Get/set the maximum number of milliseconds that a client will wait for a connection from the pool
130
*/
131
long getConnectionTimeout();
132
void setConnectionTimeout(long connectionTimeoutMs);
133
134
/**
135
* Get/set the maximum number of milliseconds that the pool will wait for a connection to be validated
136
*/
137
long getValidationTimeout();
138
void setValidationTimeout(long validationTimeoutMs);
139
140
/**
141
* Get/set the maximum amount of time that a connection is allowed to sit idle in the pool
142
*/
143
long getIdleTimeout();
144
void setIdleTimeout(long idleTimeoutMs);
145
146
/**
147
* Get/set the amount of time that a connection can be out of the pool before leak detection triggers
148
*/
149
long getLeakDetectionThreshold();
150
void setLeakDetectionThreshold(long leakDetectionThresholdMs);
151
152
/**
153
* Get/set the maximum lifetime of a connection in the pool
154
*/
155
long getMaxLifetime();
156
void setMaxLifetime(long maxLifetimeMs);
157
158
/**
159
* Get/set the minimum number of idle connections that HikariCP tries to maintain in the pool
160
*/
161
int getMinimumIdle();
162
void setMinimumIdle(int minIdle);
163
164
/**
165
* Get/set the maximum size that the pool is allowed to reach
166
*/
167
int getMaximumPoolSize();
168
void setMaximumPoolSize(int maxPoolSize);
169
170
/**
171
* Set the password used for authentication. Changing this at runtime will apply to new connections only.
172
* Altering this at runtime only works for DataSource-based connections, not Driver-class or JDBC URL-based connections.
173
*/
174
void setPassword(String password);
175
176
/**
177
* Set the username used for authentication. Changing this at runtime will apply to new connections only.
178
* Altering this at runtime only works for DataSource-based connections, not Driver-class or JDBC URL-based connections.
179
*/
180
void setUsername(String username);
181
182
/**
183
* Get the name of the connection pool
184
*/
185
String getPoolName();
186
}
187
```
188
189
**Usage Examples:**
190
191
```java
192
HikariConfigMXBean configBean = dataSource.getHikariConfigMXBean();
193
194
// Adjust pool size based on load
195
int currentLoad = getCurrentSystemLoad();
196
if (currentLoad > 80) {
197
// Increase pool size during high load
198
configBean.setMaximumPoolSize(30);
199
configBean.setMinimumIdle(10);
200
} else if (currentLoad < 20) {
201
// Decrease pool size during low load
202
configBean.setMaximumPoolSize(10);
203
configBean.setMinimumIdle(2);
204
}
205
206
// Adjust timeouts for different environments
207
if (isProductionEnvironment()) {
208
configBean.setConnectionTimeout(5000); // 5 seconds in production
209
configBean.setValidationTimeout(1000); // 1 second validation
210
} else {
211
configBean.setConnectionTimeout(30000); // 30 seconds in dev/test
212
configBean.setValidationTimeout(5000); // 5 seconds validation
213
}
214
215
// Enable leak detection in development
216
if (isDevelopmentEnvironment()) {
217
configBean.setLeakDetectionThreshold(10000); // 10 seconds
218
} else {
219
configBean.setLeakDetectionThreshold(0); // Disabled in production
220
}
221
222
// Update credentials (DataSource-based connections only)
223
configBean.setUsername("new_user");
224
configBean.setPassword("new_password");
225
```
226
227
### JMX Integration Setup
228
229
Configure JMX registration and access to management beans.
230
231
```java { .api }
232
// In HikariConfig
233
/**
234
* Set whether or not JMX Management Beans (MBeans) are registered
235
* @param register whether to register JMX MBeans
236
*/
237
public void setRegisterMbeans(boolean register);
238
public boolean isRegisterMbeans();
239
240
/**
241
* Set the name of the connection pool. This is primarily used for the MBean
242
* to uniquely identify the pool configuration.
243
* @param poolName the name of the connection pool to use
244
*/
245
public void setPoolName(String poolName);
246
```
247
248
**Usage Examples:**
249
250
```java
251
// Enable JMX registration
252
HikariConfig config = new HikariConfig();
253
config.setRegisterMbeans(true);
254
config.setPoolName("MyAppConnectionPool");
255
config.setJdbcUrl("jdbc:postgresql://localhost:5432/mydb");
256
257
HikariDataSource dataSource = new HikariDataSource(config);
258
259
// Access via JMX (programmatically)
260
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
261
ObjectName poolName = new ObjectName("com.zaxxer.hikari:type=Pool (MyAppConnectionPool)");
262
ObjectName configName = new ObjectName("com.zaxxer.hikari:type=PoolConfig (MyAppConnectionPool)");
263
264
// Get pool statistics via JMX
265
Integer activeConnections = (Integer) server.getAttribute(poolName, "ActiveConnections");
266
Integer totalConnections = (Integer) server.getAttribute(poolName, "TotalConnections");
267
268
// Modify configuration via JMX
269
server.setAttribute(configName, new Attribute("MaximumPoolSize", 25));
270
server.invoke(poolName, "softEvictConnections", null, null);
271
```
272
273
### Monitoring and Alerting Integration
274
275
Integrate HikariCP JMX metrics with monitoring systems.
276
277
**Usage Examples:**
278
279
```java
280
// Custom monitoring integration
281
public class HikariPoolMonitor {
282
private final HikariPoolMXBean poolBean;
283
private final HikariConfigMXBean configBean;
284
private final String poolName;
285
286
public HikariPoolMonitor(HikariDataSource dataSource) {
287
this.poolBean = dataSource.getHikariPoolMXBean();
288
this.configBean = dataSource.getHikariConfigMXBean();
289
this.poolName = configBean.getPoolName();
290
}
291
292
public void checkPoolHealth() {
293
if (poolBean == null) return;
294
295
int active = poolBean.getActiveConnections();
296
int total = poolBean.getTotalConnections();
297
int waiting = poolBean.getThreadsAwaitingConnection();
298
299
// Check for high utilization
300
double utilization = (double) active / total;
301
if (utilization > 0.9) {
302
sendAlert("High pool utilization",
303
"Pool " + poolName + " is " + (utilization * 100) + "% utilized");
304
}
305
306
// Check for connection starvation
307
if (waiting > 5) {
308
sendAlert("Connection starvation",
309
waiting + " threads waiting for connections in pool " + poolName);
310
}
311
312
// Check for pool exhaustion
313
if (active >= total && waiting > 0) {
314
sendAlert("Pool exhausted",
315
"Pool " + poolName + " has no available connections");
316
}
317
}
318
319
public Map<String, Object> getMetrics() {
320
Map<String, Object> metrics = new HashMap<>();
321
if (poolBean != null) {
322
metrics.put("active_connections", poolBean.getActiveConnections());
323
metrics.put("idle_connections", poolBean.getIdleConnections());
324
metrics.put("total_connections", poolBean.getTotalConnections());
325
metrics.put("waiting_threads", poolBean.getThreadsAwaitingConnection());
326
}
327
328
metrics.put("max_pool_size", configBean.getMaximumPoolSize());
329
metrics.put("min_idle", configBean.getMinimumIdle());
330
metrics.put("connection_timeout", configBean.getConnectionTimeout());
331
metrics.put("pool_name", configBean.getPoolName());
332
333
return metrics;
334
}
335
336
private void sendAlert(String title, String message) {
337
// Integration with your alerting system
338
System.err.println("ALERT: " + title + " - " + message);
339
}
340
}
341
342
// Usage in application
343
HikariPoolMonitor monitor = new HikariPoolMonitor(dataSource);
344
345
// Schedule regular health checks
346
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
347
scheduler.scheduleAtFixedRate(monitor::checkPoolHealth, 0, 30, TimeUnit.SECONDS);
348
```