1、问题描述
某个版本推生产后,各个域的tomcat均启动不成功。后台日志报spring初始化bean失败。测试、生产环境使用相同版本的tomcat、jdk、工程代码,都可以正常启动。
tomcat版本:apache-tomcat-7.0.54
jdk版本:jdk1.6.0_38
错误日志如下:
2015-03-11 14:32:16,437 [localhost-startStop-1] ERROR [org.springframework.web.context.ContextLoader] - Context initialization failed
java.lang.NoClassDefFoundError: org.springframework.beans.FatalBeanException
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:529)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:296)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:293)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:198)
at org.springframework.context.support.AbstractApplicationContext.registerBeanPostProcessors(AbstractApplicationContext.java:753)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:464)
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:410)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:306)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:112)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4973)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5467)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1559)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1549)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
Mar 11, 2015 2:32:16 PM org.apache.catalina.core.StandardContext startInternal
SEVERE: Error listenerStart
Mar 11, 2015 2:32:16 PM org.apache.catalina.core.StandardContext startInternal
SEVERE: Context [/] startup failed due to previous errors
2、解决方法
经分析,为JVM内存参数设置问题,-Xss参数设置值过小,导致工程启动失败。
1)、生产catalina.sh文件中的jvm内存设置为:
JAVA_OPTS="$JAVA_OPTS -Xmx8192m -Xms8192m -Xmn4g -Xss256k -XX:ParallelGCThreads=24 ....
2)、-Xss 值的默认值是1m,在测试、开发环境没添加该参数,使用默认的1m,所以没出现问题。
3)、生产环境去掉-Xss配置,问题解决,项目成功上线。
3、分析过程
1)、将生产的环境的tomcat、jdk部署到测试环境上,发现可以重现问题。初步定位为tomcat的配置问题。
2)、分别比较生产和测试环境tomcat的bin、conf目录,发现bin目录下的catalina.sh文件的中,生产环境的jvm参数配置与测试环境的不一致。配置如下:
JAVA_OPTS="$JAVA_OPTS -Xmx8192m -Xms8192m -Xmn4g -Xss256k -XX:ParallelGCThreads=24 ....
3)、将生产的jvm配置覆盖到测试tomcat中,启动时出现同样的异常。这一步确认问题出在JVM参数配置上。
4)、排除法逐个测试JVM的参数,最后定位到-Xss参数配置存在问题。
5)、-Xss参数说明(摘自网络)
设置每个线程的堆栈大小。JDK5.0以后每个线程堆栈大小为1M,以前每个线程堆栈大小为256K。根据应用的线程所需内存大小进行调整。在相同物理内存下,减小这个值能生成更多的线程。但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在3000~5000左右。
4、TIPS
推荐一款文件比较工具:Beyond Compare 2,比较文件夹时,需将“比较内容”设置为“二进制比较”。