Tomcat で OpenEJB を使用します (JBoss、Weblogic などで実行するために使用されます)。負荷テストの実行中に、JMS メッセージ (キュー) の処理で重大なパフォーマンスの問題が発生します。問題は、データベース接続プールがプールへの接続を取得または解放する際のブロックに限られていました。ブロッキングによって同時 MDB インスタンス (スレッド) の実行が妨げられたため、パフォーマンスが 10 倍以上低下しました。アプリケーション サーバーで (それぞれの接続プールの実装を使用して) 実行するために使用される同じコードは、まったくブロックされません。
ブロックされたスレッドの例:
Name: JMS Resource Adapter-worker-23
State: BLOCKED on org.apache.commons.pool.impl.GenericObjectPool@1ea6b4a owned by: JMS Resource Adapter-worker-19
Total blocked: 18,426 Total waited: 0
Stack trace:
org.apache.commons.pool.impl.GenericObjectPool.returnObject(GenericObjectPool.java:916)
org.apache.commons.dbcp.PoolableConnection.close(PoolableConnection.java:91)
- locked org.apache.commons.dbcp.PoolableConnection@1bcba8
org.apache.commons.dbcp.managed.ManagedConnection.close(ManagedConnection.java:147)
com.xxxxx.persistence.DbHelper.closeConnection(DbHelper.java:290)
....
いくつか質問があります。
- 一部のトランザクション属性とプロパティがこのブロックに寄与していることはほぼ確実ですが、MDB は非トランザクションとして定義されています (注釈と ejb-jar.xml の両方を使用しています)。ただし、一部の EJB はコンテナー管理のトランザクションを使用します (そこでもブロックを観察できます)。ブロッキングを修正できる DBCP 構成はありますか?
- DBCP接続プールの実装はOpenEJBで置き換え可能ですか? それを別のライブラリに置き換えるのはどれくらい簡単(難しい)ですか?
念のため、これが OpenEJB (openejb.xml) でデータ ソースを定義する方法です。
<Resource id="MyDataSource" type="DataSource">
JdbcDriver oracle.jdbc.driver.OracleDriver
JdbcUrl ${oracle.jdbc}
UserName ${oracle.user}
Password ${oracle.password}
JtaManaged true
InitialSize 5
MaxActive 30
ValidationQuery SELECT 1 FROM DUAL
TestOnBorrow true
</Resource>