一个Spring定时器引发的血案!

时间:2021-09-15 20:48:13
不知道从哪说起,应该说相关问题由来已久,只是现在到了不得不处理的时候。
很传统的tomcat服务器,下面有四个项目,这段时间老是报permgen space异常,据史料记载, 这块内存主要是被JVM存放Class和Meta信息的,要说meta占用太多空间不切实际,意思是class创建太多?这让我联想到貌似spring管理的bean是被实例化多次的!!看来跟spring有关系,是spring的配置问题??
进一步搜索资料发现,对此问题的描述与解决主要有两个版本:
一、Spring的配置文件 applicationContext.xml由于web.xml中的配置及spring自身的扫描机制,该文件共被加载两次;
二、修改tomcat的conf目录下的server.xml。修改节点Host,将appBase属性由默认的“webapps”设置为空("")即可 。
对于第一种方案,很好说,去掉web.xml中的配置,发现applicationContext.xml并未被加载,因此不成立。
尝试第二种方案,项目不能启动,因路径错误,因为不是所有tomcat下的项目都是一个个配置,问题根本还不在这里。
不过通过查看server.xml中的配置信息,还是有收获的,注意到存在三个<Host...配置!并且 docBase都是从webapps开始,到此为止,我还不能完全知道这意味着什么!删去一个<Host ..配置,重启tomcat,效果马上出现了:spring定时器只执行两次,比之前少一次!!这下知道三个<Host...配置意味着什么了----由于docBase为webapps,那webapps下所有的项目都被tomcat容器加载了三次!!这样看来,创建了太多了class导致Permgen space也不足为怪了。
经过短暂考虑,最终配置于下:
由于有两个不同的域名指到不同的项目,因此至少需要存在两个<Host>配置,主域名下所有项目配置到docBase=webapps下,另一个域名指定的项目docBase指定到其根目录下,至此,webapps下的项目只会被加载一次,由此带来内在的消耗与性能的提高,自然是巨大的!
结果观察,之前所有疑问都已释然,所有问题都被解决!
当然,内存消耗还有进一步减小的可能:每个项目单独配置<Host> 信息,对于项目多的可能麻烦些。
如图,通过几次对server.xml的修改,服务器的启动时间从63秒缩减到26秒,spring定时器也只会执行一次了。


一个Spring定时器引发的血案!

一个Spring定时器引发的血案!

一个Spring定时器引发的血案!

综观所有,一系列问题并不是由spring引起,单单讨论技术是没有意义的,重要的是在对服务器整体配置不了解的情况下怎么找到问题根本原因,如果是spring本身的原因,通过设置静态变量来标识也没有用,说明问题的层次不在程序级,而应该在更上一级:服务器级!如何分析问题找问题才是这个日志记录的意义所在。