はじめに
今回は、Liberty の接続プールを REST API を使用して空にする方法をまとめてみました。Liberty を停止せずに DB 等への接続を即時にクローズしたいことが希にあり、そのようなケースで役に立つものです。
使用する REST API は、Liberty が REST コネクターとして以前から提供している機能です。REST コネクターを使用すると、Java の JMX MBean (Java Management Extensions (JMX) 管理 Bean) が提供する機能を REST API で実行することができます。
準備
REST コネクターを利用するには、以下の2つの準備が必要となります。
- restConnector-2.0 フィーチャーを有効にする
- administrator ロールを持つユーザーをレジストリーに登録する
詳細は、以前執筆した「Liberty のテスト接続機能を利用する」の「準備」の部分を参照してください。
MBean メソッドの実行方法を確認する
上記の準備を施した Liberty を起動し、ブラウザーで下記の URL にアクセスすると、REST API のヘルプ画面が表示されます。尚、ベーシック認証で保護されていますので、上記の方法で定義した administrator ロールを持つユーザーでアクセスする必要があります。
- https://(ホスト):(ポート)/IBMJMXConnectorREST/api
この画面の左上に表示されたドロップダウンから実行したい操作を選択すると、選択した操作の呼び出し方法が確認できます。
今回は、MBean のメソッドを実行する操作を利用します。ドロップダウンから「MBean > MBean operation invocation」を選択すると、その方法が表示されます。
ヘルプ画面に示されたように、MBean の名前 {objectName}
とメソッド名 {operation}
から特定される下記の URL に対して、MBean のメソッドに渡すパラメーター(値と型)とメソッドのシグニチャーを JSON 形式で記述したデータを HTTP の POST で送信すれば良いわけです。表示されたヘルプ画面では、パラメーター数が 0、1、および、3 個のケースで、POST する JSON 形式のデータの例が確認できます。
この URL も、ベーシック認証で保護されていますので、前述の方法で定義した administrator ロールを持つユーザーでアクセスすることになります。
- https://(ホスト):(ポート)/IBMJMXConnectorREST/mbeans/{objectName}/operations/{operation}
また、下記の URL にアクセスすると、その時点で利用可能な MBean の情報(objectName, クラス名、URL)がリストできます。
尚、Liberty の MBean は、該当の機能が初めて使用されるときに作成されますので、アクセスした時点で使用されていない機能の MBean はリストされません。
- https://(ホスト):(ポート)/IBMJMXConnectorREST/mbeans
Liberty や JVM の MBean の情報は、以下の URL で確認できます。
- Liberty の MBean (Liberty API)
- JVM の MBean
接続プールを空にする
では、Liberty の MBean のメソッドを REST API で呼び出して、接続プールを空にしてみましょう。
使用する MBean の説明
接続プールを管理する MBean は、ConnectionManagerMBean
です。
ConnectionManagerMBean
の情報は、上記の Liberty API のドキュメントのトップページから、下記のリンクを辿ると表示できます。
- WAS Liberty の場合
- WebSphere Connection Manager API > ConnectionManagerMBean
- Open Liberty の場合
- Java Database Connectivity 4.3 > com.ibm.ws.jca.cm.mbean > ConnectionManagerMBean
ConnectionManagerMBean
のドキュメントを見ると、この MBean は下記のメソッドを持ち、purgePoolContents
メソッドを実行すると接続プールを空にできることが分かります。
- String abortConnections(String type, Long time) -- deprecated
- long getAvailable()
- String getJndiName()
- long getMaxSize()
- long getSize()
- void purgePoolContents(String doImmediately)
- String showPoolContents()
使用する MBean の URL を取得
MBean のドキュメントに MBean の objectName
の例が記載されています。この例を参考にして、objectName
を特定することもできますが、ここでは、先ほど紹介した「https://(ホスト):(ポート)/IBMJMXConnectorREST/mbeans」にアクセスして取得します。
この URL に GET でアクセスし、jq で成形した出力から、今回利用する ConnectionManagerMBean
を含むものを grep します。下記の実行例では、1つの ConnectionManagerMBean
の情報(objectName,className,URL)が出力されており、この出力から MBean の URL を特定できます。
ConnectionManagerMBean
は接続プールごとに作成されます。複数の接続プールが存在する場合も、objectName
の内容からどの接続プールの MBean か特定できます。
尚、ConnectionManagerMBean
は、該当の接続プールが利用されるまで作成されませんので、接続プールが利用された後でないと、この方法は利用できません。
> curl -s --insecure -u admin:pswd https://localhost:9443/IBMJMXConnectorREST/mbeans | jq | grep ConnectionManagerMBean
"objectName": "WebSphere:type=com.ibm.ws.jca.cm.mbean.ConnectionManagerMBean,jndiName=jdbc/sample,name=dataSource[SampleDS]/connectionManager",
"className": "com.ibm.ws.jca.cm.mbean.ConnectionManagerMBean",
"URL": "/IBMJMXConnectorREST/mbeans/WebSphere%3AjndiName%3Djdbc%2Fsample%2Cname%3DdataSource%5BSampleDS%5D%2FconnectionManager%2Ctype%3Dcom.ibm.ws.jca.cm.mbean.ConnectionManagerMBean"
MBean のメソッドを実行: showPoolContents
先ほどの出力から、今回利用する MBean の objectName と URL が特定できました。今回は、以下の URL を利用すれば良いことになります。
- https://(ホスト):(ポート)/IBMJMXConnectorREST/mbeans/WebSphere%3AjndiName%3Djdbc%2Fsample%2Cname%3DdataSource%5BSampleDS%5D%2FconnectionManager%2Ctype%3Dcom.ibm.ws.jca.cm.mbean.ConnectionManagerMBean/{method}
接続プールを空にするのは、purgePoolContents
メソッドとなりますが、まずは、簡単に実行できそうな(パラメーターを必要としない) showPoolContents
メソッドを試してみます。これは、接続プールの内容(状態)を返すメソッドです。
showPoolContents
メソッドはパラメーターを必要としないので、以下のような JSON データを使います。
> echo {"params":[],"signature":[]} | jq
{
"params": [],
"signature": []
}
準備した JSON データを先ほどの URL にポストします。POST するデータの Content-Type には application/json を指定する必要があります。
> echo {"params":[],"signature":[]} | curl --insecure -u admin:pswd -X POST -H "Content-Type: application/json" -d @- https://localhost:9443/IBMJMXConnectorREST/mbeans/WebSphere%3AjndiName%3Djdbc%2Fsample%2Cname%3DdataSource%5BSampleDS%5D%2FconnectionManager%2Ctype%3Dcom.ibm.ws.jca.cm.mbean.ConnectionManagerMBean/operations/showPoolContents
{"value":"PoolManager@a985c0a6\r\nname=WebSphere:type=com.ibm.ws.jca.cm.mbean.ConnectionManagerMBean,jndiName=jdbc/sample,name=dataSource[SampleDS]/connectionManager\r\njndiName=jdbc/sample\r\nmaxPoolSize=50\r\nsize=1\r\nwaiting=0\r\nunshared=0\r\nshared=0\r\navailable=1\r\n ManagedConnection@fcc2537f=Reusable\r\n","type":"java.lang.String"}
出力が見にくいので、jq --raw-output ".value"
にパイプして、value のみを取り出してエスケープを解除すると以下の様になります。
size=1
、available=1
とあり、接続プールのサイズと利用可能な接続数はともに 1 であることが確認できます。
> echo {"params":[],"signature":[]} | curl --insecure -s -u admin:pswd -X POST -H "Content-Type: application/json" -d @- https://localhost:9443/IBMJMXConnectorREST/mbeans/WebSphere%3AjndiName%3Djdbc%2Fsample%2Cname%3DdataSource%5BSampleDS%5D%2FconnectionManager%2Ctype%3Dcom.ibm.ws.jca.cm.mbean.ConnectionManagerMBean/operations/showPoolContents | jq --raw-output ".value"
PoolManager@a985c0a6
name=WebSphere:type=com.ibm.ws.jca.cm.mbean.ConnectionManagerMBean,jndiName=jdbc/sample,name=dataSource[SampleDS]/connectionManager
jndiName=jdbc/sample
maxPoolSize=50
size=1
waiting=0
unshared=0
shared=0
available=1
ManagedConnection@f28fea39=Reusable
MBean のメソッドを実行: purgePoolContents
purgePoolContents
メソッドを実行して、接続プールを空にしてみます。
purgePoolContents
メソッドは、1つの String 型のパラメーターを必要とするメソッドなので、POST で送信する JSON データは以下のような内容になります。
ドキュメントによると、パラメーターの値には、"immediate" や "abort" を指定できますが、実行中のアプリケーションの処理に影響が無いように、"immediate" を指定しています。
> echo {"params":[{"value":"immediate","type":"java.lang.String"}],"signature":["java.lang.String"]} | jq
{
"params": [
{
"value": "immediate",
"type": "java.lang.String"
}
],
"signature": [
"java.lang.String"
]
}
以下は、purgePoolContents
メソッドを実行した例です。
purgePoolContents
メソッドの戻り値の型は void なので、成功しても、{"value":null,"type":null}
が返されるだけになります。
> echo {"params":[{"value":"immediate","type":"java.lang.String"}],"signature":["java.lang.String"]} | curl --insecure -u admin:pswd -X POST -H "Content-Type: application/json" -d @- https://localhost:9443/IBMJMXConnectorREST/mbeans/WebSphere%3AjndiName%3Djdbc%2Fsample%2Cname%3DdataSource%5BSampleDS%5D%2FconnectionManager%2Ctype%3Dcom.ibm.ws.jca.cm.mbean.ConnectionManagerMBean/operations/purgePoolContents
{"value":null,"type":null}
実際に接続プールが空になっていることは、先ほどの showPoolContents
メソッドを実行することで確認できます。以下の様に、size=0
となっていれば、接続プールは空の状態です。
> echo {"params":[],"signature":[]} | curl --insecure -u admin:pswd -X POST -H "Content-Type: application/json" -d @- https://localhost:9443/IBMJMXConnectorREST/mbeans/WebSphere%3AjndiName%3Djdbc%2Fsample%2Cname%3DdataSource%5BSampleDS%5D%2FconnectionManager%2Ctype%3Dcom.ibm.ws.jca.cm.mbean.ConnectionManagerMBean/operations/showPoolContents | jq --raw-output ".value"
PoolManager@a985c0a6
name=WebSphere:type=com.ibm.ws.jca.cm.mbean.ConnectionManagerMBean,jndiName=jdbc/sample,name=dataSource[SampleDS]/connectionManager
jndiName=jdbc/sample
maxPoolSize=50
size=0
waiting=0
unshared=0
shared=0
available=0
終わりに
Liberty の REST コネクターを使用すると、Liberty の内部状態を MBean から取得したり、MBean のメソッドを実行することで様々な操作を行うことができます。
今回は、REST コネクターを使用して、Liberty の接続プールを空にしてみました。この情報が何かのお役に立てば幸いです。