web-dev-qa-db-ja.com

HikariCPの接続が多すぎる

Javaサーブレットがあり、jdbc(データベース:mysql)と共に接続プールを使用したい。

だからここに私がやっていることがあります:

(このクラスはパブリック最終クラスDBConnectorです)

private static final HikariDataSource dataSource = new HikariDataSource();
private static final HikariDataSource dataSource2 = new HikariDataSource();
private static final HikariDataSource dataSource3 = new HikariDataSource();

static {
    dataSource.setDriverClassName("com.mysql.jdbc.Driver");
    dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/contentdb");
    dataSource.setUsername("root2");
    dataSource.setPassword("password");
    dataSource.setMaximumPoolSize(400);
    dataSource.setMinimumIdle(5);
    dataSource.setLeakDetectionThreshold(15000);
    dataSource.setConnectionTestQuery("SELECT 1");
    dataSource.setConnectionTimeout(1000);

    dataSource2.setDriverClassName("com.mysql.jdbc.Driver");
    dataSource2.setJdbcUrl("jdbc:mysql://localhost:3306/userdb");
    dataSource2.setUsername("root");
    dataSource2.setPassword("password");
    dataSource2.setMaximumPoolSize(300);
    dataSource2.setMinimumIdle(5);
    dataSource2.setLeakDetectionThreshold(15000);
    dataSource2.setConnectionTestQuery("SELECT 1");
    dataSource2.setConnectionTimeout(1000);

    dataSource3.setDriverClassName("com.mysql.jdbc.Driver");
    dataSource3.setJdbcUrl("jdbc:mysql://localhost:3306/analysedb");
    dataSource3.setUsername("root2");
    dataSource3.setPassword("password");
    dataSource3.setMaximumPoolSize(200);
    dataSource3.setMinimumIdle(5);
    dataSource3.setLeakDetectionThreshold(15000);
    dataSource3.setConnectionTestQuery("SELECT 1");
    dataSource3.setConnectionTimeout(1000);

}

private DBConnector() {
    //
}

public static Connection getConnection(int dataBase) throws SQLException {
    if (dataBase == 0) {
        return dataSource.getConnection();
    } else if (dataBase == 1) {
        return dataSource2.getConnection();
    } else {
        return dataSource3.getConnection();
    }
}

そして、私がそれを呼びたいとき:

Connection con = null;
    PreparedStatement query = null;
    ResultSet result = null;
    try {
        con = DBConnector.getConnection(0);
    }catch(SQLException ex){
    }finally{
       if (result != null) {
            try {
                result.close();
            } catch (SQLException logOrIgnore) {
            }
        }
        if (query != null) {
            try {
                query.close();
            } catch (SQLException logOrIgnore) {
            }
        }
        if (con != null) {
            try {
                con.close();
            } catch (SQLException logOrIgnore) {
            }
        }
    }

しかし、アプリをクリックすると、しばらくするとハングし始め、次のエラーが発生します。

Java.sql.SQLException: Timeout after 1001ms of waiting for a connection.
at com.zaxxer.hikari.pool.HikariPool.getConnection(HikariPool.Java:208)
at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.Java:108)
at main.Java.db.DBConnector.getConnection(DBConnector.Java:60)
at main.Java.ressources.SingleItemData.getVotes(SingleItemData.Java:1088)
at main.Java.item.methods.GET.content.GetStreamContent.getStreamContent(GetStreamContent.Java:126)
at main.Java.RestService.doGet(RestService.Java:254)
at javax.servlet.http.HttpServlet.service(HttpServlet.Java:621)
at javax.servlet.http.HttpServlet.service(HttpServlet.Java:728)
at org.Apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.Java:305)
at org.Apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.Java:210)
at org.Apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.Java:222)
at org.Apache.catalina.core.StandardContextValve.invoke(StandardContextValve.Java:123)
at org.Apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.Java:502)
at org.Apache.catalina.core.StandardHostValve.invoke(StandardHostValve.Java:171)
at org.Apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.Java:99)
at org.Apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.Java:953)
at org.Apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.Java:118)
at org.Apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.Java:408)
at org.Apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.Java:1023)
at org.Apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.Java:589)
at org.Apache.Tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.Java:312)
at Java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.Java:1145)
at Java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.Java:615)
at Java.lang.Thread.run(Thread.Java:724)

原因:com.mysql.jdbc.exceptions.jdbc4.CommunicationsException:通信リンク障害

Mysql max_conncetionsを1000に設定しました。「SHOW PROCESSLIST」クエリは、多くのスリーププロセスを表示します。これらはアイドルですか?

私は本当にここで立ち往生しています。問題を引き起こしている設定がわからない。だから私の質問は-このエラーの原因は何ですか?何が悪いのですか?助けてくれてありがとう。

編集:Mysql(localhost)のセットアップ:

[mysqld]

user=mysql

port=3306

socket      =/Applications/XAMPP/xamppfiles/var/mysql/mysql.sock

key_buffer=16M

max_allowed_packet=1M

table_open_cache=64

sort_buffer_size=512K

net_buffer_length=8K

read_buffer_size=256K

read_rnd_buffer_size=512K

myisam_sort_buffer_size=8M

max_connections = 1000

wait_timeout = 28800

interactive_timeout = 28800

HikariCP:HikariCP-Java6-2.2.5.jar

MySQLコネクタ:mysql-connector-Java-5.1.25-bin.jar

11
Fabian Lurz

いくつかのこと。まず、HikariCP、Java、MySQLドライバーのバージョンは何ですか?

次に、1つのプールで400接続ですか? 多すぎる! 各プールで10〜20から始めます。 1秒あたり数千のトランザクションを処理できることに驚かれることでしょう。

第三に、これは2番目の質問 FAQ内 です。答えとリンクを読んでください。 maxLifetimeをMySQLネイティブタイムアウトよりも短い(1分だけ)に設定する必要があります。

最後に、DEBUGロギングをオンにします。HikariCPにはノイズがありません。 30秒ごとに、ハウスキーピングスレッドが実行され、プール統計がログに記録されます。

21
brettw