日期:2014-05-16  浏览次数:20385 次

tomcat集群环境下,JSP页面更新同步,页面展示未更新 的问题排查

背景:

企业环境下使用域名轮询 + 多台tomcat 来平衡负载,tomcat之间共享数据库,因为没用到session所以并没有做tomcat集群的配置。多个tomcat之间会使用rsync文件同步来同步工程文件,举例说来就是,用一台服务器作为主服务器,一旦主服务器上的jsp文件更新那么会定时同步到其他服务器上去。

问题描述:

主服务器上jsp页面更新,主服务器访问页面更新生效,从服务器访问页面没有更新。

问题猜想1:

更新没有生效首先就怀疑页面文件同步出了问题。

问题排查1:

主从服务器上取下页面文件进行对比,发现页面文件无差异,但是通过tomcat显示出来的页面就是没更新。

问题猜想2:

tomcat在更新jsp之后没有及时编译jsp文件为class,导致页面访问效果没有更新。

问题排查2:

进入到tomcat的work目录下面,将主从服务器的页面编译后的java和class文件做了比较,发现不一致,问题果然出在这里。

那么为什么jsp页面更新了之后tomcat没有检测到更新并且自动更新编译成java或者class呢?

结论:

首先,我们确定配置了<Context reloadable="true">,tomcat会去检测jsp的更新重新编译。

然后,再深入一点了解tomcat的检测机制,我们发现,tomcat是这么做的:

tomcat是根据文件的更新日期判断jsp文件是不是比现有的编译好的.java文件新来决定是否重新编译。(这个来源于资料,没有验证:http://daidalei321.iteye.com/blog/909999)

那么极有可能问题就出在这里,查看了下发现主从服务器的时间果然没有同步,从服务器比主服务器快了几分钟。假设从服务器比主服务器快了10分钟,这样的话就可能发生如下的过程:

主服务器 : 时间00:00(新增Jsp文件) -> 时间00:01(更新jsp文件,文件更新时间戳为00:01)

从服务器 : 时间00:10(同步得JSP,编译class时间戳为00:10) -> 时间00:11(得到更新的jsp文件更新时间戳为00:01比本地编译的class00:10晚,判断为不更新)

于是乎杯具产生了。

所以这种情况下的解决办法就是同步主从服务器系统时间。