關於ActiveMQ+Zookeeper做集群時,解決啟動報錯:java.io.IOException: com/google/common/util/concurrent/internal/InternalFutureFailureAccess


  這個問題我也是無意間碰到的,之前一直是使用單機的ActiveMQ,所以也沒這個問題,但是做集群時碰到這個問題,問題是這樣子出現的:

  首先,我准備了三台虛擬機,然后使用 Replicated LevelDB 的方式配置集群,配置如下:  

        <persistenceAdapter>
            <!--<kahaDB directory="${activemq.data}/kahadb"/>-->
            <replicatedLevelDB
               directory="${activemq.data}/leveldb"
               replicas="3"
               bind="tcp://0.0.0.0:61619"
               zkAddress="192.168.209.133:2181,192.168.209.134:2181,192.168.209.135:2181"
               zkPath="/activemq"
               hostname="test3"
             />
        </persistenceAdapter>

  之后使用 ./activemq console 命令將三個虛擬機中的ActiveMQ成功啟動。

  接着我斷開master節點,發現剩下兩台slave節點會自動選舉一個成為master節點,再把原來的master節點啟動,就相當於一個新的slave節點加入了集群。

  這樣子,我以為集群就是好的了,然后寫代碼,發布消費,都是很正常的。然后問題就出現了。

  我在把master節點關閉,本來期望着剩下的節點能自動選一個成為master節點,可結果發現本該成為master節點的服務拋出了異常,重啟都無效,而且此時代碼也訪問不了,ActiveMQ的管理后台也訪問不了,就相當於整個集群掛了!!!

  報錯大概是這樣子的:  

    java.io.IOException: com/google/common/util/concurrent/internal/InternalFutureFailureAccess
	at org.apache.activemq.util.IOExceptionSupport.create(IOExceptionSupport.java:40)
	at org.apache.activemq.leveldb.LevelDBClient.might_fail(LevelDBClient.scala:552)
	at org.apache.activemq.leveldb.LevelDBClient.replay_init(LevelDBClient.scala:667)
	at org.apache.activemq.leveldb.LevelDBClient.start(LevelDBClient.scala:558)
	at org.apache.activemq.leveldb.DBManager.start(DBManager.scala:648)
	at org.apache.activemq.leveldb.LevelDBStore.doStart(LevelDBStore.scala:312)
	at org.apache.activemq.leveldb.replicated.MasterLevelDBStore.doStart(MasterLevelDBStore.scala:110)
	at org.apache.activemq.util.ServiceSupport.start(ServiceSupport.java:55)
	at org.apache.activemq.leveldb.replicated.ElectingLevelDBStore$$anonfun$start_master$1.apply$mcV$sp(ElectingLevelDBStore.scala:230)
	at org.fusesource.hawtdispatch.package$$anon$4.run(hawtdispatch.scala:330)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)
   Caused by: java.lang.NoClassDefFoundError: com/google/common/util/concurrent/internal/InternalFutureFailureAccess
	at java.lang.ClassLoader.defineClass1(Native Method)
	at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
	at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
	at java.net.URLClassLoader.defineClass(URLClassLoader.java:468)
	at java.net.URLClassLoader.access$100(URLClassLoader.java:74)
	at java.net.URLClassLoader$1.run(URLClassLoader.java:369)
	at java.net.URLClassLoader$1.run(URLClassLoader.java:363)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.net.URLClassLoader.findClass(URLClassLoader.java:362)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
	at java.lang.ClassLoader.defineClass1(Native Method)
	at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
	at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
	at java.net.URLClassLoader.defineClass(URLClassLoader.java:468)
	at java.net.URLClassLoader.access$100(URLClassLoader.java:74)
	at java.net.URLClassLoader$1.run(URLClassLoader.java:369)
	at java.net.URLClassLoader$1.run(URLClassLoader.java:363)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.net.URLClassLoader.findClass(URLClassLoader.java:362)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
	at java.lang.ClassLoader.defineClass1(Native Method)
	at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
	at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
	at java.net.URLClassLoader.defineClass(URLClassLoader.java:468)
	at java.net.URLClassLoader.access$100(URLClassLoader.java:74)
	at java.net.URLClassLoader$1.run(URLClassLoader.java:369)
	at java.net.URLClassLoader$1.run(URLClassLoader.java:363)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.net.URLClassLoader.findClass(URLClassLoader.java:362)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
	at com.google.common.cache.LocalCache$LoadingValueReference.<init>(LocalCache.java:3472)
	at com.google.common.cache.LocalCache$LoadingValueReference.<init>(LocalCache.java:3476)
	at com.google.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2134)
	at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2045)
	at com.google.common.cache.LocalCache.get(LocalCache.java:3951)
	at com.google.common.cache.LocalCache.getOrLoad(LocalCache.java:3974)
	at com.google.common.cache.LocalCache$LocalLoadingCache.get(LocalCache.java:4958)
	at org.iq80.leveldb.impl.TableCache.getTable(TableCache.java:90)
	at org.iq80.leveldb.impl.TableCache.newIterator(TableCache.java:78)
	at org.iq80.leveldb.impl.TableCache.newIterator(TableCache.java:73)
	at org.iq80.leveldb.impl.DbImpl.buildTable(DbImpl.java:1011)
	at org.iq80.leveldb.impl.DbImpl.writeLevel0Table(DbImpl.java:952)
	at org.iq80.leveldb.impl.DbImpl.recoverLogFile(DbImpl.java:564)
	at org.iq80.leveldb.impl.DbImpl.<init>(DbImpl.java:209)
	at org.iq80.leveldb.impl.Iq80DBFactory.open(Iq80DBFactory.java:82)
	at org.apache.activemq.leveldb.LevelDBClient$$anonfun$replay_init$2.apply$mcV$sp(LevelDBClient.scala:687)
	at org.apache.activemq.leveldb.LevelDBClient$$anonfun$replay_init$2.apply(LevelDBClient.scala:667)
	at org.apache.activemq.leveldb.LevelDBClient$$anonfun$replay_init$2.apply(LevelDBClient.scala:667)
	at org.apache.activemq.leveldb.LevelDBClient.might_fail(LevelDBClient.scala:549)
	... 11 more
   Caused by: java.lang.ClassNotFoundException: com.google.common.util.concurrent.internal.InternalFutureFailureAccess
	at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
	... 63 more

  然后花了半個小時的時間百度(Google進不去,可惜了),得到的解決方法主要有四種:

  1、移除lib目錄中的pax-url-aether-1.5.2.jar包(對我情況無效,lib目錄下沒有這個包,園友們可以試試)

  2、注釋或者刪除conf/activemq.xml中id="logQuery"的bean,它的class="io.fabric8.insight.log.log4j.Log4jLogQuery"(對我情況無效,園友們可以試試

  3、清除所有的數據,也就是刪除每個節點的上面配置的 replicatedLevelDB 節點中 directory 屬性指向的目錄 ,比如我這里就是刪除每個節點下的 data/leveldb 目錄(證實有效)

  4、換低版本的activemq試試(這個沒試)

  唯一能解決這個問題的辦法是清除所有數據,這讓我難以接受,如果哪天線上環境不小心把master節點停了,然道要清除所有數據才能重啟?這種情況誰都無法接受。

  只能自己想辦法了,看異常信息,開頭是:  

  java.io.IOException: com/google/common/util/concurrent/internal/InternalFutureFailureAccess
	at org.apache.activemq.util.IOExceptionSupport.create(IOExceptionSupport.java:40)
	at org.apache.activemq.leveldb.LevelDBClient.might_fail(LevelDBClient.scala:552)
	at org.apache.activemq.leveldb.LevelDBClient.replay_init(LevelDBClient.scala:667)
	at org.apache.activemq.leveldb.LevelDBClient.start(LevelDBClient.scala:558)
	at org.apache.activemq.leveldb.DBManager.start(DBManager.scala:648)
	at org.apache.activemq.leveldb.LevelDBStore.doStart(LevelDBStore.scala:312)
	at org.apache.activemq.leveldb.replicated.MasterLevelDBStore.doStart(MasterLevelDBStore.scala:110)
	at org.apache.activemq.util.ServiceSupport.start(ServiceSupport.java:55)
	at org.apache.activemq.leveldb.replicated.ElectingLevelDBStore$$anonfun$start_master$1.apply$mcV$sp(ElectingLevelDBStore.scala:230)
	at org.fusesource.hawtdispatch.package$$anon$4.run(hawtdispatch.scala:330)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)
     ....

  這個大致信息可以理解為,本節點在作為master節點啟動時出錯了,在 IOExceptionSupport.create()方法想創建一個對象時拋出異常,異常信息是下面的:  

  Caused by: java.lang.NoClassDefFoundError: com/google/common/util/concurrent/internal/InternalFutureFailureAccess
	at java.lang.ClassLoader.defineClass1(Native Method)
	at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
	at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
       ...
  Caused by: java.lang.ClassNotFoundException: com.google.common.util.concurrent.internal.InternalFutureFailureAccess
	at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
	... 63 more

  這個明顯是說找不到類:com.google.common.util.concurrent.internal.InternalFutureFailureAccess,那好吧,我給你去找這個類。

  於是接着百度,果然度娘最喜歡辜負了苦心人,沒有!

  這時腦子突然機靈了一下,為什么不去Maven上面找找呢?maven直通車:https://mvnrepository.com/

  然后我搜索 com.google.common.util.concurrent.internal.InternalFutureFailureAccess 這個類,果然在上面找到一個包存在這個類:

  

  進去看詳情,好家伙,這個包就兩個版本,還兩三年沒更新了,然后我選擇1.0.1版本進去,下載jar包:

  

  為避免不熟悉maven的朋友找不到,我將兩個版本的jar包都下載再來了,因為擔心每個版本依賴不一樣,大家可以從百度網盤獲取:https://pan.baidu.com/s/1T7sxBYuqqrPnyGWU4VJz9g (提取碼: mtaj )

  jar下載下來后,我將包放到每個節點ActiveMQ的lib目錄下,然后重啟每個節點,問題完美解決!!!!

  這個問題寫這么多,是因為確實度娘上的資料太少了,相信以后還有很多園友會碰到這個問題了,特此記一下!

  - - - - - - - - - - - - - - - - - - - 分割線- - - - - - - - - - - - - - - - - - -

  另外,還有一個小問題,在使用過程中,發現ActiveMQ啟動后,拋出下面的異常:An IOException was thrown (should never happen in this method).

  java.lang.RuntimeException: An IOException was thrown (should never happen in this method).
	at org.apache.activemq.leveldb.record.CollectionKey$Buffer.bean(CollectionKey.java:264)
	at org.apache.activemq.leveldb.record.CollectionKey$Buffer.getKey(CollectionKey.java:284)
	at org.apache.activemq.leveldb.LevelDBClient$$anonfun$replay_from$1$$anonfun$apply$mcV$sp$4.apply(LevelDBClient.scala:757)
	at org.apache.activemq.leveldb.LevelDBClient$$anonfun$replay_from$1$$anonfun$apply$mcV$sp$4.apply(LevelDBClient.scala:740)
	at scala.Option.map(Option.scala:146)
	at org.apache.activemq.leveldb.LevelDBClient$$anonfun$replay_from$1.apply$mcV$sp(LevelDBClient.scala:740)
	at org.apache.activemq.leveldb.LevelDBClient$$anonfun$replay_from$1.apply(LevelDBClient.scala:707)
	at org.apache.activemq.leveldb.LevelDBClient$$anonfun$replay_from$1.apply(LevelDBClient.scala:707)
	at org.apache.activemq.leveldb.LevelDBClient.might_fail(LevelDBClient.scala:549)
	at org.apache.activemq.leveldb.LevelDBClient.replay_from(LevelDBClient.scala:706)
	at org.apache.activemq.leveldb.replicated.SlaveLevelDBStore$$anonfun$send_wal_ack$1.apply$mcV$sp(SlaveLevelDBStore.scala:185)
	at org.fusesource.hawtdispatch.package$$anon$4.run(hawtdispatch.scala:330)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)
  Caused by: java.io.EOFException
	at org.fusesource.hawtbuf.proto.CodedInputStream.readRawByte(CodedInputStream.java:346)
	at org.fusesource.hawtbuf.proto.CodedInputStream.readRawVarint32(CodedInputStream.java:240)
	at org.fusesource.hawtbuf.proto.CodedInputStream.skipField(CodedInputStream.java:117)
	at org.apache.activemq.leveldb.record.CollectionKey$Bean.mergeUnframed(CollectionKey.java:172)
	at org.apache.activemq.leveldb.record.CollectionKey$Buffer.bean(CollectionKey.java:259)
	... 14 more

  雖然有這個異常,但是ActiveMQ還是能正常啟動正常使用,不過我還是有些擔心,所以就查了一下,結果發現后台跑了兩個ActiveMQ進程,殺掉再啟動還是會再啟動兩個進程,沒辦法,只好試試重啟一下機器,結果問題解決

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM