我有一个现有的 Spring Boot 3 应用程序,它运行带有 Caffeine 缓存和
@Cacheable
注释的单节点。
到目前为止,该应用程序运行良好,因为 Caffeine 不关心 POJO 结构或格式,它只会将键和值存储在内存中。请记住,在 Spring Cache 世界中,键通常是对象,例如缓存的
Person getPerson(String firstName, String lastName)
使用复合键。
该应用程序在性能方面对业务至关重要。它在支付行业运作,所以我将专门讨论安全考虑。
好的,现在是时候在 Openshift 上实施红帽数据网格了。因此,我启动了 Infinispan 14 的本地实例,并希望自动配置能发挥一些作用。
这是 infinispan.yaml
infinispan:
local-cache-configuration:
name: base-template
expiration:
lifespan: 1800000
encoding:
media-type: application/x-java-object #We'll talk about this
cache-container:
name: default
caches:
ipe.my-ipe-cache: # Consider it is referenced in @Cacheable(value = CACHE_KEY)
local-cache:
configuration: base-template
# Consider 24 identical nodes
server:
interfaces:
- name: public
inet-address:
value: 127.0.0.1
socket-bindings:
default-interface: public
port-offset: 0
socket-binding:
- name: default
port: 11222
- name: memcached
port: 11221
endpoints:
endpoint:
socket-binding: default
security-realm: default
security:
security-realms:
- name: default
properties-realm:
groups-attribute: Roles
user-properties:
path: users.properties
group-properties:
path: groups.properties
和application.yaml
infinispan:
embedded:
enabled: false
remote:
enabled: true
server-list: "localhost:11222"
auth-username: admin
auth-password: admin
# marshaller: org.infinispan.commons.marshall.UTF8StringMarshaller
# marshaller: org.infinispan.commons.marshall.ProtoStreamMarshaller
marshaller: org.infinispan.commons.marshall.JavaSerializationMarshaller
java-serial-allow-list: "com\\.acme\\.ipe\\.(.*)\\.dto\\.\\w+"
现在问题在于配置正确的编组,而我陷入了困境
反正没成功
org.infinispan.client.hotrod.exceptions.HotRodClientException: org.infinispan.commons.CacheException: ISPN000936: Class 'com.acme.ipe.core.data.dto.ChannelDto' blocked by deserialization allow list. Adjust the configuration serialization allow list regular expression to include this class.
at java.base/java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:396)
at java.base/java.util.concurrent.CompletableFuture.get(CompletableFuture.java:2096)
at org.infinispan.client.hotrod.impl.Util.await(Util.java:52)
at org.infinispan.client.hotrod.impl.RemoteCacheSupport.put(RemoteCacheSupport.java:196)
at org.infinispan.client.hotrod.impl.RemoteCacheSupport.put(RemoteCacheSupport.java:186)
at org.infinispan.spring.common.provider.SpringCache.put(SpringCache.java:145)
at org.springframework.cache.interceptor.AbstractCacheInvoker.doPut(AbstractCacheInvoker.java:87)
java.lang.IllegalArgumentException: No marshaller registered for object of Java type com.acme.ipe.core.data.dto.ChannelDto : ChannelDto(id=1, creationDate=2017-11-06T06:40:06, ...)
at org.infinispan.protostream.impl.SerializationContextImpl.getMarshallerDelegate(SerializationContextImpl.java:503)
at org.infinispan.protostream.WrappedMessage.writeMessage(WrappedMessage.java:281)
at org.infinispan.protostream.WrappedMessage.write(WrappedMessage.java:242)
at org.infinispan.protostream.ProtobufUtil.toWrappedByteBuffer(ProtobufUtil.java:153)
at org.infinispan.commons.marshall.ImmutableProtoStreamMarshaller.objectToBuffer(ImmutableProtoStreamMarshaller.java:55)
at org.infinispan.commons.marshall.AbstractMarshaller.objectToByteBuffer(AbstractMarshaller.java:70)
at org.infinispan.client.hotrod.marshall.MarshallerUtil.obj2bytes(MarshallerUtil.java:117)
at org.infinispan.client.hotrod.DataFormat$DataFormatImpl.valueToBytes(DataFormat.java:92)
at org.infinispan.client.hotrod.DataFormat.valueToBytes(DataFormat.java:211)
at org.infinispan.client.hotrod.impl.RemoteCacheImpl.valueToBytes(RemoteCacheImpl.java:610)
at org.infinispan.client.hotrod.impl.RemoteCacheImpl.putAsync(RemoteCacheImpl.java:306)
at org.infinispan.client.hotrod.impl.RemoteCacheSupport.put(RemoteCacheSupport.java:196)
at org.infinispan.client.hotrod.impl.RemoteCacheSupport.put(RemoteCacheSupport.java:186)
at org.infinispan.spring.common.provider.SpringCache.put(SpringCache.java:145)
at org.springframework.cache.interceptor.AbstractCacheInvoker.doPut(AbstractCacheInvoker.java:87)
media-type
设置为
application/json
,但我在类路径中找不到任何支持的编组器包起来
另外,是否可以不使用 Protobuf 注释手动注释所有现有的 DTO,例如通过使用一些可能会为您生成映射的 IDE 或 Maven 插件?
作为今天的最后手段,我怎样才能克服几行前显示的错误
ISPN000936
?我确实将允许列表添加到了我的 Spring 应用程序中!
encoding: application/x-java-object
。这意味着服务器将希望拥有类的字节码,以便能够解释数据并可能对其进行转码。这也是您收到
org.infinispan.commons.CacheException: ISPN000936: Class 'com.acme.ipe.core.data.dto.ChannelDto' blocked by deserialization allow list.
错误的原因:它来自服务器,而不是客户端。
在服务器上使用 application/octet-stream
可以避免这种情况。此外,JBoss Marshalling 将提供比普通 Java 序列化更好的性能。协议缓冲区显然是理想的选择,但如果要适应大量现有代码,它们确实需要大量的跑腿工作。
对于 JSON,您可以使用 Jackson 来实现客户端
JSONMarshaller
来进行编组/解组。这也可以为上游贡献。