データベース コネクション プールの枯渇により高負荷状態となり Confluence の速度低下やタイムアウトが発生する
プラットフォームについて: サーバーと Data Center のみ。この記事は、サーバーおよび Data Center プラットフォームのアトラシアン製品にのみ適用されます。
問題
高負荷状態の期間に Confluence の速度が低下する。
この問題は原因ではなく症状と考えられることにご注意ください。他のスレッドがリソースを消費している可能性があります。
診断
速度低下中に 20 ~ 30 秒間隔で 10 個のスレッド ダンプを取得し、それらを分析します。
次のように、多数の HTTP スレッドが DB コネクションの取得を待機していることを確認できます。
"http-8080-Processor150" daemon prio=1 tid=0x08543368 nid=0x11aa in Object.wait() [0x665a4000..0x665a51b0]
at java.lang.Object.wait(Native Method)
- waiting on <0x83140488> (a com.mchange.v2.resourcepool.BasicResourcePool)
at com.mchange.v2.resourcepool.BasicResourcePool.awaitAcquire(BasicResourcePool.java:968)
at com.mchange.v2.resourcepool.BasicResourcePool.checkoutResource(BasicResourcePool.java:208)
- locked <0x83140488> (a com.mchange.v2.resourcepool.BasicResourcePool)
または
"TP-Processor3" daemon prio=1 tid=0x1fc5bd30 nid=0x279c in Object.wait() [0x1e47d000..0x1e47dda0]
at java.lang.Object.wait(Native Method)
at com.mchange.v2.resourcepool.BasicResourcePool.awaitAvailable(BasicResourcePool.java:1315)
at com.mchange.v2.resourcepool.BasicResourcePool.prelimCheckoutResource(BasicResourcePool.java:557)
- locked <0x32cf7538> (a com.mchange.v2.resourcepool.BasicResourcePool)
at com.mchange.v2.resourcepool.BasicResourcePool.checkoutResource(BasicResourcePool.java:477)
at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutPooledConnection(C3P0PooledConnectionPool.java:525)
多数の HTTP スレッドが通常どおり実行されていることも確認できます。
"http-8080-Processor47" daemon prio=1 tid=0x098d5d40 nid=0xe2a runnable [0x757fc000..0x757ff1b0]
通常どおり実行されている HTTP スレッドの数を数えます。
原因
データベース コネクション プールで構成されたコネクション数が、ピーク負荷時間中の受信リクエストの数を処理するには小さすぎます。
たとえば、診断/テストの実行後は、HTTP コネクションの大多数がデータベース コネクションの取得を待機します。上記の例のように、HTTP-スレッド 150 がデータベースへの接続を待機しています。これにより、Confluence では最大でおよそ 150 の同時処理を行う必要があることがわかります。
ほとんどすべての HTTP スレッドは、なんらかの作業を完了するためにデータベースへの接続を必要とします。しかしながら、DB への同時接続数が小さすぎる場合、このリソースがボトルネックになります。
上記の例では、通常は 30 個のスレッドが実行され、処理を行っています。30 はデータベース プールでのデータベース コネクションの既定数です。
また、多数のリソースを処理するスレッドがある場合、それによってインストレーションが強制的にガベージ コレクション モードに切り替えられます。JRE がこれを行った場合、すべてのアプリケーション スレッドが CPU から取り除かれます。Confluence でリクエストを完了する準備ができていないにもかかわらずユーザーからのリクエストが引き続き生成され、最終的にプールで利用可能なデータベース コネクションが枯渇します。
ソリューション
- データベース コネクション プールを最適化します。これにより、データベース プールでのコネクションの最大数を定義します。この数字は、負荷時間に使用される HTTP スレッドの数 (HTTP スレッドの設定については以降をご参照ください) よりも、少なくとも 10 回多いか、25 % 大きい必要があります (より高い値を採用します)。これは、アクティブな HTTP スレッドに加えて、バックグラウンドのジョブで使用されるコネクションを考慮に入れるためです (ピーク負荷時間中に外部でスレッド ダンプを取得し、使用されている HTTP スレッドを数えます)。
データベースへの直接 JDBC 接続をセットアップ済みの場合:
<confluence-home> ディレクトリでconfluence.cfg.xml
ファイルを確認します。次の行を見つけ、要件に合わせて更新します。<property name="hibernate.c3p0.max_size">60</property>
If you're running Confluence 7.14 or later, update both of these properties to the same value.
<property name="hibernate.c3p0.max_size">60</property> <property name="hibernate.hikari.maximumPoolSize">60</property>
conf/server.xml
でデータ ソースを使用している場合:
Confluence 5.8.x 以降を使用している場合 (Tomcat 8 が同梱):maxTotal
パラメータを構成します。また、maxWait
構成オプションの名前が Tomcat 8 では maxWaitMillis に変更されている点にご注意ください。例については「Apache Tomcat で MySQL データソースを構成する」をご参照ください。<Resource name="jdbc/confluence" auth="Container" type="javax.sql.DataSource" ... maxTotal="60" />
Confluence 5.7.x 以前を使用している場合 (Tomcat 7 以前が同梱):maxActive
パラメータを構成します (この属性の名前は Tomcat 8 でmaxTotal
に変更されています)。<Resource name="jdbc/confluence" auth="Container" type="javax.sql.DataSource" ... maxActive="60" />
- 定義された数がスレッド ダンプの取得中に実行されていた HTTP スレッドの数に近く、残りのスレッドはデータベース コネクションを待機していた場合、データベースへのコネクションの数が不十分であることがわかります。
- 利用可能な HTTP スレッドの数を制限し、利用可能なデータベース コネクションの数に近づけます。ボトルネックがある場合、HTTP コネクションの待機中に消費されるリソースの数が少ないため、DB コネクション プールよりも HTTP スレッド プールのほうが適しています。
この方法はご利用のアプリケーション サーバーの構成方法に応じて異なります。既定のコネクタを使用しているスタンドアロン構成の場合、
<conf-install>\conf\server.xml
で定義されている Connector のmaxThreads
属性を変更するか、それが存在しない場合は追加します。このパラメータが指定されていない場合、既定の 200 が使用されます。maxThreads="48"
- データベースのパフォーマンスを評価します。
- タイムアウトを確立します。詳細については「データベース クエリのタイムアウトを構成する」をご参照ください。
注意
Synchrony
共同編集機能に使われる Synchrony プロセスは独自のデータベース コネクション プールを持ち、最大で 15 個の DB コネクションを使います。プールのサイズを変更することはできませんが、Synchrony ではコネクションのリサイクルが非常に効率的に行われます。データベースでコネクションの数を構成する際にはこのプールを考慮するようにします。
データベース接続
データベースのコネクション数も構成する必要がある場合があります。SQL Server と Oracle は十分に大きい制限値を持つため、これは通常は PostgreSQL と MySQL に関連します。
MySQL
MySQL の既定の最大コネクション数は 151 です。構成されている最大値を次のように確認できます。
mysql -u confluence -h localhost -p -e "SHOW VARIABLES LIKE '%max_connections%';"
制限を増やす方法については MySQL のドキュメントをご確認ください。
PostgreSQL
PostgreSQL の最大コネクション数は 100 です。構成されている最大値を次のように確認できます。
psql -U postgres -c 'show max_connections;'
制限を増やす方法については PostgreSQL のドキュメントをご確認ください。
SQL Server
SQL Server ではデフォルトで 32767 個の同時接続が許可されます。調整が必要な場合は次のコミュニティ ディスカッションをご確認ください。