带有 Infinispan 和 JBoss EAP 7.0.6 的休眠 L2C 不工作
Posted
技术标签:
【中文标题】带有 Infinispan 和 JBoss EAP 7.0.6 的休眠 L2C 不工作【英文标题】:Hibernate L2C with Infinispan and JBoss EAP 7.0.6 is not working 【发布时间】:2018-02-01 01:22:23 【问题描述】:我有一个使用 Hibernate 5.0.9.Final 的应用程序部署到 JBoss EAP 7.0.6(默认使用 Infinispan 8.0.1.Final)。必须缓存几个实体,它们使用 JPA 的 @Cacheable
和 Hibernate 的 @Cache
进行注释,以提供每个实体的缓存策略。
代码库包含一个简单的测试,它检查 Infinispan 在本地与测试用例一起运行并直接访问数据源,也就是说,两者之间没有 JBoss EAP,也没有 Arquillian 测试。测试成功运行,我可以看到在可用时从缓存中获取实体。
现在将应用程序部署到 JBoss EAP 并运行会导致负面体验。我可以在日志中看到 Infinispan 缓存实体。我还可以在 JBoss Web 控制台上看到缓存统计信息。当一个应该导致缓存命中计数的查询被执行时,结果是没有命中计数发生,而是查询命中了数据源。
更新: 已使用 persistence.xml
中的适当属性启用了休眠和 infinispan 统计信息; L2C 和查询缓存也是如此。区域工厂设置为JndiInfinispanRegionFactory
,如http://infinispan.org/docs/8.0.x/user_guide/user_guide.html 中所述。此外,所有执行的查询都是 JPQL 查询。据我所知,告诉 Infinispan 和 JBoss AS/7 使用他们的默认配置。
更新 2: JBoss 服务器实际上是 EAP 7.0.6,而不是前面所述的 AS/7。
目前我们无法升级到更新版本的 JBoss EAP(恐怕现在还没有 Wildfly)。
顺便说一句,尝试在本地运行 EhCache 是成功的,但在 JBoss EAP 中运行会由于模块问题导致 CNFE。
persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="DefaultUnit" transaction-type="JTA">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<jta-data-source>java:/MyDataSource</jta-data-source>
<class>...</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.DB2Dialect" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.connection.datasource" value="java:/MyDataSource"/>
<property name="hibernate.generate_statistics" value="true" />
<property name="hibernate.cache.infinispan.statistics" value="true"/>
<property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.JBossTransactionManagerLookup"/>
<property name="hibernate.cache.use_second_level_cache" value="true" />
<property name="hibernate.cache.use_query_cache" value="true" />
<property name="hibernate.cache.region.factory_class" value="org.hibernate.cache.infinispan.JndiInfinispanRegionFactory"/>
<property name="hibernate.cache.infinispan.cachemanager" value="java:jboss/infinispan/container/hibernate"/>
</properties>
</persistence-unit>
</persistence>
standalone.xml 这个块定义了休眠容器
<cache-container name="hibernate" default-cache="local-query" module="org.hibernate.infinispan">
<local-cache name="entity">
<transaction mode="FULL_XA"/>
<eviction strategy="LRU" max-entries="10000"/>
<expiration max-idle="100000"/>
</local-cache>
<local-cache name="local-query">
<eviction strategy="LRU" max-entries="10000"/>
<expiration max-idle="100000"/>
</local-cache>
<local-cache name="timestamps"/>
</cache-container>
【问题讨论】:
Andres,您的部署中是否包含 Infinispan 和/或 Hibernate jar?只是想知道是否使用了错误的东西。另外,我认为您使用的 persistence.xml 配置是错误的。查看EAP 7 documentation,其中详细说明了用于启用 Infinispan 2LC 的属性。 特别是,仅使用文档说明的属性并删除区域工厂定义。这当然是假设您使用的是 EAP 提供的 Hibernate 和 Infinispan 版本... 查看 here 以获取去除配置中多余元素的 persistence.xml。 Galder,Hibernate 被设置为提供范围内的依赖项。 Infinispan 未定义为生产依赖项,因为它预计是 EAP 的内部设置。 Infinispan 仅设置为测试依赖项。 好的,那么您绝对应该按照要点所示配置持久性 XML。我们现有的 EAP 粘合代码为您完成了所有艰苦的工作。 【参考方案1】:当一个应该导致缓存命中计数的查询被执行时,它 结果没有发生命中计数并且查询命中数据源 而是。
当您说查询时,您是指 JPQL 查询还是 Criteria API?
实体查询旨在通过实体标识符直接获取。对于查询,您还需要查询缓存,但不清楚这是否是您所需要的。
此外,如果未启用统计信息,则命中计数可以为 0:
与 Hibernate Core 相关的hibernate.generate_statistics
之一
或者,hibernate.cache.infinispan.statistics
,代表 Infinispan
找出发生了什么的一种方法是调试DefaultLoadEventListener#doLoad
方法:
entity = loadFromSecondLevelCache( event, persister, keyToLoad );
看看为什么它不能从 Infinispan 获取。
更新:
此外,所有执行的查询都是 JPQL 查询。
您是否启用了查询缓存?
请注意,查询缓存使用单个区域,因此一旦您添加/删除/修改属于该表空间的任何单个条目,所有使用某个表空间的查询结果都会被清除。
如果您在尝试加速 JPQL 时依赖实体 2 级缓存而不使用查询缓存,那么它的工作效率将低于没有 2 级缓存的情况。那是因为 JPQL 无论如何都会执行 SQL 查询,因此您只需丢弃结果并转到缓存以通过其 id 获取实体。如果在缓存中找不到实体,这实际上会变得非常糟糕,这意味着将发出过多的辅助查询。
如果您在执行读写事务时尝试卸载主节点,则二级缓存非常有意义。对于只读查询,只需使用数据库复制并将负载分散到多个副本上,这些副本的缓冲池配置为将整个工作集存储在 RAM 中。
【讨论】:
感谢弗拉德,我在问题中添加了更多细节。基本上我们遵循 infinispan.org/docs/8.0.x/user_guide/user_guide.html 并启用了 Hibernate 和 Infinispan 的统计信息。 是的,查询缓存已启用。我们正在测试设置缓存的水域,因此目前使用单个区域。 对于查询缓存,只有一个区域:StandardQueryCache。我不认为 Hibernate 可以为查询缓存使用更多的查询结果区域。【参考方案2】:我强烈建议避免这种组合:
JBoss AS7 陈旧到无法与 Java 8 完全兼容的地步 Infinispan 8 需要 Java 8由于您声明您无法升级到 WildFly(即将推出 11 个!),因此您落后了近 4 个主要版本:这是很多缺失的错误修复和改进,但在您的几代库中也存在显着差异'重新组合。
我建议:
坚持使用 Ehcache 坚持使用应用服务器中包含的旧版本 Hibernate ORM WildFly 11 更新 :-) 获取受支持的 JBoss EAP 7.x对于 EAP 的商业参考,我深表歉意,但它可能是一个很好的解决方案,具体取决于您无法升级到 WildFly 的原因,因为它本质上是结合了更高版本(尤其是向后移植的兼容性修复)和严格的 API 向后兼容性政策。
关于 Ehcache 让您在模块方面遇到麻烦,我很乐意为您提供帮助。模块系统很棒,我相信这可能很容易解决,但作为不同的问题/论坛处理可能会更好。
【讨论】:
知道了。 EhCache 主题发布于***.com/questions/45841056/… 顺便说一下,我们使用的实际 JBoss 版本是 7.0.6 EAP ;-)【参考方案3】:persistence.xml 配置不正确。部署到 EAP 时,只需这样做:
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="DefaultUnit" transaction-type="JTA">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<jta-data-source>java:/MyDataSource</jta-data-source>
<class>...</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.DB2Dialect" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.connection.datasource" value="java:/MyDataSource"/>
<property name="hibernate.generate_statistics" value="true" />
<property name="hibernate.cache.infinispan.statistics" value="true"/>
<property name="hibernate.cache.use_second_level_cache" value="true" />
<property name="hibernate.cache.use_query_cache" value="true" />
</properties>
</persistence-unit>
</persistence>
通过定义您自己的区域工厂,您可能会冒着不使用由您正在检查统计信息的 EAP 管理的实际 Infinispan 实例的风险。
查看EAP 7 documentation 了解更多信息。
【讨论】:
以上是关于带有 Infinispan 和 JBoss EAP 7.0.6 的休眠 L2C 不工作的主要内容,如果未能解决你的问题,请参考以下文章
JBoss EAP 6.4 Infinispan 集群缓存网络问题
为啥休眠 5.3 不支持带有 infinispan 的事务缓存
带有 websocket 和 stockjs 的 JBOSS eap 6.3 beta - 使用 spring 框架的 stomp.js