Infinispan Cache
默认情况下,Quarkus Cache 使用 Caffeine 作为后端。你可以改用 Infinispan。 :iokays-category: quarkus :iokays-path: modules/ROOT/pages/_includes/extension-status.adoc :keywords: Quarkus, 中文文档, 编程技术
该技术被认为是 {extension-status}。 有关可能状态的完整列表,请查看我们的 FAQ entry. |
Infinispan as cache backend
将 Infinispan 用作 Quarkus 缓存的后端时,每个缓存项都将存储在 Infinispan 中:
-
后端使用 @13 Infinispan 客户端(除非配置不同),因此请确保其配置已相应设置(或使用 @14)。
-
键和值都使用 Protostream 和 protobuf 进行计算。
Use the Infinispan backend
首先,将 @15 扩展添加到你的项目:
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-infinispan-cache</artifactId>
</dependency>
implementation("io.quarkus:quarkus-infinispan-cache")
然后,使用 @16 和其他缓存注释,正如 @17 中详细说明的那样:
@GET
@Path("/{keyElement1}/{keyElement2}/{keyElement3}")
@CacheResult(cacheName = "expensiveResourceCache")
public ExpensiveResponse getExpensiveResponse(@PathParam("keyElement1") @CacheKey String keyElement1,
@PathParam("keyElement2") @CacheKey String keyElement2, @PathParam("keyElement3") @CacheKey String keyElement3,
@QueryParam("foo") String foo) {
invocations.incrementAndGet();
ExpensiveResponse response = new ExpensiveResponse();
response.setResult(keyElement1 + " " + keyElement2 + " " + keyElement3 + " too!");
return response;
}
@POST
@CacheInvalidateAll(cacheName = "expensiveResourceCache")
public void invalidateAll() {
}
Configure the Infinispan backend
Infinispan 后端使用 @18 Infinispan 客户端. 请参阅 @19 以了解配置对 Infinispan 的访问权限。
在开发模式中,你可以使用 @20. |
如果你想为你的缓存使用另一个 Infinispan,请按照如下方式配置 @21:
quarkus.cache.infinispan.client-name=another
Marshalling
在 Quarkus 中与 Infinispan 交互时,您可以在存储或从缓存中检索数据时轻松地序列化和反序列化 Java 原始类型。Infinispan 不需要额外的编组配置。
@CacheResult(cacheName = "weather-cache") (1)
public String getDailyForecast(String dayOfWeek, int dayOfMonth, String city) { (2)
return dayOfWeek + " will be " + getDailyResult(dayOfMonth % 4) + " in " + city;
}
1 | 要求将此方法执行缓存到“weather-cache”中 |
2 | 该键组合了 String`星期几、`int`本月几日和 `String`城市。关联的值类型为 `String 。 |
Quarkus 默认使用协议缓冲区对 Infinispan 中的数据进行序列化。Infinispan 建议使用协议缓冲区作为首选的数据结构方式。因此,在使用纯旧 Java 对象 (POJO) 时,用户需要在 Infinispan 中提供编组架构。
Marshalling Java types
我们假设要使用 `java.time.LocalDate`创建一个复合键。
@CacheResult(cacheName = "weather-cache") (1)
public String getDailyForecast(LocalDate date, String city) { (2)
return date.getDayOfWeek() + " will be " + getDailyResult(date.getDayOfMonth() % 4) + " in " + city;
}
1 | 要求将此方法执行的响应缓存到“weather-cache”中 |
2 | 该键组合了 `java.util.LocalDate`日期和 `String`城市。关联的值的类型为“String”。 |
由于 Infinispan 在 Quarkus 中默认使用协议缓冲区序列化数据,因此执行代码会产生以下错误:
java.lang.IllegalArgumentException:
No marshaller registered for object of Java type java.time.LocalDate
协议缓冲区本身不知道如何编组 java.time.LocalDate
。幸运的是,Protostream 提供了一种使用 `@ProtoAdapter`和 `@ProtoSchema`来轻松解决此问题的方案。
@ProtoAdapter(LocalDate.class)
public class LocalDateAdapter {
@ProtoFactory
LocalDate create(String localDate) {
return LocalDate.parse(localDate);
}
@ProtoField(1)
String getLocalDate(LocalDate localDate) {
return localDate.toString();
}
}
@ProtoSchema(includeClasses = LocalDateAdapter.class, schemaPackageName = "quarkus")
public interface Schema extends GeneratedSchema {
}
Marshalling your POJOs
与 Java 类型一样,在将您的 POJO 用作键或值时,您可以遵循此方法:
@CacheResult(cacheName = "my-cache") (1)
public ExpensiveResponse requestApi(String id) { (2)
// very expensive call
return new ExpensiveResponse(...);
}
1 | 要求将此方法执行的响应缓存到“my-cache”中 |
2 | 该键是一个 String 。关联的值的类型为 org.acme.ExpensiveResponse 。 |
在这种情况下,您需要使用 `@Proto`和 `@ProtoSchema`为 Java 类型定义架构。该架构可以包含 Quarkus 应用程序中使用的所有类型和适配器。
@Proto
public record ExpensiveResponse(String result) {
}
@ProtoSchema(includeClasses = { ExpensiveResponse.class })
interface Schema extends GeneratedSchema {
}
在基于注解的序列化部分的 Infinispan reference中阅读更多相关信息。
Expiration
您可以配置两个数据过期属性: lifespan*和 *max-idle。
Lifespan
在 Infinispan 中,*lifespan*指一个配置参数,用于确定一项(或一个对象)在缓存中创建或在标记为过期并从缓存中移除之前,在该缓存中可以驻留的最长时间。
当您为 Infinispan 缓存中的条目配置 *lifespan*参数时,您指定了一个时间持续时间。一项被添加到缓存中或被访问(读取或写入)后,便开始倒计时其生命周期。如果自条目创建或最后访问以来的时间超出了指定“生命周期”持续时间,那么该条目将被视为已过期,且符合从缓存中驱逐的条件。
quarkus.cache.infinispan.my-cache.lifespan=10s
Max Idle
当您为 Infinispan 缓存中的条目配置 *max-idle*参数时,您指定了一个时间持续时间。一项在缓存中被访问(读取或写入)后,如果在指定持续时间内没有后续访问该项,那么该项会被视为闲置。一旦闲置时间超过 *max-idle*持续时间,那么该条目将被视为已过期,且符合从缓存中驱逐的条件。
quarkus.cache.infinispan.my-cache.max-idle=100s
Unresolved include directive in modules/ROOT/pages/cache-infinispan-reference.adoc - include::../../../target/quarkus-generated-doc/config/quarkus-infinispan-cache.adoc[]