0

ここでこのトピックに関する関連する質問を調べ、しばらくグーグルで検索しました。それでも、Tomcat の DBCP 構成またはメカニズムで重要なことを理解していないようです。

Tomcat 6、DBCP リソースが構成されていますserver.xml:

<Resource name="jdbc/myDB" auth="Container" description="Database connection"
  type="javax.sql.DataSource"
  driverClassName="com.mysql.jdbc.Driver"
  url="jdbc:mysql://myhost:3306/mydb?autoReconnectForPools=true&useUnicode=true"
  username="user"
  password="password"
  validationQuery="SELECT 1"
  testOnBorrow="true"
  testWhileIdle="true"
  timeBetweenEvictionRunsMillis="10000" minEvictableIdleTimeMillis="60000"
  maxActive="20" maxWait="20000" maxIdle="10"
  removeAbandoned="true" removeAbandonedTimeout="60" logAbandoned="true" />

また、mysqlを探しましwait_timeoutたが、デフォルトです28800

要約すると、いくつかのオプションを試しましたが、問題は、mysql 接続がアイドル状態で 28800 秒に達し、サーバーがそれらを閉じることです。プールは何とかこの状況をvalidationQueryandtestOnBorrowで処理するべきだと思っていましたが、間違っているようです。

アイドル期間後に使用するautoReconnectと、url最初のクエリの試行で " ...CommunicationsException: The last packet successfully received from the server was 157,493,261 milliseconds ago." が返されますが、その後は正常に動作します。

使用autoReconnectForPoolsしている場合、urlまたは使用していない場合 - アイドル期間 (8 時間) の後、毎回 " .MySQLNonTransientConnectionException: No operations allowed after connection closed" になります。

どちらの場合も、アプリに負荷がかかっている間はスムーズに進みます。したがって、接続はmysql側から閉じられたと結論付けました。

助けて、何を見逃したの?Mysql で wait_timeout を変更せずにこの問題を解決したいと思います。目標 - アイドル時間が発生した場合でも生き残る可能性のある安定したアプリ:)

4

2 に答える 2

0

それが役立つかどうかはわかりませんが、Tomcat 7.xには新しい(おそらくより良い)接続プールの実装があります-それを使用するには、これを構成に追加します:

factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"

残りのオプションはすべて同じだと確信しています。http://people.apache.org/~fhanik/jdbc-pool/jdbc-pool.htmlを参照してください

于 2013-01-24T12:02:02.737 に答える
0

Tomcat DBCP にはまったく問題はありませんでしたが、少し考えて、この質問はそのままにしておくことにしました。私の決定は、かなりの数の同様の質問を見つけたという事実に動機付けられており、それらの多くは未回答であり、何が起こっているのかについての手がかりを見つけることができませんでした. だから、突然同じ道を歩いている人への警告として、ここにメッセージを残します。

問題は、次のように、一度だけ初期化されたデータベースを使用するリソースがあることでした。

class MyClass {
   private MyResource res = null;

   private MyResource getMyResource() {
      if (res == null) res = new MyResource(getConnection());
      return res;
   }

   private Connection getConnection() {
      ....
      con = dataSource.getConnection();
      ....
      return con;
   }
}

私のアプリがサーブレットにあったとき、 MyResource のインスタンスが唯一のものであり、接続が開いていたという状況につながりました。そのため、MySQL サーバーが期限切れの接続を強制終了すると、最初のクエリでタイムアウトに関する例外が発生しますが、後続のクエリの autoReconnect により、接続が再び有効になります。プールは解放されていなかったため、接続に触れていませんでした。

最後に私はそれに気づき、次のように変更getMyResourceして修正しました:

private MyResource getMyResource() {
  return new MyResource(getConnection());
}

私の場合は妥当でした。この変更の後、すべてが期待どおりに機能し始めました。

于 2013-02-04T11:22:02.183 に答える