使用Ehcache缓存同步启动时抛出异常net.sf.ehcache.CacheException: Can't assign requested address

问题:在使用Ehcache缓存,采用RMI(UDP传输协议)进行数据广播同步,启动项目时报异常: net.sf.ehcache.CacheException: Can’t assign requested address

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'cacheManagerFactory' defined in class path resource [app-ehcache.xml]: Invocation of init method failed; nested exception is net.sf.ehcache.CacheException: Can't assign requested address
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1553)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:304)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:328)
    ... 128 more
Caused by: net.sf.ehcache.CacheException: Can't assign requested address
    at net.sf.ehcache.distribution.MulticastRMICacheManagerPeerProvider.init(MulticastRMICacheManagerPeerProvider.java:99)
    at net.sf.ehcache.CacheManager.doInit(CacheManager.java:479)
    at net.sf.ehcache.CacheManager.init(CacheManager.java:395)
    at net.sf.ehcache.CacheManager.<init>(CacheManager.java:270)
    at net.sf.ehcache.CacheManager.newInstance(CacheManager.java:1116)
    at net.sf.ehcache.CacheManager.newInstance(CacheManager.java:1092)
    at net.sf.ehcache.CacheManager.create(CacheManager.java:1075)
    at org.springframework.cache.ehcache.EhCacheManagerFactoryBean.afterPropertiesSet(EhCacheManagerFactoryBean.java:148)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1612)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1549)
    ... 135 more
配置信息如下:
<!-- 瞬时缓存,用于缓存时间较短的中间缓存 add by xubiao-->
    <cache name="instantCache" eternal="false"
           maxElementsInMemory="10000" overflowToDisk="true" diskPersistent="false"
           timeToIdleSeconds="90" timeToLiveSeconds="30" >

        <cacheEventListenerFactory
                class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
                properties="replicateAsynchronously=true, replicatePuts=true, replicateUpdates=true,
                            replicateUpdatesViaCopy=false, replicateRemovals=true,asynchronousReplicationIntervalMillis=1000"
        />

    </cache>

    <!--缓存监听工厂-->
    <cacheManagerPeerListenerFactory
            class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"
            properties="hostName = 127.0.0.1,
                    port = 50001,
                    socketTimeoutMillis=10000" />
    <!--使用RMI机制进行广播,当前限制同一子网下访问-->
    <cacheManagerPeerProviderFactory
            class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
            properties="peerDiscovery=automatic, multicastGroupAddress=230.0.0.1,
            multicastGroupPort=4666, timeToLive=1" />
问题分析:
  • 定位:“无法分配请求地址”的异常常出现在网络分配问题上。这个问题之前在Windows电脑上使用ehcache未出现此问题。当前使用的电脑是Macbook Pro无线网络环境,网络环境使用的公司内网。防火墙处于关闭状态。网络是可以正常指配的。
调试
  • 根据异常提示,发现报错在调用heartBeatReceiver.init()创建接受器的的时候,会创建多广播socket–MulticastSocket,创建MulticastSocket时,调用NetworkInterface会静态获取默认的网络接口:
/**
     * Join the multicast group.
     * @param inetaddr multicast address to join.
     */
    protected void join(InetAddress inetaddr) throws IOException {
        join(inetaddr, null);
    }
        /**
         * required for some platforms where it's not possible to join
         * a group without setting the interface first.
         */
        NetworkInterface defaultInterface = NetworkInterface.getDefault();

        if (!interfaceSet && defaultInterface != null) {
            setNetworkInterface(defaultInterface);
        }

        getImpl().join(mcastaddr);
/**
     //静态加载默认的网络接口
     * Returns the default network interface of this system
     *
     * @return the default interface
     */
    static NetworkInterface getDefault() {
        return defaultInterface;
    }

发现的问题原因:

  • 经过调试发现,在创建心跳接受器时,调用java虚拟机,系统默认使用的网络接口是ipv6,配置的ipv4的广播端口230.0.0.1,无法join进去,所以报了无法分配请求地址的异常。如下图:
    这里写图片描述

  • 解决办法:在启动服务时,指定使用默认ipv4的网络接口。可以在启动jvm时添加参数-Djava.net.preferIPv4Stack=true。
    这里写图片描述

猜你喜欢

转载自blog.csdn.net/m0_37113539/article/details/82461856