com.alibaba.dubbo.remoting.RemotingException: java.lang.NoClassDefFoundError問題排查

記一次有意思的dubbo服務調用java.lang.NoClassDefFoundError問題排查,儘管如今還不清除具體原理是什麼,可是問題已經解決。java

背景

  1. 這是一個新的項目,從新搭建開發環境,以及運維部署docker環境,jdk採用1.8。
  2. 項目啓動正常,沒有任何錯誤日誌,日誌級別調成DEBUG級別也未發現問題。

異常出現

具體異常docker

cause: java.lang.NoClassDefFoundError: org/apache/commons/lang/StringUtils
java.lang.NoClassDefFoundError: org/apache/commons/lang/StringUtils
        at net.dubboclub.catmonitor.CatTransaction.createProviderCross(CatTransaction.java:187)
        at net.dubboclub.catmonitor.CatTransaction.invoke(CatTransaction.java:55)
        at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:69)
        at com.alibaba.dubbo.rpc.filter.ContextFilter.invoke(ContextFilter.java:61)
        at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:69)
        at com.alibaba.dubbo.rpc.filter.GenericFilter.invoke(GenericFilter.java:132)
        at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:69)
        at com.alibaba.dubbo.rpc.filter.ClassLoaderFilter.invoke(ClassLoaderFilter.java:38)
        at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:69)
        at com.alibaba.dubbo.rpc.filter.EchoFilter.invoke(EchoFilter.java:38)
        at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:69)
        at com.alibaba.dubbo.rpc.protocol.dubbo.DubboProtocol$1.reply(DubboProtocol.java:98)
        at com.alibaba.dubbo.remoting.exchange.support.header.HeaderExchangeHandler.handleRequest(HeaderExchangeHandler.java:98)
        at com.alibaba.dubbo.remoting.exchange.support.header.HeaderExchangeHandler.received(HeaderExchangeHandler.java:170)
        at com.alibaba.dubbo.remoting.transport.DecodeHandler.received(DecodeHandler.java:52)
        at com.alibaba.dubbo.remoting.transport.dispatcher.ChannelEventRunnable.run(ChannelEventRunnable.java:81)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:745) 
複製代碼

這個異常拋出在dubbo服務調用方,也就是消費者端,起初覺得是消費者端缺乏commons-lang:2.6.jar致使,排查發現這個jar包確實是存在的!!!可是爲何會報這個異常呢?apache

本地調試

經過本地idea啓動生產者與消費者,採用直連的方式dubbo://localhost:20881,發現服務居然可以正常提供服務!!!What's up?bash

運維改變部署環境

本地啓動可以正常提供服務,那是否是運維新建的環境有問題呢?It's possible.服務器

  1. 是否是打包出現了問題? 辛苦運維大哥將服務器上打包的項目拿下來,將服務器端服務kill,在本地啓動從新註冊到zk上,本地啓動消費者(由於網絡限制策略,開發部署環境不能鏈接本機服務),服務並無出現異常,而是正常提供服務!!!
  2. 運維開始懷疑是否是本身新建環境有問題了?? 將項目打的包拷貝至宿主機使用java -jar project.jar運行,經過dubbo-admin觀察,發現服務註冊成功,測試調用發現服務也是正常!!!
  3. 惟一有問題的就是將服務部署在新的docker環境了。。。 經過以上2種排查,那剩下的惟一有問題只能是服務+環境
    1. 檢查docker環境的jdk環境、classpath環境,均發現正常沒有問題。
    2. 檢查服務與消費者的網絡,發現也是正常沒有問題。
    3. 誰能告訴我,這個究竟是怎麼啦???
  4. 網絡搜索到的解決方案
    1. 缺乏jar 這個經過檢查maven依賴,打包以後的lib發現jar包確實很多
    2. javassist版本不對 有網友說是由於javassist的版本不對致使,經過消費者lib包發現,項目中確實存在兩個版本的javassist,以下圖,請運維將低版本的刪除,而後啓動,發現服務依舊是不行~~~~ 能試的,我都試了,爲何你要這麼折磨我這個小菜逼,ಥ_ಥ
      image.png
  5. 在服務中寫個JUnit測試類,經過dubbo引用服務端的服務吧~ 在本地寫了一個JUnit測試類,經過<dubbo:reference id="${serverId}" interface="${serviceInterfaceClass}" version="${version}" group="${group}" url="dubbo://${ip}:${port}"/>直連提供者,終於出現了一樣的錯誤~,😂,儘管仍是不知道怎麼解決,可是出現了總比不出現要好,對於bug就是這個樣子的。。。
  6. 檢查服務提供者的jar依賴 發現服務提供者的maven依賴並無
<dependency>
    <groupId>commons-lang</groupId>
    <artifactId>commons-lang</artifactId>
    <version>2.6</version>
</dependency>
複製代碼

會不會就是這個錯誤呢?有可能的哦!儘管不是很肯定,但仍是要搞一搞~ 將這個依賴添加上,從新打包部署,好期待奇蹟出現哦~ 運行JUnit測試類,What?! 果真奇蹟出現了,居然沒有錯誤了!服務呢?是否也正常了?Yes! 服務也正常了!!!網絡

總結

致使這個錯誤的緣由是由於服務提供者沒有提供commons-lang:2.6的依賴包,致使了運行時出錯,可是這個異常確拋在了消費端,讓人一時懵逼覺得真的是由於消費者出現了錯誤! 經過異常堆棧發現,使用StringUtils工具類的是 cat-dubbo-monitor ,項目使用cat監控dubbo服務狀態。 至於爲何這個錯誤會出如今消費者端,而不是生產者端,具體緣由還不知道,還請只到的大牛可以給指點一下,很是感謝!!app

相關文章
相關標籤/搜索