跨多个应用程序同步Apache负载均衡器数据

3
我有一个设置,其中两个相同应用程序的实例部署在负载均衡器后面,并且这两个应用程序都与同一个数据库交互。
我遇到的问题是,当通过其中一个应用程序将数据插入数据库时,另一个应用程序无法访问/查看完全相同的数据。
这两个应用程序在数据库抽象框架、Spring框架等方面具有完全相同的配置。此外,这两个应用程序在不同的物理服务器上运行不同的Tomcat服务器。
可能导致这个问题的原因是什么?
编辑
Hibernate的配置如下:

enter image description here

编辑2

这是ehcache.xml文件

<cache name="org.hibernate.cache.internal.StandardQueryCache"
       maxElementsInMemory="10000"
       eternal="false"
       timeToLiveSeconds="86400"
       overflowToDisk="false"
       memoryStoreEvictionPolicy="LRU"/>

<defaultCache
        maxElementsInMemory="10000"
        eternal="false"
        timeToLiveSeconds="86400"
        overflowToDisk="false"
        memoryStoreEvictionPolicy="LRU"/>

你的开发环境中有ORM吗?用的是哪个?如果有,你是如何配置它的缓存行为的? - Tasos P.
@Cascader 是的,使用了Hibernate。我已经用一张截图更新了问题。 - user6332430
请问您能否包含您的 echache.xml 文件? - Tasos P.
3个回答

2

您很可能遇到了缓存复制问题,可能是由于缺少/不正确的缓存协调配置引起的。

假设

您已在Hibernate中启用了二级缓存和查询缓存,这是可以的,您获得了性能提升。问题在于您使用了两个节点,每个节点都有自己的缓存,或者它们没有正确地使缓存失效。

例如,节点A执行所有实体Z的查询(即产品类别列表:Z1、Z2等),并缓存结果。稍后,节点B添加了一个新的产品类别实体Zn。在其自己的缓存失效之前,节点A将不使用该新实体;在此之前,它将使用不包括Zn的缓存结果集。

如果您禁用查询缓存(即设置<property name="hibernate.cache.use_query_cache">false</property>),则可以验证此假设。

解决方案

优化缓存失效。这在很大程度上取决于您的业务需求,但一些建议如下:

  • 为某些查询减少缓存TTL,直到找到一个最佳点(您可以容忍缺少/多余值的时间跨度)。您可以使用EhCache区域来实现。
  • 对于某些实体,完全禁用缓存

例如:

ehcache.xml中创建一个短暂(即5分钟)查询结果区域:

<cache name = "short-lived"
maxElementsInMemory = "500"
eternal = "false"
timeToIdleSeconds = "600"
timeToLiveSeconds = "600"
overflowToDisk = "false"
/>

对于需要经常刷新的特定查询:

Query query = session.createQuery("FROM Z");
query.setCacheable(true);
query.setCacheRegion("short-lived");

关于这个主题,点击此处了解更多信息。

这是一个真正的解决方案。您可以为所有节点设置一个共享缓存。尽管它的设置和配置肯定更困难,但它可以提供最佳性能。例如,缓存查询将在整个集群中运行一次,而不是像现在这样每个节点都要运行一次。

请查看Terracotta


0

有不同类型的可能导致此问题。

1)检查数据库访问权限。还要检查您的应用程序是否能够将数据提交到数据库中。您需要调试不同的情况

  1. 从cluster_1插入数据,然后尝试从cluster_2读取相同的数据
  2. 以不同的顺序重复步骤1
  3. 在SQL数据库中检查插入数据时是否存在任何差异(所有者信息、对象版本)。

2)您可以在(Clustering/Session Replication How-To)中创建一个tomcat服务器集群。


0

你的应用程序中是否有与数据库通信的ORM?

我猜是有的,所以这是我的答案:

每个应用程序都有自己的ORM缓存机制(如Hibernate)。如果其中一个更改了数据,则更改将反映在其缓存中,但另一个则不知道DB中的任何更改。您可以执行以下操作之一:

  1. 在应用程序中禁用ORM缓存(最快的解决方案)
  2. 使用另一个应用程序包装DB,作为模型层+缓存服务器
  3. 创建消息系统以广播实例之间的更改事件,并在触发器的情况下更新缓存。(虽然不是一个好主意)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接