コネクションプールライブラリ HikariCPのMBean (JMX)を取得し表示する

# はじめに

HikariCPは高速なコネクションプールライブラリで人気があるようです。
HikariCPのプール中の情報はJMXで取得できます。取得できる情報は以下のとおりです。

- アイドルしているコネクションの数
- アクティブなコネクションの数
- 合計コネクション数（アイドル＋アクティブ）
- コネクション取得を待っているスレッドの数


# MBeanを取得できるように設定を変更する。

HikariCPのデフォルトではMBeanが取得できないようになっているため、以下の2つの設定を追加します。

- poolName (デフォルト : auto-generated)
loggingとJMX managementで出力されるpoolの名前を指定する。

- registerMbeans (デフォルト : false)
MBeanに登録するかどうかを決めます。

DataSourceをSpring XML DSLで設定している場合は、以下の2行を追加するだけです。

```xml
		<property name="registerMbeans" value="true" />
		<property name="poolName" value="testHikariPool" />
```

追加後の設定例は以下のとおり。

```xml
	<bean id="hikariConfig" class="com.zaxxer.hikari.HikariConfig">
		<property name="jdbcUrl" value="jdbc:postgresql://192.168.20.71:5432/testdb" />
		<property name="driverClassName" value="org.postgresql.Driver" />
		<property name="minimumIdle" value="10" />
		<property name="maximumPoolSize" value="100" />
		<property name="connectionTimeout" value="30000" />
		<property name="idleTimeout" value="600000" />
		<property name="maxLifetime" value="1800000" />
		<property name="username" value="postgres" />
		<property name="password" value="postgres" />
		<property name="connectionInitSql" value="SELECT 1" />
		<!-- <property name="connectionTestQuery" value="SELECT 1" />  --><!-- connectionTestQueryは非推奨 -->
		<property name="validationTimeout" value="5000" />
		<property name="registerMbeans" value="true" />
		<property name="poolName" value="testHikariPool" />
	</bean>

	<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource"
		destroy-method="close">
		<constructor-arg ref="hikariConfig" />
	</bean>
```


# JMXで取得し、表示する

hawtioというWebコンソールを用いて、MBeanの情報を表示しています。
jconsoleでも同じように表示できます。



![image.png](https://qiita-image-store.s3.amazonaws.com/0/179607/3bd2b248-5eb0-0b74-0386-808c7255232a.png)

hawtioだと、以下のようにグラフで表示することもできます（見づらいけど！）。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/179607/d603d53c-0784-1397-76b4-01ceea3761b3.png)

現時点でのコネクション数などは以下のように取得できる。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/179607/262c350b-9990-74ea-7922-ce507e48b6a8.png)

HikariCPの設定情報も以下のように取得できる。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/179607/e40c231c-c14c-dfed-8e19-723063538e59.png)

プールのコネクション数は何となく設定して後々性能問題を引き起こしたりもします。性能に関する問題が生じてもプーリングが問題だというのはモニタリングしていないと気付きにくいです。
開発中でもコネクション数が取得できると便利ですし、プロダクション環境でもモニタリングしていた方が良いでしょう。JMXで取得できるので、zabbix等でもモニタリングできます。

参考：このデータソースをApache Camelのプロセッサから取得する場合は以下のコードになる。

```java
@Component
public class InsertSql implements Processor {

	@Resource
	private CamelContext context;

	private Logger logger = LoggerFactory.getLogger("sample.CreateDataProcessor");

	private String sql = "insert into log_tbl(id, msg1, msg2, insert_time) values(logkey_seq.NEXTVAL, ?, ?, current_timestamp)";

	private Faker faker = new Faker(new Locale("ja_JP"));

    @Override
    public void process(Exchange exchange) throws Exception {

    	HikariDataSource ds = (HikariDataSource)context.getRegistry().lookupByName("dataSource");

		try (Connection con = ds.getConnection();
				PreparedStatement ps = con.prepareStatement(sql);) {
			ps.setString(1, faker.lorem().sentence(3));
			ps.setString(2, faker.lorem().sentence(5));

			logger.info("insert process");
			try (ResultSet rs = ps.executeQuery();) {
				con.commit();
			}
		} catch (SQLException e) {
			logger.error(e.getMessage(), e);
		}
    }
}

/* DDLは以下のとおり
CREATE TABLE log_tbl
 (
 id number NOT NULL,
 msg1 varchar2(128),
 msg2 varchar2(128),
 insert_time timestamp
 );
*/
```

# 参考

MBean (JMX) Monitoring and Management
https://github.com/brettwooldridge/HikariCP/wiki/MBean-(JMX)-Monitoring-and-Management

世界の一部 JDBC Connection Pool [HikariCP] 設定
http://time-complexity.blogspot.com/2015/03/db-connection-pool-hikaricp.html