The English version of quarkus.io is the official project site. Translated sites are community supported on a best-effort basis.

Cassandra クライアントの使用

Apache Cassandra®は、フリーでオープンソースの分散型ワイドカラムストアのNoSQLデータベース管理システムで、多くのコモディティサーバーにまたがる大量のデータを処理するように設計されており、単一障害点のない高可用性を提供します。

このガイドでは、RESTサービスでCassandraデータベースを使用する方法を見ていきます。

このエクステンションはサードパーティによって開発されたもので、Quarkus Platformの一部です。

前提条件

このガイドを完成させるには、以下が必要です:

  • 約15分

  • IDE

  • JDK 17+がインストールされ、 JAVA_HOME が適切に設定されていること

  • Apache Maven 3.9.6

  • 使用したい場合は、 Quarkus CLI

  • ネイティブ実行可能ファイルをビルドしたい場合、MandrelまたはGraalVM(あるいはネイティブなコンテナビルドを使用する場合はDocker)をインストールし、 適切に設定していること

  • 稼働中の Apache CassandraDataStax Enterprise(DSE)、または DataStax Astraデータベース、あるいはきれいなDockerのインストール

アーキテクチャ

このクイックスタート・ガイドでは、 DataStax Javaドライバーを使用してApache Cassandra、DataStax Enterprise(DSE)、またはDataStax Astraデータベースに接続できる Cassandra Quarkusエクステンションを使用してRESTアプリケーションを構築する方法を説明します。

このガイドでは、DataStax Object Mapper も使用します。これは、Java から CQL にマッピングする強力なフレームワークで、CQLクエリーを手動で記述する手間を省くことで、アプリケーションのデータアクセス階層コードを大幅に簡素化します。

このガイドで構築されたアプリケーションは非常にシンプルです: ユーザーはフォームを使用してリストに要素を追加することができ、アイテムリストが更新されます。ブラウザーとサーバー間の情報はすべてJSONフォーマットで、各要素はCassandraデータベースに保存されます。

ソリューション

次の章で紹介する手順に沿って、ステップを踏んでアプリを作成することをお勧めします。ただし、完成した例にそのまま進んでも構いません。

ソリューションはCassandra QuarkusエクステンションGitHubレポジトリの quickstart directory にあります。

空白の Maven プロジェクトの作成

まず、新しいMavenプロジェクトを作成し、 quickstart ディレクトリーに存在する pom.xml ファイルをコピーします。

pom.xml 、必要なQuarkusのエクステンションや依存関係をすべてインポートしています。

データモデルとデータアクセスオブジェクトの作成

この例では、果物のリストを管理するアプリケーションを作成します。

まず、以下のように Fruit クラスであらわされるデータモデルを作成してみましょう。

@Entity
@PropertyStrategy(mutable = false)
public class Fruit {

    @PartitionKey
    private final String name;

    private final String description;

    public Fruit(String name, String description) {
      this.name = name;
      this.description = description;
    }
  // getters, hashCode, equals, toString methods omitted for brevity
}

前述のとおり、ここではDataStax Object Mapperを使用しています。つまり、CQLクエリーを手動で記述するのではなく、データ・モデルにいくつかのアノテーションを付け、裏側でマッパーが適切なCQLクエリーを生成するのです。

これが、 Fruit クラスが @Entity でアノテーションされている理由です。このアノテーションは、Cassandraテーブルにマッピングされる _エンティティ・クラス_としてマークされます。このクラスのインスタンスは、Cassandraデータベースに自動的に永続化され、そこから取得されます。ここでは、テーブル名はクラス名から推測されます: fruit

また、name フィールドは Cassandra パーティションキーを表すため、ObjectMapper ライブラリーの別のアノテーションである @PartitionKey のアノテーションを付けています。

エンティティークラスには通常、今回のように @PropertyStrategy(mutable = false) のアノテーションが付けられている場合を除き、デフォルトの引数なしのコンストラクタが必要です。

次のステップでは、 Fruit エンティティーのインスタンスを管理する DAO (データアクセスオブジェクト) インターフェイスを作成します。

@Dao
public interface FruitDao {
  @Update
  void update(Fruit fruit);

  @Select
  PagingIterable<Fruit> findAll();
}

このインターフェイスは、REST サービスで使用される操作を公開します。繰り返しになりますが、アノテーション @Dao は DataStaxObjectMapper から取得され、このインターフェイスの実装も自動的に生成されます。

findAll メソッドの特別なリターンタイプにも注意してください PagingIterable: これはドライバーによって返される結果セットの基本タイプです。

最後に、 Mapper インタフェースを作成しましょう:

@Mapper
public interface FruitMapper {
  @DaoFactory
  FruitDao fruitDao();
}

@Mapper アノテーションは、DataStax Object Mapperが認識する別のアノテーションです。マッパーはDAOインスタンスの構築を担当します。この場合、outマッパーは唯一のDAOである FruitDao のインスタンスを構築します。

マッパー・インターフェースをDAO Beanのファクトリーと考えてください。もし、あなた自身のコードで特定のDAO Beanを構築し注入するつもりなら、まず、 @Mapper インタフェースでそのための @DaoFactory メソッドを追加する必要があります。

@DaoFactory メソッド名は関係ありません。

@DaoFactory メソッドは、以下の型のBeanを返す必要があります:

  • @Dao アノテーションの付与されたインタフェース。例: FruitDao;

  • @Dao -アノテーションの付与されたインターフェースの CompletionStage (例: CompletionStage<FruitDao> )。

  • @Dao アノテーションの付与されたインタフェースの Uni 。例: Uni<FruitDao>

Uni は、Quarkusが使用しているリアクティブプログラミングライブラリであるMutinyライブラリの型です。これについては、後述の「リアクティブプログラミング」のセクションで詳しく説明します。

DAOとマッパーの実装の生成

もうお分かりだと思いますが、私たちは上記のインターフェイスを実装しません。代わりに、Object Mapperがそのような実装を生成してくれるのです。

Object Mapperは、2つのパーツから構成されています:

  1. @Mapper@Dao または @Entity でアノテーションされたクラスについてクラスパスをスキャンし、それらのためのコードとCQLクエリを生成する(コンパイル時)アノテーション・プロセッサー、および

  2. 生成されたクエリーを実行するためのロジックを含む実行時モジュール。

そのため、Object Mapperを有効にするには、2つのステップが必要です:

  1. cassandra-quarkus-mapper-processor アノテーション・プロセッサーを宣言します。Mavenでは、プロジェクトの pom.xml ファイルのコンパイラ・プラグイン設定を以下のように変更することで実現出来ます:

<plugin>
  <artifactId>maven-compiler-plugin</artifactId>
  <version>3.10.1</version>
  <configuration>
    <source>${java.version}</source>
    <target>${java.version}</target>
    <annotationProcessorPaths>
      <path>
        <groupId>com.datastax.oss.quarkus</groupId>
        <artifactId>cassandra-quarkus-mapper-processor</artifactId>
        <version>${cassandra-quarkus.version}</version>
      </path>
    </annotationProcessorPaths>
  </configuration>
</plugin>

Gradleでは、 build.gradle ファイルに以下の行を追加することで実現します:

annotationProcessor "com.datastax.oss.quarkus:cassandra-quarkus-mapper-processor:${cassandra-quarkus.version}"
正しいアノテーション・プロセッサーを有効にしていることを確認してください!Cassandraドライバには、 java-driver-mapper-processor というObject Mapperアノテーション・プロセッサーが付属しています。しかし、Cassandra Quarkusエクステンションには、独自のアノテーション・プロセッサーも同梱されています: `cassandra-quarkus-mapper-processor `これは、ドライバーのものよりも多くの機能を備えています。このアノテーション・プロセッサーはQuarkusアプリケーションで使用するのに適した唯一のものなので、これが使用されているものであることを確認してください。また、両方のアノテーションプロセッサを一緒に使用しないでください。
  1. プロジェクトの pom.xml ファイルのコンパイルスコープで java-driver-mapper-runtime の依存関係を以下のように宣言します:

<dependency>
  <groupId>com.datastax.oss</groupId>
  <artifactId>java-driver-mapper-runtime</artifactId>
</dependency>
このモジュールは "ランタイム "と呼ばれていますが、コンパイルスコープで宣言する必要があります。

プロジェクトが正しくセットアップされていれば、エラーなくコンパイルできるはずです。また、生成されたコードが target/generated-sources/annotations ディレクトリに存在する筈です(Maven を使用している場合)。生成されたコードは、ほとんどがデータベースとやりとりするための内部処理なので、慣れる必要はないでしょう。

serviceとJSON RESTエンドポイントの作成

ここで、アプリケーションのビジネス層となる FruitService を作成し、Cassandraデータベースから果物をセーブ/ロードします。

@ApplicationScoped
public class FruitService {

  @Inject FruitDao dao;

  public void save(Fruit fruit) {
    dao.update(fruit);
  }

  public List<Fruit> getAll() {
    return dao.findAll().all();
  }
}

サービスが FruitDao インスタンスを注入されていることに注意してください。このDAOインスタンスは、生成された実装のおかげで、自動的に注入されます。

Cassandra Quarkus エクステンションを使用すると、次の Bean のいずれかを独自のコンポーネントに挿入できます。

  • プロジェクト内にある @Mapper アノテーション付きインターフェイスすべて。

  • @Mapper アノテーション付きインタフェースの CompletionStage または Uni を注入することもできます。

  • @DaoFactory メソッドから返されるBean(とりうるBean型は上記を参照)。

  • QuarkusCqlSession bean: このアプリケーションスコープのシングルトン Bean は、Cassandra クライアントへの主要なエントリーポイントです。これは、Quarkus 用に特別に調整されたメソッドを備えた特殊な Cassandra ドライバーセッションインスタンスです。javadoc をしっかり確認してください。

  • CompletionStage<QuarkusCqlSession> または Uni<QuarkusCqlSession> を注入することもできます。

この例では、 FruitMapperFruitDao の両方をどこにでも注入できますが、 FruitServiceFruitDao を注入しています。

最後に必要なのは、GETとPOSTのメソッドを公開するREST APIです。

@Path("/fruits")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class FruitResource {

  @Inject FruitService fruitService;

  @GET
  public List<FruitDto> getAll() {
    return fruitService.getAll().stream().map(this::convertToDto).collect(Collectors.toList());
  }

  @POST
  public void add(FruitDto fruit) {
    fruitService.save(convertFromDto(fruit));
  }

  private FruitDto convertToDto(Fruit fruit) {
    return new FruitDto(fruit.getName(), fruit.getDescription());
  }

  private Fruit convertFromDto(FruitDto fruitDto) {
    return new Fruit(fruitDto.getName(), fruitDto.getDescription());
  }
}

FruitResourceFruitService インスタンスを自動的に注入していることに注目してください。

通常、REST API とデータアクセス層の間で同じエンティティーオブジェクトを使用することはお勧めしません。各 API を互いに独立して進化させるには、これらのレイヤーを実際に分離し、個別の API を使用する必要があります。このように、異なるオブジェクトを ( FruitDto ) を使用する理由です。DTO という用語は、「Data Transfer Object」の略です。この DTO オブジェクトは、HTTP メッセージで JSON に対する変換を自動的に行います。

public class FruitDto {

  private String name;
  private String description;

  public FruitDto() {}

  public FruitDto(String name, String description) {
    this.name = name;
    this.description = description;
  }
  // getters and setters omitted for brevity
}

JSONへの変換とJSONからの変換は、Quarkus REST(旧RESTEasy Reactive)エクステンションによって自動的に行われます。 このエクステンションは、このガイドのpom.xmlファイルに含まれています。 アプリケーションに手動で追加する場合は、以下のスニペットをアプリケーションの ppm.xml ファイルに追加します:

<dependency>
  <groupId>io.quarkus</groupId>
  <artifactId>quarkus-rest</artifactId>
</dependency>
<dependency>
  <groupId>io.quarkus</groupId>
  <artifactId>quarkus-rest-jackson</artifactId>
</dependency>
JSONのシリアライゼーションレイヤーで使用されるDTOクラスは、デフォルトの引数なしのコンストラクタが必要です。

DTO から JSON への変換は自動的に処理されますが、それでも Fruit から FruitDto に、またはその逆に変換する必要があります。これは手動で行う必要があるので、 FruitResource で 2 つの変換メソッド convertToDtoconvertFromDto を宣言しています。

この例では、 FruitFruitDto は非常に似ているので、すべてに Fruit を使用しないのはなぜかと思うかもしれませんが、実際には、DTO とエンティティーの構造が大きく異なることは珍しくありません。

Cassandra データベースへの接続

ApacheCassandra または DataStaxEnterprise (DSE) への接続

構成する主なプロパティーは次のとおりです。Cassandraデータベースにアクセスするための contact-points 、ドライバーによって必要とされる local-datacenter そしてオプションでバインド先のキースペースです。

設定のサンプルは以下のようになります。

quarkus.cassandra.contact-points={cassandra_ip}:9042
quarkus.cassandra.local-datacenter={dc_name}
quarkus.cassandra.keyspace={keyspace}

この例では、localhost上で動作する単一のインスタンスを使用しており、データを含むキースペースは k1 となっています。

quarkus.cassandra.contact-points=127.0.0.1:9042
quarkus.cassandra.local-datacenter=datacenter1
quarkus.cassandra.keyspace=k1

クラスタがプレーンテキスト認証を必要とする場合は、さらに2つの設定を行う必要があります。 usernamepassword です。

quarkus.cassandra.auth.username=john
quarkus.cassandra.auth.password=s3cr3t

DataStaxAstra クラウドデータベースへの接続

DataStax Astra に接続する場合には、接続先とデータセンターを提供する代わりに、いわゆる セキュア接続バンドル を提供して、Astra のセキュア接続バンドルファイルへの有効なパスを指定する必要があります。セキュア接続バンドルは、AstraWeb コンソールからダウンロードできます。

Astra クラスターでは常に認証が必要なため、ユーザー名とパスワードも指定する必要があります。

DataStax Astraのサンプル構成は次のようになります。

quarkus.cassandra.cloud.secure-connect-bundle=/path/to/secure-connect-bundle.zip
quarkus.cassandra.auth.username=john
quarkus.cassandra.auth.password=s3cr3t
quarkus.cassandra.keyspace=k1

高度なドライバー設定

application.conf または application.json ファイルを使用して、他の Java ドライバーの設定を設定することができます。これらのファイルは、アプリケーションのクラスパスに配置する必要があります。すべての設定は、基礎となるドライバー設定メカニズムに自動的に渡されます。 application.propertiesquarkus.cassandra のプレフィックスを付けて定義された設定は、 application.conf または application.json で定義された設定よりも優先されます。

設定の全リストを見るには、 ドライバーの設定リファレンス を参照してください。

ローカル Cassandra データベースの実行

デフォルトでは、Cassandra クライアントは、ポート 9042(デフォルトの Cassandra ポート)でローカル Cassandra データベースにアクセスするように構成されています。

設定 quarkus.cassandra.local-datacenter が、Cassandraクラスターのデータセンターと一致していることを確認してください。
ローカルのデータセンターの名前がわからない場合は、以下の CQL クエリを実行することでこの値を見つけることができます : SELECT data_center FROM system.local

Docker を使用して Cassandra データベースを実行する場合は、次のコマンドを使用してバックグラウンドでデータベースを起動できます。

docker run --name local-cassandra-instance -p 9042:9042 -d cassandra

次に、アプリケーションで使用するキースペースとテーブルを作成する必要があります。Dockerを使用している場合は、以下のコマンドを実行します。

docker exec -it local-cassandra-instance cqlsh -e "CREATE KEYSPACE IF NOT EXISTS k1 WITH replication = {'class':'SimpleStrategy', 'replication_factor':1}"
docker exec -it local-cassandra-instance cqlsh -e "CREATE TABLE IF NOT EXISTS k1.fruit(name text PRIMARY KEY, description text)"

CQLSH ユーティリティーを使用して、データベースに対話式に問い合わせることもできます。

docker exec -it local-cassandra-instance cqlsh

REST API のテスト

プロジェクトのルートディレクトリー:

  • mvn clean package を実行してから、 java -jar./target/cassandra-quarkus-quickstart-*-runner.jar を実行してアプリケーションを起動します。

  • または、mvn clean quarkus:dev でアプリケーションを開発モードで実行します。

これで、curl コマンドを使用して、基盤となる REST API と対話できます。

fruit を作成するには以下を実行します。

curl --header "Content-Type: application/json" \
  --request POST \
  --data '{"name":"apple","description":"red and tasty"}' \
  http://localhost:8080/fruits

Fruit を回収するには以下を実行します。

curl -X GET http://localhost:8080/fruits

フロントエンドの作成

それでは、 FruitResource と対話するためのシンプルなウェブページを追加してみましょう。

Quarkus は、 META-INF/resources ディレクトリーの下にある静的リソースを自動的に提供します。 src/main/resources/META-INF/resources ディレクトリーに、このファイル の内容を含めて fruits.html ファイルを追加します。

これで、REST サービスと対話できるようになりました。

  • まだの場合は、 mvn clean quarkus:dev を使用してアプリケーションを起動します。

  • ブラウザーで http://localhost:8080/fruits.html を指定します。

  • フォームを使って新しいフルーツをリストに追加します。

Cassandra クライアントを使用したリアクティブプログラミング

QuarkusCqlSession インタフェース を使用すると、Quarkus およびそのリアクティブフレームワークである Mutiny をシームレスに統合する一連のリアクティブメソッドにアクセスできます。

Mutinyに慣れていない方は、 Mutiny - 直感的なリアクティブプログラミングライブラリをご覧ください。

Mutiny でリアクティブプログラミングを使用してアプリケーションを書き換えてみましょう。

まず、リアクティブな方法で機能する別の DAO インターフェイスを宣言しましょう:

@Dao
public interface ReactiveFruitDao {

  @Update
  Uni<Void> updateAsync(Fruit fruit);

  @Select
  MutinyMappedReactiveResultSet<Fruit> findAll();
}

MutinyMappedReactiveResultSet の使い方に注意してください。これは、ドライバが返すオリジナルの Publisher から変換された特殊な Mutiny 型で、クエリの実行情報を取得するなど、いくつかの追加メソッドも公開されています。このインターフェイスで何も必要としない場合は、単純に Multi を返すようにメソッドを宣言することもできます: Multi<Fruit> findAll()

同様に、メソッド updateAsyncUni を返します。これは、ドライバーが返す元の結果セットから自動的に変換されます。

Cassandraドライバは、リアクティブコールにReactive Streamsの Publisher APIを使用しています。しかし、QuarkusフレームワークではMutinyを使用しています。そのため、 CqlQuarkusSession インターフェイスは、ドライバが返す Publisher インスタンスを透過的にリアクティブ型の Multi に変換します。 CqlQuarkusSessionPublisherUni に変換することもできます - この場合、パブリッシャーは最大で1行を出力し、その後完了することが期待されます。これは書き込みクエリ(行を返さない)や、最大で1行を返すことが 保証されている読み込みクエリ(例えばカウントクエリ)に適しています。

次に、 FruitMapper を適応させて、 ReactiveFruitDao インスタンスを構築する必要があります。

@Mapper
public interface FruitMapper {
  // the existing method omitted

  @DaoFactory
  ReactiveFruitDao reactiveFruitDao();
}

これで、リアクティブ DAO を活用する ReactiveFruitService を作成できます。

@ApplicationScoped
public class ReactiveFruitService {

  @Inject ReactiveFruitDao fruitDao;

  public Uni<Void> add(Fruit fruit) {
    return fruitDao.update(fruit);
  }

  public Multi<Fruit> getAll() {
    return fruitDao.findAll();
  }
}

最後に、 ReactiveFruitResource を作成できます。

@Path("/reactive-fruits")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class ReactiveFruitResource {

  @Inject ReactiveFruitService service;

  @GET
  public Multi<FruitDto> getAll() {
    return service.getAll().map(this::convertToDto);
  }

  @POST
  public Uni<Void> add(FruitDto fruitDto) {
    return service.add(convertFromDto(fruitDto));
  }

  private FruitDto convertToDto(Fruit fruit) {
    return new FruitDto(fruit.getName(), fruit.getDescription());
  }

  private Fruit convertFromDto(FruitDto fruitDto) {
    return new Fruit(fruitDto.getName(), fruitDto.getDescription());
  }
}

上記のリソースは、新しいエンドポイント reactive-fruits を公開しています。その機能は、以前に FruitResource で作成したものと同じですが、すべてがブロッキング操作なしでリアクティブな方法で処理されます。

上記の getAll () メソッドは Multi を返し、 add () メソッドは Uni を返します。これらのタイプは、以前使用した Mutiny タイプと同じで、Quarkus リアクティブ REST API により自動的に認識されるので、JSON に変換する必要はありません。

Quarkus REST natively supports the Mutiny reactive types e.g. Uni and Multi.

この依存関係は、本書の pom.xml にすでに含まれていますが、新しいプロジェクトを最初から開始する場合は必ず追加するようにしてください。

リアクティブ REST API のテスト

上で説明したようにアプリケーションを開発モードで実行すると、curl コマンドを使用して基盤となる REST API と対話できます。

リアクティブ REST エンドポイントを使用して fruit を作成するには以下を実行します。

curl --header "Content-Type: application/json" \
  --request POST \
  --data '{"name":"banana","description":"yellow and sweet"}' \
  http://localhost:8080/reactive-fruits

リアクティブ REST エンドポイントを使用して fruit を取得するには以下を実行します。

curl -X GET http://localhost:8080/reactive-fruits

リアクティブなフロントエンドの作成

次に、 ReactiveFruitResource と対話するための簡単な Web ページを追加しましょう。 src/main/resources/META-INF/resources ディレクトリーに、 このファイル の内容を含めて reactive-fruits.html ファイルを追加します。

これで、リアクティブな REST サービスと対話できるようになりました。

  • まだの場合は、 mvn clean quarkus:dev を使用してアプリケーションを起動します。

  • ブラウザーで http://localhost:8080/reactive-fruits.html を指定します。

  • フォームを使って新しいフルーツをリストに追加します。

ヘルスチェック

Quarkus SmallRye Health エクステンションを使用している場合には、Cassandra クライアントは、Cassandra クラスターへの接続を検証するための準備ヘルスチェックを自動的に追加します。このエクステンションは、本書の pom.xml にすでに含まれていますが、アプリケーションに手動で含める必要がある場合は、次を追加してください。

<dependency>
  <groupId>io.quarkus</groupId>
  <artifactId>quarkus-smallrye-health</artifactId>
</dependency>

ヘルスチェックが利用可能になると、アプリケーションの /health/ready エンドポイントにアクセスして、接続検証ステータスに関する情報を取得できます。

mvn clean quarkus:dev を使用して開発モードで実行している場合には、ブラウザーで http://localhost:8080/health/ready を指定すると、次のような出力が表示されます。

{
    "status": "UP",
    "checks": [
        {
            "name": "DataStax Apache Cassandra Driver health check",
            "status": "UP",
            "data": {
                "cqlVersion": "3.4.4",
                "releaseVersion": "3.11.7",
                "clusterName": "Test Cluster",
                "datacenter": "datacenter1",
                "numberOfNodes": 1
            }
        }
    ]
}
アプリケーションでヘルスチェックをグローバルに有効にする必要があるが、Cassandra ヘルスチェックは有効にしない場合は、 application.propertiesquarkus.cassandra.health.enabled プロパティーを false に設定して Cassandra ヘルスチェックを無効にできます。

メトリクス

Cassandra Quarkus クライアントは、Cassandra セッションおよび個々の Cassandra ノードに関するメトリクスを提供できます。このクライアントは、Micrometer と MicroProfile の両方をサポートします。

メトリクスの有効化の最初のステップは、使用する予定のメトリクスフレームワークに応じて、いくつかの依存関係を追加することです。

Micrometer でのメトリクスの有効化

Micrometer は、Quarkus アプリケーションで推奨されるメトリクスフレームワークです。

アプリケーションで Micrometer メトリクスを有効にするには、pom.xml に以下を追加する必要があります。

<dependency>
  <groupId>com.datastax.oss</groupId>
  <artifactId>java-driver-metrics-micrometer</artifactId>
</dependency>
<dependency>
  <groupId>io.quarkus</groupId>
  <artifactId>quarkus-micrometer-registry-prometheus</artifactId>
</dependency>

このガイドでは Micrometer を使用しているため、上記の依存関係はこのガイドの pom.xml にすでに含まれています。

MicroProfile メトリクスを使用したメトリクスの有効化

pom.xml から Micrometer への依存関係を削除し、代わりに次の依存関係を追加します。

<dependency>
  <groupId>com.datastax.oss</groupId>
  <artifactId>java-driver-metrics-microprofile</artifactId>
</dependency>
<dependency>
  <groupId>io.quarkus</groupId>
  <artifactId>quarkus-smallrye-metrics</artifactId>
</dependency>

Cassandra メトリクスの有効化

アプリケーションでメトリクスが有効になっている場合でも、この機能をオプトインしない限り、Cassandra クライアントはメトリクスを報告しません。そのため、次のステップとして、 application.properties ファイルで Cassandra メトリクスを有効化してください。

quarkus.cassandra.metrics.enabled=true

以上です!

最後の手順 (任意) で、Cassandra クライアントに追跡させる特定の Cassandra メトリクスをカスタマイズします。複数のメトリクスを追跡できますが、この手順をスキップすると、有用なメトリクスのデフォルトセットが自動的に追跡されます。

使用可能なメトリクス名の完全なリストについては、 Driver Setting Reference ページを参照してください。このページで advanced.metrics セクションを検索してください。また、Cassandra ドライバーのメトリクスについては、 ドライバーマニュアル で詳しく説明されています。

追跡するメトリクスをカスタマイズする場合は、次のプロパティーを使用する必要があります。

  • quarkus.cassandra.metrics.session.enabled には、有効にするセッションレベルのメトリクス (セッションに対してグローバルなメトリクス) が含まれている必要があります。

  • quarkus.cassandra.metrics.node.enabled には、有効にするノードレベルのメトリクス (Cassandra クライアントが接続する各ノードが独自のメトリクス値を取得するメトリクス) が含まれている必要があります 。

どちらのプロパティーにも、有効なメトリクス名をコンマ区切りにした一覧を使用できます。

たとえば、次の 3 つの Cassandra メトリクスを有効にする場合には、以下のとおりです。

  • セッションレベル: session.connected-nodes および session.bytes-sent;

  • ノードレベル: node.pool.open-connections

次に、application.properties に以下の設定を追加する必要があります。

quarkus.cassandra.metrics.enabled=true
quarkus.cassandra.metrics.session.enabled=connected-nodes,bytes-sent
quarkus.cassandra.metrics.node.enabled=pool.open-connections

本書の application.properties ファイルでは、すでに多くのメトリクスが有効になっています。このメトリクスリストを開始点として使用して、アプリケーションの有用な Cassandra メトリクスを公開すると適切です。

メトリクスが適切に有効になっている場合には、有効になっているすべてのメトリクスのメトリクスレポートは、アプリケーションの /metrics REST エンドポイントで利用できます。

mvn clean quarkus:dev を使用して開発モードで実行している場合には、ブラウザーで http://localhost:8080/metrics を指定するとメトリクスのリストが表示されます。名前に cassandra が含まれているメトリクスを検索します。

Cassandra メトリクスを表示するには、Cassandra クライアントを初期化して接続する必要があります。遅延初期化 (以下を参照) を使用している場合には、アプリケーションが、実際に接続してデータベースに初めてアクセスするまで、Cassandra メトリクスは表示されません。

ネイティブモードでの実行

GraalVMをインストールした場合は、以下の方法で ネイティブ・イメージをビルド できる:

mvn clean package -Dnative

ネイティブコンパイルにはかなりの時間がかかる可能性があることに注意してください。コンパイルが完了したら、次のようにネイティブ実行可能ファイルを実行できます。

./target/cassandra-quarkus-quickstart-*-runner

その後、ブラウザで http://localhost:8080/fruits.html を開いてアプリケーションを使用します。

Eager初期化とLazy初期化の選択

上記のように、このエクステンションを使用すると、多くの種類の Bean を注入できます:

  • QuarkusCqlSessionFruitDao のようなシンプルなBean;

  • そのBeanの非同期バージョン、例えば CompletionStage<QuarkusCqlSession> や `CompletionStage<FruitDao>> など;

  • そのBeanのリアクティブバージョン、例えば Uni<QuarkusCqlSession>Uni<FruitDao> など。

最も簡単な方法は、明らかにBeanを直接注入することです。これはほとんどのアプリケーションで問題なく動作するはずです。しかし、 QuarkusCqlSession Beanとそれに依存するすべてのDAO Beanは、初めて使用できるようになる前に初期化するのに時間がかかるかもしれませんし、このプロセスはブロッキング操作です。

幸いにも、初期化のタイミングを制御できます。 quarkus.cassandra.init.eager-init パラメーターは、 QuarkusCqlSession bean を最初にアクセスしたタイミング (lazy) または、アプリケーションが起動するタイミング (eager) のいずれで初期化するべきかを判断します。このパラメーターのデフォルト値は、 false で、init プロセスが遅延設定されていることを意味しています。たとえば、Cassandra データベースと対話する必要がある最初の REST 要求がある場合に、 QuarkusCqlSession bean は、遅延して、最初にアクセスしたタイミングで初期化されます。

遅延初期化を使用すると、アプリケーションの起動時間が短縮され、Cassandraデータベースが利用できない場合の起動失敗を回避できます。ただし、コードが完全にノンブロッキングである場合、たとえば リアクティブ・ルート を使用している場合などは、危険であることがわかります。実際、遅延初期化は、Vert.xイベント・ループ・スレッドなど、ブロックが許可されていないスレッドで誤って発生する可能性があります。したがって、 quarkus.cassandra.init.eager-initfalse に設定し、 QuarkusCqlSession を注入することは、このようなコンテキストでは避けるべきです。

Vert.x(または他のノンブロッキングフレームワーク)を使用し、遅延初期化動作を維持したい場合、代わりに目的のBeanの CompletionStage または Uni のみを注入する必要があります。これらのBeanを注入すると、初期化プロセスは遅延的にトリガーされますが、Vert.xのイベントループを活用したノンブロッキングの方法でバックグラウンドで発生します。こうすることで、Vert.xのスレッドをブロックするリスクを回避することができます。

quarkus.cassandra.init.eager-init この場合、セッションBeanとすべてのDAO Beanは、アプリケーションの起動時にQuarkusのメインスレッドで、早期初期化されます。これにより、Vert.xスレッドをブロックする危険性がなくなりますが、その分、起動時間が長くなります。

まとめ

クライアント・アプリケーションからのCassandraデータベースへのアクセスは、QuarkusとCassandraエクステンションで簡単に行えます。

関連コンテンツ