You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Grails 2.4.5多节点Ehcache缓存复制失效问题求助

多节点缓存不一致与RMI复制失效排查方案

一、先处理RMI复制的SocketException(Broken pipe)

该错误直接指向RMI通信链路中断,优先从连通性和配置入手:

  • 验证RMI端口连通性:
    在应用内执行以下Groovy脚本,确认两台节点的RMI监听端口能互相访问:
    def testRmiConnectivity(String targetIp, int port) {
        def socket = new Socket()
        try {
            socket.connect(new InetSocketAddress(targetIp, port), 5000)
            return "节点${targetIp}:${port}连通成功"
        } catch (Exception e) {
            return "节点${targetIp}:${port}连通失败: ${e.message}"
        } finally {
            socket.close()
        }
    }
    // 调用示例:testRmiConnectivity("192.168.1.100", 40001)
    
    若连通失败,说明防火墙/安全组阻断了端口,需联系运维开放;若连通成功,继续排查配置问题。
  • 调整RMI超时配置:
    在ehcache配置中延长连接超时时间:
    <cacheManagerPeerListenerFactory
        class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"
        properties="port=40001, socketTimeoutMillis=30000"/>
    
    同时可尝试添加JVM启动参数:-Dsun.rmi.transport.tcp.responseTimeout=30000(若允许修改Tomcat启动参数)。
  • 检查RMI端口绑定状态:
    查看应用启动日志,确认RMI监听端口是否绑定成功,是否存在Address already in use这类端口占用报错。

二、校验ehcache分布式复制配置

  • 确认缓存复制开关:
    检查每个需要同步的缓存节点,是否配置了RMICacheReplicatorFactory并开启必要复制规则:
    <cache name="yourCacheName" maxEntriesLocalHeap="10000" eternal="false" timeToIdleSeconds="3600" timeToLiveSeconds="7200">
        <cacheEventListenerFactory 
            class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
            properties="replicatePuts=true, replicateUpdates=true, replicateRemovals=true, replicateUpdatesViaCopy=true"/>
    </cache>
    
  • 检查Peer节点配置:
    若为手动指定Peer节点,确认cacheManagerPeerProviderFactory的peerList包含两台节点的完整RMI地址:
    <cacheManagerPeerProviderFactory
        class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
        properties="peerDiscovery=manual, peerList=rmi://node1-ip:40001/cacheManagerPeer,rmi://node2-ip:40001/cacheManagerPeer"/>
    
    若为自动发现模式(peerDiscovery=automatic),确认两台节点在同一广播域,组播地址(默认230.0.0.1:4446)配置正确。
  • 核对依赖版本兼容性:
    本地执行grails dependency-report,确认grails-cache-ehcache1.0.101依赖的ehcore版本与Grails2.4.5的适配性,避免版本冲突导致RMI协议不兼容。

三、排查应用层缓存操作逻辑

  • 校验缓存Key一致性:
    在缓存读写逻辑处添加日志,打印生成的缓存Key,对比两台节点的日志,确认同一业务数据生成的Key完全一致(避免因本地变量、节点标识导致Key差异)。
  • 检查缓存失效同步:
    确认缓存失效操作(如cacheEvict)是否触发了RMI复制,若失效逻辑仅在本地执行,会导致节点间缓存状态不一致。

四、临时替代方案

若RMI问题无法快速解决,可采用以下方案规避:

  • 切换集中式缓存:替换ehcache分布式实现为Redis,通过grails-cache-redis插件实现全节点共享缓存,从根源解决一致性问题。
  • 缩短缓存过期时间:给缓存设置较短的TTL(比如30分钟),缩小数据不一致的窗口;或在写操作后,通过HTTP接口主动触发其他节点的缓存失效。

内容的提问来源于stack exchange,提问作者Axel Kouassi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 23:10:43