LoginSignup
93
93

More than 5 years have passed since last update.

Tomcat JDBC Connection Poolの存在を忘れてました

Last updated at Posted at 2015-11-04

はじめに

少し前まで業務でSeasar2 FWを使っていたためコネクションプールはSeasar2のものを利用していました。S2のコネクションプールの実装はシンプルだったし業務で利用していても特にそこがボトルネックになることはありませんでした。
別のプロジェクトに移ってDBCPを触っていたのですが、実装になんとなく疑問を感じたので調べてみました。

tomcat jdbc connection poolとは?

  • tomcatで実装したConnectionPoolの実装です。(DBCPとは異なります。)
  • tomcat 7.0.19から利用できます。
  • tomat-jdbc.jarに含まれています。
  • DBCPからの切り替えはfactoryを変更するだけです。
  • tomcatのdefaultではDBCPが選択されていますので明示的に変更が必要です。
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"

どこに違いがあるのか。

パフォーマンス

  • DBCPよりパフォーマンスが優れています。
  • connectionを取得して簡単なSQLを投げてCloseする。という流れを1000回投げてみたところ、DBCPでは平均33msecでしたが、tomcat jdbc poolは平均10msecでした。
  • ThreadPoolを使って同時5スレッドで試しましたが性能差は同様でした。

設定値に対する内部動作

  • 設定値の意味については基本的に違いはありませんが、内部ではいろいろ違います。
  • 例えばDBCPではシングルスレッドで動きgetConnection時にsynchronizedをかけてコネクションのチェック処理&取得を行っているようです。jdbc connection poolはconnectionの利用を監視している部分は別のThreadで行っており、この点からもパフォーマンス的にはよさそうでした。
  • 細かい点で動きが違う点を挙げておきます。
  • 初期のコネクションプールのサイズを決めるinitialsizeを0、minIdleを10としたときにDBCPではminIdleの設定(10)が有効になりますが、dbcpではinitialsizeが0であれば起動時は0になり利用される度にminIdle以下であれば保持するような動きをするようです。

Interceptor

Interceptorを使う

  • QueryTimeoutInterceptorを利用してQueryTimeoutを設定するには以下のようにします。
  • package名は省略することが可能です。引数は()内に記載します。
jdbcInterceptors="QueryTimeoutInterceptor(queryTimeout=10)"

独自のInterceptorを作る

  • org.apache.tomcat.jdbc.pool.JdbcInterceptorを実装するだけです。
  • tomcat-jdbcはtomcat-juli.jarのみに依存していますのでそれだけ依存関係に追加しておきましょう。
  • Commons DBCPを超えるTomcat JDBC Poolとは

JMX

  • jconsoleでtomcatを叩くとjmx経由でdatasourceの情報が取得できます。
  • DBCPでできる操作はremoveConnectionProperty,addConnectionProperty,getConnection closeです。
  • tomcat jdbc connection poolでは、checkIdle,testIdle,checkAbandonedを操作できます。

パラメータについて(tomcat jdbc pool)

属性 説明 設定例
type javax.sql.DataSource
driverClassName JDBCドライバのクラス名
url 接続URL
username データベースに接続するユーザ名
password データベースに接続するパスワード
factory org.apache.tomcat.jdbc.pool.DataSourceFactory
jdbcInterceptors Interceptorのクラス名と引数を指定する。複数記載するときには;(セミコロン)で区切る 例)QueryTimeoutInterceptor(queryTimeout=10) 
initialSize tomcat起動時に作成するプールの初期値 10
maxActive データベース接続の最大数 100
minIdle アイドルするコネクションの最小数 10
maxIdle アイドルするコネクションの最大数 50
testWhileIdle コネクションの有効性を確認するか否か true
testOnBorrow プールからコネクションを取得する際に有効性を確認するか否か true
testOnReturn プールにコネクションを返却する際に有効性を確認するか否か true
validationQuery 有効性を確認するときのSQLを指定する
validationInterval 有効性を確認する間隔を指定する 15(sec)
timeBetweenEvictionRunsMillis 指定した間隔でコネクションの有効性確認を行う。tomcat7.0.23で確認したところminIdleまで減るが、minIdle以下の場合minIdleにまで増やすことは行わない 15000(msec)
minEvictableIdleTimeMillis アイドル接続しているコネクションの生存時間 msec
removeAbandoned removeAbandonedTimeoutを過ぎたコネクションを自動で切断するか否か。この時切断したコネクションはプールに戻らないので注意が必要。 true
removeAbandonedTimeout コネクションを切断するまでの時間 10(sec)
poolPreparedStatements 利用不可
maxOpenPreparedStatements 利用不可
numTestsPerEvictionRun 利用不可
93
93
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
93
93