5

Hibernate を ORM ツールとして使用する API があり、c3p0 を接続プール ハンドラーとして使用します。負荷がかかっているときは問題ありません。ただし、API が 1 日ほど非アクティブになっていると、「接続を取得できません」という例外が発生します。そのため、週末に API を使用する人がいない場合、月曜日の朝に接続エラーが発生します。

原因: java.sql.SQLException: クライアントによる接続のチェックアウトの試行がタイムアウトしました。

データベースとしてmysqlを使用しています。私の調査では、mySQL が 8 時間ほど後に接続を無効にすることがわかりました。接続プールが失効した接続をクライアントに提供しているため、クライアントの接続タイムアウト例外が発生している可能性があります。

現在、C3Po で構成されている接続テストはありません。IdleTestPeriod を使用して、プールによってクライアントに接続が提供される前に接続をテストするとします。次に、ある時点ですべての接続がテストに失敗した場合はどうなりますか? これらの失敗した接続はプールから削除され、新しいアクティブな接続が再び生成されますか?

現在、これは使用している c3p0 設定です。この問題の他の理由はありますか?

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
        <property name="driverClass" value="${----}"/>
        <property name="jdbcUrl" value="${----}"/>
        <property name="user" value="${----}"/>
        <property name="password" value="${------}"/>
        <property name="minPoolSize" value="5"/>
        <property name="acquireIncrement" value="5" />
        <property name="maxPoolSize" value="125" />
        <property name="maxStatements" value="10" />
        <property name="maxIdleTime" value="180" />
        <property name="maxIdleTimeExcessConnections" value="30" />
        <property name="checkoutTimeout" value="3000" />
        <property name="preferredTestQuery" value="SELECT 1" />
    </bean>
4

2 に答える 2

12

したがって、3秒(3000ミリ秒)のcheckoutTimeoutが設定されています。それはあなたが見ている例外です。クライアントは、プールから接続をチェックアウトするために3秒間だけ待機できます。3秒では不十分な場合は、例外が表示されます。

問題は、なぜクライアントが接続を取得するのにそれほど時間がかかるのかということです。通常、接続のチェックアウトは非常に高速な操作です。ただし、すべての接続がチェックアウトされている場合、クライアントはデータベースからの(低速の)接続取得を待機する必要があります。

かなり積極的に接続をカリングするようにプールを構成しました。minPoolSize = 5を超える接続は、maxIdleTimeExcessConnections = 30秒を超えてアイドル状態になると、破棄されます。ただし、プールは大規模バースト用に構成されています:maxPoolSize=125。アプリがしばらく静かになり、その後クライアントから接続要求のバーストを取得するとします。プールはすぐに接続を使い果たし、acquireIncrement=5のバーストで取得を開始します。ただし、突然25のクライアントがあり、プールに5つの接続しかない場合、接続を取得する前に25番目のクライアントがタイムアウトになる可能性はありません。

できることはたくさんあります。これらの微調整は分離可能であり、必要に応じて組み合わせることができます。

  1. アイドル状態の「過剰な」接続をそれほど積極的にカリングしないため、一般に、プールにはリクエストのバーストを処理するためのある程度の容量があります。maxIdleTimeExcessConnectionsを完全に削除し、maxIdleTime=180秒の使用停止後にConnectionsをゆっくりと枯渇させる可能性があります。(欠点?非アクティブな期間中は、リソースのフットプリントが大きくなり、長くなります。)

  2. minPoolSizeをより高い値に設定して、接続が少なすぎるアクティビティのバーストがプールに表示される可能性が低くなるようにします。(欠点?永続的なリソースのフットプリントが大きくなります。)

  3. 構成からcheckoutTimeoutを削除します。c3p0のデフォルトでは、クライアントは接続を無期限に待機できます。(欠点?成功の可能性を待つのではなく、クライアントが失敗をすばやく報告することを好むかもしれません。)

あなたが観察している問題は、接続テストやMySQLタイムアウト自体とはあまり関係がないと思いますが、それはあなたがそれらの問題に対処すべきではないという意味ではありません。MySQLの再接続の問題に関するnobehのアドバイスに従います。(私はMySQLの大規模なユーザーではありません。)接続テストの実装を検討する必要があります。あなたはpreferredTestQueryを持っているので、テストはかなり速いはずです。私の通常の選択は、testConnectionOnCheckinとidleConnectionTestPeriodを使用することです。http://www.mchange.com/projects/c3p0/#configuring_connection_testingを参照してください

幸運を!

于 2012-07-31T18:04:19.183 に答える
1

MySQL Java Connectorの高可用性とクラスタリングのセクションで、プロパティを見てください。具体的には JDBC 接続 URL でプロパティを使用します。以前、MySQL、Hibernate、および C3P0 を使用していたとき、彼らは私を助けてくれました。これが役立つことを願っています。autoReconnectautoReconnetForPools

于 2012-07-31T16:22:03.217 に答える