0Pricing
Java Academy · レッスン

HikariCP によるコネクションプール

接続を効率的に再利用します。

「HikariCP によるコネクションプール」はCoddyKit上の無料Java Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはJava Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Java Academyコースには全4レッスンが含まれています。

なぜ接続をプールするのか

データベース接続の確立にはコストがかかります。TCPハンドシェイク、認証、セッションのセットアップに数十ミリ秒かかることがあります。

コネクションプールは、確立済みの接続をいくつか用意しておきます。コードは接続を借りて使用し、返却します。これにより、高コストな接続確立が低コストな貸し出しに変わります。

HikariCPの紹介

HikariCPは、Javaでデファクトスタンダードとなっているプールです。小さく高速で、Spring Bootのデフォルトでもあります。

javax.sql.DataSourceを実装しているため、JDBCコードの他の部分はそのまま使えます。DriverManagerからではなく、プールから接続を取得するだけです。

プールの設定

HikariCPは HikariConfig オブジェクトを使って設定します。設定項目にはJDBC URL、認証情報、プールサイズなどがあります。

次に、そのオブジェクトから HikariDataSource を作成します。通常はアプリケーションの起動時に一度だけ作成し、共有します。

import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;

public class Main {
    public static void main(String[] args) {
        HikariConfig config = new HikariConfig();
        config.setJdbcUrl("jdbc:postgresql://localhost:5432/shop");
        config.setUsername("app");
        config.setPassword("secret");
        config.setMaximumPoolSize(10);
        HikariDataSource ds = new HikariDataSource(config);
        System.out.println("Pool ready, max size " + config.getMaximumPoolSize());
        ds.close();
    }
}

接続を借りる

ds.getConnection() を呼び出して接続を借ります。通常どおり、try-with-resourcesでラップしてください。

ここが重要なポイントです。プールされた接続を閉じても、物理的なソケットは閉じられません。接続がプールに戻され、再利用されます。

import com.zaxxer.hikari.HikariDataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.sql.DataSource;

public class Main {
    public static void main(String[] args) {
        DataSource ds = new HikariDataSource();
        try (Connection conn = ds.getConnection();
             PreparedStatement ps = conn.prepareStatement("SELECT count(*) FROM users");
             ResultSet rs = ps.executeQuery()) {
            if (rs.next()) System.out.println("Users: " + rs.getInt(1));
        } catch (SQLException e) {
            System.out.println(e.getMessage());
        }
    }
}

close()は返却を意味する

これは多くの開発者が混乱する点です。プールを使用している場合は、次のようになります。

  • conn.close() は接続をプールに返却します。
  • プールは実際のソケットを開いたままにして、次に借りる人が使えるようにします。

したがって、常に閉じるべきです。try-with-resourcesが正しい方法です。接続を破棄するのではなく、返却しているのです。

プールサイズ

大きければよいというわけではありません。大きすぎるプールは、同時実行される処理によってデータベースに過剰な負荷をかけます。

HikariCPの指針では、(core_count * 2) + effective_spindle_count 程度の小さなプールが、巨大なプールよりも優れていることがよくあります。maximumPoolSize は上限で、minimumIdle はいくつかの接続をすぐ使える状態に保ちます。

public class Main {
    public static void main(String[] args) {
        int cores = 4;
        int spindles = 1; // SSD-ish
        int recommended = (cores * 2) + spindles;
        System.out.println("Suggested max pool size: " + recommended);
    }
}

主なタイムアウト

HikariCPには、データベースが応答しなくなった場合にアプリケーションを保護するタイムアウトがあります。

  • connectionTimeout — 接続を借りる処理が失敗するまで待機する時間です(デフォルトは30秒)。
  • idleTimeout — アイドル状態の接続を維持する時間です。
  • maxLifetime — この経過時間に達した接続を廃棄します(データベース側のタイムアウトより短くしてください)。

接続の検証

ネットワークによって、接続が気付かないうちに切断されることがあります。HikariCPは接続を渡す前に検証できます。

最新のJDBCドライバーでは Connection.isValid(timeout) を使用し、HikariCPが自動的に呼び出します。また、isValid を持たない古いドライバーには connectionTestQuery を設定することもできます。

リーク検出

接続リークは、コードが接続を借りたまま閉じない場合に発生します。最終的にはプールが空になり、すべての貸し出し処理がタイムアウトします。

leakDetectionThreshold(例:20000ミリ秒)を設定すると、それより長く保持された接続について、HikariCPがスタックトレースをログに記録します。問題のあるコードをすぐに特定できます。

アプリケーションごとに1つのプール

HikariDataSource は一度だけ作成し、アプリケーションの存続期間全体で再利用してください。

リクエストごとに新しいプールを作成すると、プールの目的に反します。毎回起動コストを支払うことになるためです。プールを閉じるのは、ds.close() を使ってシャットダウン時だけにしてください。

プールの監視

HikariCPは実行時メトリクスを提供するため、プールの状態を監視できます。

  • アクティブ、アイドル、合計の接続数。
  • 現在、接続を待機中のスレッド数。

Micrometer、Dropwizard Metrics、JMXと統合できます。「awaiting」の件数が継続的に高い場合は、プールが小さすぎるか、接続が長時間保持されています。

クイックチェック

HikariCPで借りた接続に対して close() を呼び出すと、どうなりますか?

まとめ

HikariCPによって、接続を効率よく再利用できます。

  • 起動時に HikariDataSource を一度だけ設定します。
  • try-with-resources内で getConnection() を使って接続を借り、close() でプールに返却します。
  • maximumPoolSize は控えめに設定します。
  • connectionTimeout、maxLifetime、接続の検証を調整します。
  • leakDetectionThreshold を使って、返却されていない接続を検出します。

よくある質問

「HikariCP によるコネクションプール」レッスンは無料ですか?

はい。「HikariCP によるコネクションプール」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Java Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Java Academyコースには全4レッスンが含まれています。

「HikariCP によるコネクションプール」で何を学びますか?

接続を効率的に再利用します。 ブラウザで直接実行するハンズオンコードでJava Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Java Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのJava Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。

「HikariCP によるコネクションプール」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このJava Academyレッスンでコードを書いて実行できますか?

はい。すべてのJava Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. JDBC の基礎
  2. PreparedStatement
  3. トランザクション
  4. HikariCP によるコネクションプール
← Java Academyに戻る