Using the Cassandra Client
Apache Cassandra® 是一款免费且开源的分布式宽列式存储、NoSQL 数据库管理系统,旨在跨多个商用服务器处理海量的数据,并提供高可用性,且无单点故障。 在本指南中,我们将了解如何让您的 REST 服务使用 Cassandra 数据库。 :iokays-category: quarkus :iokays-path: modules/ROOT/pages/_includes/platform-include.adoc :keywords: Quarkus, 中文文档, 编程技术
此扩展由第三方开发并属于 Quarkus Platform。 |
- Prerequisites
- Architecture
- Solution
- Creating a Blank Maven Project
- Creating the Data Model and Data Access Objects
- Generating the DAO and mapper implementations
- Creating a service & JSON REST endpoint
- Connecting to the Cassandra Database
- Running a Local Cassandra Database
- Testing the REST API
- Creating a Frontend
- Reactive Programming with the Cassandra Client
- Testing the Reactive REST API
- Creating a Reactive Frontend
- Health Checks
- Metrics
- Running in native mode
- Choosing between eager and lazy initialization
- Conclusion
Prerequisites
include::./_includes/prerequisites.adoc[]* 正在运行的 Apache Cassandra, DataStax Enterprise (DSE) 或 DataStax Astra 数据库;或者,干净的 Docker 安装。
Architecture
本快速入门指南显示了如何使用 Cassandra Quarkus extension构建 REST 应用程序,此应用程序允许您连接到 Apache Cassandra、DataStax Enterprise (DSE) 或 DataStax Astra 数据库,使用 DataStax Java driver。
本指南还将使用 DataStax Object Mapper– 一个功能强大的 Java 到 CQL 映射框架,通过避免您手动编写 CQL 查询的麻烦,极大地简化了您的应用程序数据访问层代码。
在本快速入门指南中构建的应用程序非常简单:用户可以使用表单在列表中添加元素,然后更新项目列表。浏览器和服务器之间所有信息都采用 JSON 格式,并且这些元素存储在 Cassandra 数据库中。
Solution
我们建议您按照以下部分中的说明进行操作,并逐步创建应用程序。但是,您可以直接转到完成的示例。
该解决方案位于 Cassandra Quarkus 扩展 GitHub 存储库的 quickstart directory中。
Creating a Blank Maven Project
首先,创建一个新的 Maven 项目,并复制 `pom.xml`中存在的 `quickstart`目录中的文件。
`pom.xml`将导入您所需的所有 Quarkus 扩展和依赖项。
Creating the Data Model and Data Access Objects
在此示例中,我们将创建一个应用程序来管理水果列表。
首先,让我们创建我们的数据模型(由 `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 表的 entity class。它的实例不会主动持久到 Cassandra 数据库,或从其检索。此处,表名称将从类名称 `fruit`中推断。
此外,`name`字段表示 Cassandra 分区键,因此我们使用来自 Object Mapper 库的另一个注释 `@PartitionKey`对其进行注释。
实体类通常需要有一个默认的无参数构造函数,除非它们使用 `@PropertyStrategy(mutable = false)`注释(此处即采用这种方式)。
下一步是创建一个 DAO(数据访问对象)接口,此接口将管理`Fruit`实体的实例:
@Dao
public interface FruitDao {
@Update
void update(Fruit fruit);
@Select
PagingIterable<Fruit> findAll();
}
此接口公开将在我们的 REST 服务中使用的操作。同样,注释`@Dao`来自 DataStax Object Mapper,它还将自动为您生成此接口的一个实现。
另请注意 findAll
方法的特殊返回类型 PagingIterable
: 它是驱动程序返回的结果集的基本类型。
最后,让我们创建一个 Mapper 接口:
@Mapper
public interface FruitMapper {
@DaoFactory
FruitDao fruitDao();
}
@Mapper
注解是 DataStax Object Mapper 识别的另一个注解。amapper 负责构建 DAO 实例——本例中,我们的 mapper 正在构建我们唯一的 DAO FruitDao
的实例。
将 mapper 接口视为 DAO bean 的工厂。如果你打算在自己的代码中构建和注入特定的 DAO bean,那么首先必须在 @Mapper
接口中为其添加 @DaoFactory
方法。
|
@DaoFactory
方法应返回以下类型的 bean:
-
任何
@Dao
注解的接口,例如FruitDao
; -
任何
@Dao
注解的接口的CompletionStage
,例如CompletionStage<FruitDao>
。 -
任何
@Dao
注解的接口的Uni
,例如Uni<FruitDao>
。
|
Generating the DAO and mapper implementations
你可能已经猜到了,我们不会实现上述接口。相反,Object Mapper 将为我们生成此类实现。
Object Mapper 由 2 部分组成:
-
(编译时)注释处理器,它扫描类路径中注释有
@Mapper
、@Dao
或@Entity
的类,并为它们生成代码和 CQL 查询; -
一个包含执行生成查询的逻辑的运行时模块。
因此,启用 Object Mapper 需要两个步骤:
-
声明
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 应用程序的注解处理器,因此请检查正在使用的是否是此注解处理器。此外,切勿同时使用两个注解处理器。
-
在项目的
pom.xml
文件中声明编译范围内的java-driver-mapper-runtime
依赖项,如下所示:
<dependency>
<groupId>com.datastax.oss</groupId>
<artifactId>java-driver-mapper-runtime</artifactId>
</dependency>
尽管这个模块称为“运行时”,但它必须在编译范围内声明。
如果正确设置了项目,现在你应该能够毫无错误地编译它,并且你应该能看到生成的代码位于 target/generated-sources/annotations
目录(如果你使用 Maven 的话)。你不必熟悉生成的代码,因为它主要是与数据库交互的内部机制。
Creating a service & JSON REST endpoint
现在让我们创建一个 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 客户端的主要入口点;它是一个专门的 Cassandra 驱动程序会话实例,有几个针对 Quarkus 量身定制的方法。仔细阅读其 Java 文档! -
你还可以注入
CompletionStage<QuarkusCqlSession>
或Uni<QuarkusCqlSession>
。
在我们的示例中,FruitMapper
和 FruitDao
都可以在任何地方注入。我们选择在 FruitService
中注入 FruitDao
。
最后缺失的部分是公开 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());
}
}
注意 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 转换为 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
中声明了两个转换方法:convertToDto
和 convertFromDto
。
在我们的示例中, |
Connecting to the Cassandra Database
Connecting to Apache Cassandra or 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}
在这个示例中,我们使用在本地主机上运行的单个实例,并且包含我们数据的键空间是 k1
:
quarkus.cassandra.contact-points=127.0.0.1:9042
quarkus.cassandra.local-datacenter=datacenter1
quarkus.cassandra.keyspace=k1
如果你的集群需要纯文本身份验证,你必须还提供更多两个设置: username
和 password
。
quarkus.cassandra.auth.username=john
quarkus.cassandra.auth.password=s3cr3t
Connecting to a DataStax Astra Cloud Database
当连接到 DataStax Astra 时,应该提供所谓的 secure connect bundle,而不是提供一个联系点和一个数据中心,这应该指向 Astra 安全连接束文件的一个有效路径。你可以在 Astra 网页控制台中下载你的安全连接束。
你还需要提供一个用户名和密码,因为 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
Advanced Driver Configuration
你可以使用 application.conf
或 application.json
文件配置其他 Java 驱动程序设置。它们需要位于你的应用程序的类路径中。所有设置都将自动传递给底层驱动程序配置机制。在 application.properties
中用 quarkus.cassandra
前缀定义的设置将优先于在 application.conf
或 application.json
中定义的设置。
要查看全部设置列表,请参阅 driver settings reference。
Running a Local Cassandra Database
默认情况下,Cassandra 客户端被配置为访问端口 9042 上的本地 Cassandra 数据库(默认 Cassandra 端口)。
确保设置 quarkus.cassandra.local-datacenter
匹配你的 Cassandra 集群的数据中心。
如果你不知道本地数据中心的名称,可以通过运行以下 CQL 查询找到这个值: |
如果你想使用 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
Testing the 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"}' \
http://localhost:8080/fruits
要检索水果:
curl -X GET http://localhost:8080/fruits
Creating a Frontend
现在,让我们添加一个简单的网页来与我们的 FruitResource
进行交互。
Quarkus 会自动提供位于 META-INF/resources
目录下的静态资源。在 src/main/resources/META-INF/resources
目录中,添加一个 fruits.html
文件,其中包含 this file 中的内容。
你现在可以与你的 REST 服务进行交互:
-
如果您还没有这样做,请使用
mvn clean quarkus:dev
启动您的应用程序; -
通过表单向列表中添加新水果。
Reactive Programming with the Cassandra Client
QuarkusCqlSession
interface 可以使用一系列响应式方法,这些方法可以与 Quarkus 及其响应式框架 Mutiny 无缝集成。
如果您不熟悉 Mutiny,请查看 Mutiny - an intuitive reactive programming library。 |
让我们使用 Mutiny 的响应式编程重写我们的应用程序。
首先,让我们声明另一个以响应式方式工作的 DAO 接口:
@Dao
public interface ReactiveFruitDao {
@Update
Uni<Void> updateAsync(Fruit fruit);
@Select
MutinyMappedReactiveResultSet<Fruit> findAll();
}
请注意使用 MutinyMappedReactiveResultSet
——它是一种专门的 Mutiny
类型,从驱动程序返回的原始 Publisher
转换而来,它还公开了一些额外的方法,例如获取查询执行信息。如果您不需要该接口中的任何内容,您还可以简单地声明您的方法返回 Multi
: Multi<Fruit> findAll()
,
同样,方法 updateAsync
返回一个 Uni
——它会从驱动程序返回的原始结果集自动转换而来。
Cassandra 驱动程序使用响应式流 |
接下来,我们需要调整 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
创建的功能相同,但一切都以响应式的方式处理,没有任何阻塞操作。
上面的 |
Quarkus REST 本机支持 Mutiny 响应式类型,例如 Uni
和 Multi
。
此依赖项已包含在此指南的 pom.xml 中,但如果您要从头开始一个新项目,请确保包含它。
Testing the Reactive REST API
如上文所述,以开发模式运行该应用程序,然后你就可以使用 curl 命令与底层 REST API 交互。
使用反应式 REST 端点创建水果:
curl --header "Content-Type: application/json" \
--request POST \
--data '{"name":"banana","description":"yellow and sweet"}' \
http://localhost:8080/reactive-fruits
使用反应式 REST 端点检索水果:
curl -X GET http://localhost:8080/reactive-fruits
Creating a Reactive Frontend
现在,我们来添加一个简单的网页以与我们的 ReactiveFruitResource
进行交互。在 src/main/resources/META-INF/resources
目录中,使用 this file 中的内容添加一个 reactive-fruits.html
文件。
你现可与你的反应式 REST 服务进行交互:
-
如果您还没有这样做,请使用
mvn clean quarkus:dev
启动您的应用程序; -
通过表单向列表中添加新水果。
Health Checks
如果你使用的是 Quarkus SmallRye Health 扩展,那么 Cassandra 客户端将自动添加一个准备就绪运行状况检查来验证与 Cassandra 集群的连接。此扩展已包括在本指南的 pom.xml 中,但如果你需要在应用程序中手动将其包含在内,请添加以下内容:
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-smallrye-health</artifactId>
</dependency>
当运行状况检查可用时,你可以访问应用程序的 /health/ready
端点,并获得有關连接验证状态的信息。
在 mvn clean quarkus:dev
的开发模式下运行,如果你将浏览器指向 [role="bare"] [role="bare"]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 运行状况检查,你可以通过在 |
Metrics
Cassandra Quarkus 客户端可以提供有关 Cassandra 会话和各个 Cassandra 节点的指标。它支持 Micrometer 和 MicroProfile。
启用指标的第一步是添加一些其他依赖项,具体取决于你计划使用的指标框架。
Enabling Metrics with 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 中。
Enabling Metrics with 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>
Enabling Cassandra Metrics
即使你的应用程序中启用了指标,Cassandra 客户端也不会报告任何指标,除非你选择此功能。因此你的下一步是在 application.properties
文件中启用 Cassandra 指标。
quarkus.cassandra.metrics.enabled=true
就是这样!
最后(可选)的一步是自定义 Cassandra 客户端要跟踪的特定 Cassandra 指标。可以跟踪几个指标;如果你跳过此步骤,将自动跟踪一组有用的默认指标。
有关可用指标名称的完整列表,请参阅 driver settings reference页面;搜索`advanced.metrics`部分。同时, driver manual中详细介绍了 Cassandra 驱动器指标。 |
如果您确实希望自定义要跟踪的指标,则应使用以下属性:
-
`quarkus.cassandra.metrics.session.enabled`应包含要启用的会话级别指标(对会话是全局的指标)。
-
`quarkus.cassandra.metrics.node.enabled`应包含要启用的节点级别指标(Cassandra 客户端所联系的每个节点获取其自己的指标值)。
这两个属性都接受有效指标名称的逗号分隔列表。
例如,假设您希望启用以下三个 Cassandra 指标:
-
Session-level:
session.connected-nodes
andsession.bytes-sent
; -
Node-level:
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 指标,直到您的应用程序实际连接并首次访问数据库为止。
Running in native mode
如果您安装了 GraalVM,可以使用以下方式进行build a native image:
mvn clean package -Dnative
请注意,本机编译可能需要大量时间!编译完成后,您可以按如下方式运行本机可执行文件:
./target/cassandra-quarkus-quickstart-*-runner
然后您可以将浏览器指向 http://localhost:8080/fruits.html
,并使用您的应用程序。
Choosing between eager and lazy initialization
如上所述,此扩展程序允许您注入多种类型的 Bean:
-
像 `QuarkusCqlSession`或`FruitDao`这样的简单 Bean;
-
Bean 的异步版本,例如`CompletionStage<QuarkusCqlSession>`或`CompletionStage<FruitDao>`;
-
Bean 的反应式版本,例如`Uni<QuarkusCqlSession>`或`Uni<FruitDao>`。
最直接的方法显然是直接注入 Bean。这应该适用于大多数应用程序。但是,`QuarkusCqlSession`Bean 以及依赖于它的所有 DAO Bean 在首次使用之前可能需要一些时间初始化,并且此过程正在阻塞。
幸运的是,可以控制初始化应该何时发生:参数`quarkus.cassandra.init.eager-init`确定是否应该在第一次访问时初始化 QuarkusCqlSession`Bean(延迟)或者在应用程序启动时(热切)初始化。此参数的默认值为 `false
,表示 init 过程是延迟的:`QuarkusCqlSession`Bean 将在其第一次访问时延迟初始化——例如,当有第一个 REST 请求需要与 Cassandra 数据库进行交互时。
使用延迟初始化可以加快应用程序的启动时间,并在 Cassandra 数据库不可用时避免启动失败。但是,如果你的代码完全非阻塞,例如它使用了 reactive routes,则它也可能被证明是危险的。事实上,延迟的初始化可能会在不允许阻塞的线程上意外发生,例如 Vert.x 事件循环线程。因此,在这些上下文中应该避免将 quarkus.cassandra.init.eager-init
设置为 false
并注入 QuarkusCqlSession
。
如果你想使用 Vert.x(或任何其他非阻塞框架)并保持延迟初始化行为,则你应该仅注入所需 Bean 的 CompletionStage
或 Uni
。在注入这些 Bean 时,将在后台以非阻塞方式利用 Vert.x 事件循环来延迟触发初始化过程。这样你就不会冒着阻塞 Vert.x 线程的风险。
或者,你可以将 quarkus.cassandra.init.eager-init
设置为 true:在这种情况下,会话 Bean 和所有 DAO Bean 将在应用程序启动期间在 Quarkus 主线程上热切地初始化。这将消除阻塞 Vert.x 线程的任何风险,代价是让你的启动时间(大大)更长。