暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Ehcache缓存同步启动时Can't assign requested address异常分析

一步一步似爪牙 2018-09-06
1008

问题:在使用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 moreCaused 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。


文章转载自一步一步似爪牙,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论