编辑此页面

使用 Cassandra 客户端

Apache Cassandra® 是一个免费开源的分布式、宽列存储 NoSQL 数据库管理系统,旨在处理大量跨多个通用服务器的数据,提供高可用性且没有单点故障。

在本指南中,我们将了解如何让您的 REST 服务使用 Cassandra 数据库。

此扩展由第三方开发,是 Quarkus 平台的一部分。

先决条件

要完成本指南,您需要

  • 大约 15 分钟

  • 一个 IDE

  • 已安装 JDK 17+ 并正确配置了 JAVA_HOME

  • Apache Maven 3.9.9

  • 如果您想使用它,可以选择 Quarkus CLI

  • 如果您想构建本机可执行文件(或者如果您使用本机容器构建,则为 Docker),可以选择安装 Mandrel 或 GraalVM 并进行适当的配置

  • 一个正在运行的 Apache CassandraDataStax Enterprise (DSE) 或 DataStax Astra 数据库;或者,一个全新的 Docker 安装。

架构

本快速入门指南展示了如何使用 Cassandra Quarkus 扩展构建 REST 应用程序,该扩展允许您使用 DataStax Java 驱动程序连接到 Apache Cassandra、DataStax Enterprise (DSE) 或 DataStax Astra 数据库。

本指南还将使用 DataStax 对象映射器 – 一个强大的 Java 到 CQL 的映射框架,通过避免手动编写 CQL 查询的麻烦,大大简化了应用程序的数据访问层代码。

本快速入门指南中构建的应用程序非常简单:用户可以使用表单在列表中添加元素,并且项目列表会更新。浏览器和服务器之间的所有信息都以 JSON 格式设置,并且元素存储在 Cassandra 数据库中。

解决方案

我们建议您按照以下章节中的说明,逐步创建应用程序。但是,您可以直接转到完整的示例。

该解决方案位于 Cassandra Quarkus 扩展 GitHub 存储库的 quickstart 目录中。

创建空白 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 对象映射器。换句话说,我们不会手动编写 CQL 查询;相反,我们将使用一些注解来注解我们的数据模型,并且映射器将在底层生成正确的 CQL 查询。

这就是 Fruit 类使用 @Entity 注解的原因:此注解将其标记为映射到 Cassandra 表的实体类。它的实例旨在自动持久保存到 Cassandra 数据库并从中检索。这里,表名将从类名推断:fruit

此外,name 字段表示 Cassandra 分区键,因此我们使用 @PartitionKey 注解它 – 对象映射器库中的另一个注解。

实体类通常需要具有默认的无参数构造函数,除非它们使用 @PropertyStrategy(mutable = false) 注解,这里就是这种情况。

下一步是创建一个 DAO(数据访问对象)接口,该接口将管理 Fruit 实体的实例

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

  @Select
  PagingIterable<Fruit> findAll();
}

此接口公开将在我们的 REST 服务中使用的操作。同样,注解 @Dao 来自 DataStax 对象映射器,它也会自动为您生成此接口的实现。

另请注意 findAll 方法的特殊返回类型,PagingIterable:它是驱动程序返回的结果集的基本类型。

最后,让我们创建一个 Mapper 接口

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

@Mapper 注解是 DataStax 对象映射器识别的另一个注解。映射器负责构造 DAO 实例 – 在这种情况下,我们的映射器正在构造我们的唯一 DAO 的实例,FruitDao

将映射器接口视为 DAO Bean 的工厂。如果您打算在您自己的代码中构造和注入特定的 DAO Bean,那么您首先必须在 @Mapper 接口中为其添加一个 @DaoFactory 方法。

@DaoFactory 方法名称无关紧要。

@DaoFactory 方法应返回以下类型的 Bean

  • 任何 @Dao 注解的接口,例如 FruitDao

  • 任何 @Dao 注解的接口的 CompletionStage,例如 CompletionStage<FruitDao>

  • 任何 @Dao 注解的接口的 Uni,例如 Uni<FruitDao>

Uni 是 Mutiny 库中的一种类型,Mutiny 库是 Quarkus 使用的响应式编程库。这将在下面的“响应式编程”部分中更详细地解释。

生成 DAO 和映射器实现

您可能已经猜到了,我们不会实现上面的接口。相反,对象映射器将为我们生成这些实现。

对象映射器由 2 个部分组成

  1. 一个(编译时)注解处理器,它扫描带有 @Mapper@Dao@Entity 注解的类路径,并为它们生成代码和 CQL 查询;以及

  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。但是 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)。不过,不需要熟悉生成的代码,因为它主要是在与数据库交互的内部机制。

创建服务和 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 注解的接口的 CompletionStageUni

  • @DaoFactory 方法返回的任何 Bean(有关可能的 Bean 类型,请参见上文)。

  • QuarkusCqlSession Bean:此应用程序范围的单例 Bean 是您访问 Cassandra 客户端的主要入口点;它是一个专门的 Cassandra 驱动程序会话实例,具有一些专门为 Quarkus 定制的方法。请仔细阅读其 Javadocs!

  • 您还可以注入 CompletionStage<QuarkusCqlSession>Uni<QuarkusCqlSession>

在我们的示例中,FruitMapperFruitDao 都可以在任何地方注入。我们选择在 FruitService 中注入 FruitDao

最后一个缺失的部分是 REST API,它将公开 GET 和 POST 方法

@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());
  }
}

请注意 FruitResource 如何自动注入 FruitService 实例。

通常不建议在 REST API 和数据访问层之间使用相同的实体对象。这些层实际上应该解耦并使用不同的 API,以便允许每个 API 独立于另一个 API 发展。这就是为什么我们的 REST API 使用不同的对象的原因:FruitDto 类 – 单词 DTO 代表“数据传输对象”。此 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 的转换由 Quarkus REST(以前的 RESTEasy Reactive)扩展自动完成,该扩展包含在本指南的 pom.xml 文件中。如果您想手动将其添加到您的应用程序中,请将以下代码段添加到您的应用程序的 pom.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 中声明了两个转换方法:convertToDtoconvertFromDto

在我们的示例中,FruitFruitDto 非常相似,因此您可能想知道为什么不 везде 使用 Fruit。但在现实生活中,DTO 和实体具有非常不同的结构并不少见。

连接到 Cassandra 数据库

连接到 Apache Cassandra 或 DataStax Enterprise (DSE)

要配置的主要属性是:contact-points(用于访问 Cassandra 数据库)、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

如果您的群集需要纯文本身份验证,您还必须提供两个设置:usernamepassword

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

连接到 DataStax Astra Cloud 数据库

在连接到 DataStax Astra 时,您应该提供所谓的安全连接包,而不是提供联系点和数据中心,该安全连接包应指向 Astra 安全连接包文件的有效路径。您可以从 Astra Web 控制台下载您的安全连接包。

您还需要提供用户名和密码,因为 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.confapplication.json 文件配置其他 Java 驱动程序设置。它们需要位于应用程序的类路径中。所有设置将自动传递到底层驱动程序配置机制。在 application.properties 中使用 quarkus.cassandra 前缀定义的设置将优先于在 application.confapplication.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 交互。

创建水果

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

检索水果

curl -X GET https://:8080/fruits

创建前端

现在让我们添加一个简单的网页来与我们的 FruitResource 交互。

Quarkus 自动服务位于 META-INF/resources 目录下的静态资源。在 src/main/resources/META-INF/resources 目录中,添加一个包含 此文件内容的 fruits.html 文件。

您现在可以与您的 REST 服务交互

  • 如果您尚未完成,请使用 mvn clean quarkus:dev 启动您的应用程序;

  • 将您的浏览器指向 https://: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 类型,它还公开了一些额外的方法,例如获取查询执行信息。如果您不需要该接口中的任何内容,您也可以简单地声明您的方法以返回 MultiMulti<Fruit> findAll()

同样,方法 updateAsync 返回一个 Uni - 它会自动从驱动程序返回的原始结果集转换而来。

Cassandra 驱动程序使用 Reactive Streams Publisher API 进行响应式调用。但是,Quarkus 框架使用 Mutiny。因此,CqlQuarkusSession 接口透明地将驱动程序返回的 Publisher 实例转换为响应式类型 MultiCqlQuarkusSession 还可以将 Publisher 转换为 Uni – 在这种情况下,预计发布者最多发出一次行,然后完成。这适用于写入查询(它们不返回行)或保证最多返回一行的读取查询(例如,计数查询)。

接下来,我们需要调整 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() 方法返回 Multiadd() 方法返回 Uni。这些类型与我们之前遇到的 Mutiny 类型相同;它们会自动被 Quarkus 响应式 REST API 识别,因此我们不需要自己将它们转换为 JSON。

Quarkus REST 本机支持 Mutiny 响应式类型,例如 UniMulti

此依赖项已包含在本指南的 pom.xml 中,但如果您从头开始一个新项目,请确保包含它。

测试响应式 REST API

如上所述以开发模式运行应用程序,然后您可以使用 curl 命令与底层 REST API 交互。

使用响应式 REST 端点创建水果

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

使用响应式 REST 端点检索水果

curl -X GET https://:8080/reactive-fruits

创建响应式前端

现在让我们添加一个简单的网页来与我们的 ReactiveFruitResource 交互。在 src/main/resources/META-INF/resources 目录中,添加一个包含 此文件内容的 reactive-fruits.html 文件。

您现在可以与您的响应式 REST 服务交互

  • 如果您尚未完成,请使用 mvn clean quarkus:dev 启动您的应用程序;

  • 将您的浏览器指向 https://: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 以开发模式运行,如果您将您的浏览器指向 https://: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.properties 中将 quarkus.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 Metrics 启用指标

从您的 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 指标。可以跟踪多个指标;如果您跳过此步骤,将自动跟踪一组有用的默认指标。

有关可用指标名称的完整列表,请参阅 驱动程序设置参考页面;搜索 advanced.metrics 部分。此外,驱动程序手册中详细介绍了 Cassandra 驱动程序指标。

如果您希望自定义要跟踪的指标,则应使用以下属性

  • quarkus.cassandra.metrics.session.enabled 应包含要启用的会话级别指标(会话全局的指标)。

  • quarkus.cassandra.metrics.node.enabled 应包含要启用的节点级别指标(Cassandra 客户端联系的每个节点都有其自己的指标值的指标)。

两个属性都接受以逗号分隔的有效指标名称列表。

例如,让我们假设您希望启用以下三个 Cassandra 指标

  • 会话级别:session.connected-nodessession.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 以开发模式运行,如果您将您的浏览器指向 https://:8080/metrics,您应该看到一个指标列表;搜索名称包含 cassandra 的指标。

要显示 Cassandra 指标,需要初始化并连接 Cassandra 客户端;如果您正在使用延迟初始化(请参见下文),在您的应用程序实际连接并首次访问数据库之前,您不会看到任何 Cassandra 指标。

以本机模式运行

如果您安装了 GraalVM,您可以使用

mvn clean package -Dnative

请注意,本机编译可能需要大量时间!完成编译后,您可以如下所示运行本机可执行文件

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

然后,您可以将您的浏览器指向 https://:8080/fruits.html 并使用您的应用程序。

在热切初始化和延迟初始化之间进行选择

如上所述,此扩展允许您注入多种类型的 Bean

  • 一个简单的 Bean,例如 QuarkusCqlSessionFruitDao

  • 该 Bean 的异步版本,例如 CompletionStage<QuarkusCqlSession> 或 `CompletionStage<FruitDao>;

  • 该 Bean 的响应式版本,例如 Uni<QuarkusCqlSession>Uni<FruitDao>

最直接的方法显然是直接注入 Bean。对于大多数应用程序来说,这应该可以正常工作。但是,QuarkusCqlSession Bean 以及所有依赖于它的 DAO Bean 可能需要一些时间才能初始化,然后才能首次使用,并且此过程是阻塞的。

幸运的是,可以控制何时发生初始化:quarkus.cassandra.init.eager-init 参数确定 QuarkusCqlSession Bean 应在其首次访问时(延迟)还是在应用程序启动时(热切)初始化。此参数的默认值为 false,这意味着初始化过程是延迟的:QuarkusCqlSession Bean 将在其首次访问时延迟初始化 – 例如,当有第一个需要与 Cassandra 数据库交互的 REST 请求时。

使用延迟初始化可以加快您的应用程序启动时间,并避免 Cassandra 数据库不可用时的启动失败。但是,如果您的代码完全是非阻塞的,例如,如果它使用 响应式路由,那么这也可能被证明是危险的。实际上,延迟初始化可能会意外地发生在不允许阻塞的线程上,例如 Vert.x 事件循环线程。因此,在这些情况下应避免将 quarkus.cassandra.init.eager-init 设置为 false 并注入 QuarkusCqlSession

如果您想使用 Vert.x(或任何其他非阻塞框架)并保持延迟初始化行为,则应仅注入所需 Bean 的 CompletionStageUni。注入这些 Bean 时,初始化过程将被延迟触发,但它将在后台以非阻塞方式进行,从而利用 Vert.x 事件循环。这样,您不会冒着阻塞 Vert.x 线程的风险。

或者,您可以将 quarkus.cassandra.init.eager-init 设置为 true:在这种情况下,会话 Bean 和所有 DAO Bean 将在应用程序启动期间在 Quarkus 主线程上热切地初始化。这将消除阻塞 Vert.x 线程的任何风险,但代价是使您的启动时间(大大)延长。

结论

使用 Quarkus 和 Cassandra 扩展程序可以轻松地从客户端应用程序访问 Cassandra 数据库,该扩展程序为 Apache Cassandra 的 DataStax Java 驱动程序提供配置和本机支持。

相关内容