周四夜間發版,我因有事先回家,
夜間10點半,看到討論組里說zhenghe-channel工程里的channel-provider和channel-web兩個服務發版出現問題,看錯誤是Apollo導致的,后來在洲同學把apollo的jar包排除掉,又出現了新的問題,錯誤為:java.lang.IllegalArgumentException: LoggerFactory is not a Logback LoggerContext but Logback is on the classpath. Either remove Logback or the competing implementation (class org.slf4j.impl.Log4jLoggerFactory loaded from jar:file:/www/service/channel-provider/channel-provider.jar!/BOOT-INF/lib/slf4j-log4j12-1.7.25.jar!/). 而奇怪的是,本地和測驗環境是可以正常啟動服務的,不存在這個問題,時間到了午夜12點,生產環境的這個問題仍然沒有解決,鑒于本次zhenghe-channel的上線內容比較少,就先回滾了事,
周五下午,我們找時間來繼續排查這個問題,功夫不負有心人!
先說專案間的依賴關系,如下圖,zhenghe-channel工程的channel-provider和channel-web依賴了zhenghe-base工程的zhenghe-common,zhenghe-common里依賴了攜程的配置中間件Apollo和spring-cloud-context,另外,發版通過Jenkins實作程式的打包和服務的部署,測驗環境的Jenkins&maven與生產環境的Jenkins&maven在兩臺不同的機器上,

周四發版時一開始啟動服務的報錯資訊如下,這個問題是因為zhenghe-channel的這兩個服務尚未接入Apollo配置中心,在yml檔案里沒有apollo的配置,解決辦法是在pom.xml檔案里排除ctrip.framework.apollo和spring-cloud-context包,
INFO 2021-11-11 22:33:33:031 main SnifferConfigInitializer : Config file found in /opt/apache-skywalking-apm-bin-es7/agent/config/agent.config. SLF4J: Class path contains multiple SLF4J bindings. ... Exception in thread "main" java.lang.reflect.InvocationTargetException at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48) at org.springframework.boot.loader.Launcher.launch(Launcher.java:87) at org.springframework.boot.loader.Launcher.launch(Launcher.java:50) at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:51) Caused by: java.lang.IllegalArgumentException: Cannot instantiate interface org.springframework.context.ApplicationContextInitializer : com.ctrip.framework.apollo.spring.boot.ApolloApplicationContextInitializer at org.springframework.boot.SpringApplication.createSpringFactoriesInstances(SpringApplication.java:450) at org.springframework.boot.SpringApplication.getSpringFactoriesInstances(SpringApplication.java:429) at org.springframework.boot.SpringApplication.getSpringFactoriesInstances(SpringApplication.java:420) at org.springframework.boot.SpringApplication.<init>(SpringApplication.java:268) at org.springframework.boot.SpringApplication.<init>(SpringApplication.java:249) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1260) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1248) at com.emax.channel.provider.ServerApplication.main(ServerApplication.java:32) ... 8 more Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.ctrip.framework.apollo.spring.boot.ApolloApplicationContextInitializer]: Constructor threw exception; nested exception is com.ctrip.framework.apollo.exceptions.ApolloConfigException: Unable to load instance for com.ctrip.framework.apollo.spring.config.ConfigPropertySourceFactory! at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:184) at org.springframework.boot.SpringApplication.createSpringFactoriesInstances(SpringApplication.java:446) ... 15 more Caused by: com.ctrip.framework.apollo.exceptions.ApolloConfigException: Unable to load instance for com.ctrip.framework.apollo.spring.config.ConfigPropertySourceFactory! at com.ctrip.framework.apollo.spring.util.SpringInjector.getInstance(SpringInjector.java:40) at com.ctrip.framework.apollo.spring.boot.ApolloApplicationContextInitializer.<init>(ApolloApplicationContextInitializer.java:48) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:423) at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:172) ... 16 more Caused by: com.ctrip.framework.apollo.exceptions.ApolloConfigException: Unable to initialize Apollo Spring Injector! at com.ctrip.framework.apollo.spring.util.SpringInjector.getInjector(SpringInjector.java:24) at com.ctrip.framework.apollo.spring.util.SpringInjector.getInstance(SpringInjector.java:37) ... 22 more Caused by: java.lang.NoSuchMethodError: com.google.common.base.Preconditions.checkState(ZLjava/lang/String;Ljava/lang/Object;)V at com.google.common.cache.CacheBuilder.setKeyStrength(CacheBuilder.java:536) at com.google.common.cache.CacheBuilder.weakKeys(CacheBuilder.java:532) at com.google.inject.internal.WeakKeySet.<init>(WeakKeySet.java:56) at com.google.inject.internal.InheritingState.<init>(InheritingState.java:67) at com.google.inject.internal.InjectorShell$Builder.getState(InjectorShell.java:209) at com.google.inject.internal.InjectorShell$Builder.lock(InjectorShell.java:115) at com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:103) at com.google.inject.Guice.createInjector(Guice.java:99) at com.google.inject.Guice.createInjector(Guice.java:73) at com.google.inject.Guice.createInjector(Guice.java:62) at com.ctrip.framework.apollo.spring.util.SpringInjector.getInjector(SpringInjector.java:22) ... 23 moreView Code
接下來再啟動服務出現的錯誤是LoggerFactory is not a Logback LoggerContext but Logback is on the classpath. 例外堆疊如下,大致意思是,專案里的日志框架是logback,而容器啟動時發現存在log4j的LoggerFactory,例外message里提到了slf4j-log4j12-1.7.25.jar這個包,然后,我們找運維確認,發現生產環境的程式部署包的lib下果然存在這個slf4j-log4j12-1.7.25.jar,并且,將其刪掉后,服務是可以正常啟動的,
INFO 2021-11-11 22:54:30:247 main SnifferConfigInitializer : Config file found in /opt/apache-skywalking-apm-bin-es7/agent/config/agent.config. SLF4J: Class path contains multiple SLF4J bindings. SLF4J: Found binding in [jar:file:/www/service/channel-provider/channel-provider.jar!/BOOT-INF/lib/slf4j-log4j12-1.7.25.jar!/org/slf4j/impl/StaticLoggerBinder.class] SLF4J: Found binding in [jar:file:/www/service/channel-provider/channel-provider.jar!/BOOT-INF/lib/slf4j-simple-1.7.25.jar!/org/slf4j/impl/StaticLoggerBinder.class] SLF4J: Found binding in [jar:file:/www/service/channel-provider/channel-provider.jar!/BOOT-INF/lib/logback-classic-1.2.3.jar!/org/slf4j/impl/StaticLoggerBinder.class] SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation. SLF4J: Actual binding is of type [org.slf4j.impl.Log4jLoggerFactory] log4j:WARN No appenders could be found for logger (org.springframework.core.KotlinDetector). log4j:WARN Please initialize the log4j system properly. log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info. Exception in thread "main" java.lang.reflect.InvocationTargetException at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48) at org.springframework.boot.loader.Launcher.launch(Launcher.java:87) at org.springframework.boot.loader.Launcher.launch(Launcher.java:50) at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:51) Caused by: java.lang.IllegalArgumentException: LoggerFactory is not a Logback LoggerContext but Logback is on the classpath. Either remove Logback or the competing implementation (class org.slf4j.impl.Log4jLoggerFactory loaded from jar:file:/www/service/channel-provider/channel-provider.jar!/BOOT-INF/lib/slf4j-log4j12-1.7.25.jar!/). If you are using WebLogic you will need to add 'org.slf4j' to prefer-application-packages in WEB-INF/weblogic.xml: org.slf4j.impl.Log4jLoggerFactory at org.springframework.util.Assert.instanceCheckFailed(Assert.java:655) at org.springframework.util.Assert.isInstanceOf(Assert.java:555) at org.springframework.boot.logging.logback.LogbackLoggingSystem.getLoggerContext(LogbackLoggingSystem.java:286) at org.springframework.boot.logging.logback.LogbackLoggingSystem.beforeInitialize(LogbackLoggingSystem.java:102) at org.springframework.boot.context.logging.LoggingApplicationListener.onApplicationStartingEvent(LoggingApplicationListener.java:220) at org.springframework.boot.context.logging.LoggingApplicationListener.onApplicationEvent(LoggingApplicationListener.java:199) at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172) at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165) at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139) at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:127) at org.springframework.boot.context.event.EventPublishingRunListener.starting(EventPublishingRunListener.java:69) at org.springframework.boot.SpringApplicationRunListeners.starting(SpringApplicationRunListeners.java:48) at org.springframework.boot.SpringApplication.run(SpringApplication.java:302) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1260) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1248) at com.emax.channel.provider.ServerApplication.main(ServerApplication.java:32) ... 8 moreView Code
那么,顯然,問題就聚焦在slf4j-log4j12-1.7.25.jar了,是哪里依賴了它了呢?
因為在本地計算機使用maven的dependency:tree證實專案并不存在對slf4j-log4j12-1.7.25.jar的依賴,測驗環境Jenkins通過maven打包也不存在slf4j-log4j12-1.7.25.jar,并且服務能正常啟動,再加上近期對zhenghe-channel的開發并不涉及pom的改動,再加上近期各專案在逐步集成apollo配置中心,所以大家的懷疑點還是apollo,認為是apollo導致的這個錯誤,
究竟是不是呢?
答案是:否!
我將分析點定位在生產Jenkins機器上的maven倉庫,是不是有些包的版本跟本地m3或測驗環境m3不同呢,為了求證,我將maven的dependency:tree命令交給運維,運維臨時將Jenkins構建任務的clean install改成這個dependency:tree,然后執行build, 發現是一個名為cncb-pay-sdk-core依賴了slf4j-log4j12-1.7.25.jar, cncb-pay-sdk-core是zhenghe-channel里的一個module,build后是一個本地jar,并且在Jenkins上存在cncb-pay-sdk-core的構建任務, 重新構建這個cncb-pay-sdk-core任務,然后回來在構建channel-provider或channel-web時,發現服務正常啟動!那個可惡的slf4j-log4j12-1.7.25.jar終于給消滅掉了!
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/356664.html
標籤:其他
下一篇:cgb2109-day11
