使用 Wildfly 11 复制的 infinispan 缓存
Posted
技术标签:
【中文标题】使用 Wildfly 11 复制的 infinispan 缓存【英文标题】:Replicated infinispan cache with Wildfly 11 【发布时间】:2018-06-12 08:41:03 【问题描述】:我正在使用wildfly-11.0.0.Final 上的java 8 和java ee7 开发一个分布在多节点上的Web 应用程序,并且我使用infinispan 缓存来共享数据。 这是缓存的配置:
<cache-container name="mycache-container" default-cache="my-cache" jndi-name="infinispan/mycache-container">
<transport lock-timeout="60000"/>
<replicated-cache name="my-cache" jndi-name="infinispan/mycache-container/my-cache" mode="ASYNC">
<locking isolation="READ_COMMITTED"/>
<transaction locking="OPTIMISTIC" mode="NON_XA"/>
<eviction strategy="NONE"/>
</replicated-cache>
</cache-container>
这是用于复制缓存的 jgroups 子系统的配置:
<subsystem xmlns="urn:jboss:domain:jgroups:5.0">
<channels default="ee">
<channel name="ee" stack="tcpping" cluster="ejb"/>
</channels>
<stacks>
<stack name="tcpping">
<transport type="TCP" socket-binding="jgroups-tcp"/>
<protocol type="org.jgroups.protocols.TCPPING">
<property name="initial_hosts">
node1[7600], node2[7600]
</property>
</protocol>
<protocol type="MERGE3"/>
<protocol type="FD_SOCK"/>
<protocol type="FD_ALL"/>
<protocol type="VERIFY_SUSPECT"/>
<protocol type="pbcast.NAKACK2"/>
<protocol type="UNICAST3"/>
<protocol type="pbcast.STABLE"/>
<protocol type="pbcast.GMS"/>
<protocol type="MFC"/>
<protocol type="FRAG2"/>
</stack>
</stacks>
</subsystem>
在应用程序启动时,我从数据库中加载所有实体并放入缓存中。 如果我以这种方式通过容器注入缓存:
@Resource(lookup="java:jboss/infinispan/mycache-container")
EmbeddedCacheManager container;
@PostConstruct
public void init()
Cache mycache = container.getCache();
应用程序启动并加载缓存中的所有对象都没有问题,但在其他节点中,这些对象也不会被复制,因此 jgroups 集群是在没有错误的情况下创建的。 相反,如果我以这种方式直接注入缓存:
@Resource(lookup="java:jboss/infinispan/mycache-container/my-cache")
Cache myCache;
启动中的应用程序给我这个错误: "WFLYCTL0348:等待服务容器稳定[300]秒后超时。操作将回滚。第一次更新服务的步骤;服务器未启动"
我应该如何使用缓存来防止启动超时并能够在所有节点上复制该对象?
谢谢。
【问题讨论】:
你试过打电话给container.getCache("my-cache");
吗?
是的,但我得到了相同的结果
【参考方案1】:
第一种方法不能按预期工作的原因是因为您没有做任何事情来确保在调用 EmbeddedCacheManager.getCache() 之前安装了必要的缓存配置。
为确保安装了必要的缓存配置,您可以:
-
直接注入缓存(就像您在第二种方法中所做的那样)
通过@Resource 或resource-ref 将必要缓存配置的依赖项添加到您的应用程序中。
我总是推荐#1,因为它更直观、更简洁,并且缓存生命周期由容器处理。
至于“超时 [...] 等待容器稳定性”的原因,如果没有看到将对象加载到缓存中的代码以及相关的堆栈跟踪,我不能肯定地说。只是一个猜测 - 你确定你的交易模式是 NON_XA 吗?这意味着缓存操作通过同步提交到活动的 UserTransaction。这不是一个常见的要求。如果您在 @PostConstruct 方法中加载缓存,并且没有正确处理事务,这可能会阻止您的组件启动(导致等待容器稳定性超时)。
另外,我建议使用未弃用的 TCPPING 配置。例如
<socket-discovery-protocol type="TCPPING" socket-bindings="node0 node1"/>
...其中套接字绑定引用配置的出站套接字绑定。 例如
<outbound-socket-binding name="node0">
<remote-destination host="node0" port="7600"/>
</outbound-socket-binding>
<outbound-socket-binding name="node1">
<remote-destination host="node1" port="7600"/>
</outbound-socket-binding>
【讨论】:
感谢保罗,您的回答。我解决了启动问题并直接恢复了缓存,现在我可以复制数据了。我还必须将事务模式从 NON_XA 更改为 NONE @Paul,您的意思是“我总是推荐 #2,因为它更直观,更简洁......”? 为了澄清,我推荐选项 #1,直接注入缓存(即 1 个依赖项);而不是选项#2,注入缓存管理器并添加对必需缓存配置的第二个依赖项。使用选项#1,缓存生命周期由容器处理,而使用选项#2,应用程序必须管理缓存生命周期。 Conainer 托管生命周期非常方便,尤其是当多个应用程序使用同一个托管缓存时。 @Paul,我现在直接注入缓存,但是缓存的性能(r/w)比我从容器注入的速度要慢。我可以做些什么来提高性能? 您的观察具有欺骗性。您在“从 [the] 容器中注入 [ing]”时看到的性能将返回本地缓存(即使用 infinispan 的默认设置),而不是您期望的复制缓存。复制缓存自然比本地缓存慢得多(这只是哈希映射)。以上是关于使用 Wildfly 11 复制的 infinispan 缓存的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Wildfly Standalone-full-ha 中使用复制的 Infinispan 缓存
在 Wildfly 9 上部署 EAR 具有原始 WAR 和复制 WAR