关于Tomcat中defaultServlet的作用

最近在部署应用测试环境的时候遇到个问题:web工程的webapp目录下的静态资源无法访问(HTTP Code 404错误),看似很简单的一个问题,实际上是我对tomcat默认配置不足够了解的后果。

今天,在这里分享下排查的过程。

背景:

     做JSP开发时,我们都有个潜意识:web工程的webapp目录下的静态资源发布到tomcat后是可以通过在浏览器中输入uri(相对路径)来访问的。不需要额外的配置。
甚至不需要重启tomcat,因为静态资源的访问是通过文件流的方式直接读入到tomcat的JVM中,返回给浏览器的,不涉及Spring IOC容器的更新等等,所以加入静态资源后,刷新浏览器就可以看效果。
      Image

现象:

     但这次在一个新应用测试环境上,web工程中的所有静态资源均无法访问,从浏览器上看,都是404错误。
     并且更让人疑惑的是:这次部署新应用的脚本是很久以前我就写好的一个一键部署的shell脚本,已经部署过团队的很多个应用,都没有发生过类似问题。
 

排查:

     1. 为了和线上环境的尽量相似,我们测试环境的配置依然是Nginx做tomcat的反向代理,既然报404错误,首先怀疑是Nginx的配置:将请求代理到了不正确的tomcat上,简单说,请求没有到tomcat。
     所以,优先看Nginx的access.log:
      000.000.000.000 – – [09/Apr/2015:10:14:14 +0800] “GET /misc/css/jquery.qtip.css HTTP/1.1” 200 12680 “http://xxx.xxx.com/” “Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:33.0) Gecko/20100101 Firefox/33.0”
      可以看到,请求的状态码是200,这至少说明nginx将请求转到某一个tomat实例上,可能是这次的新应用,可能是老应用(但肯定是找到下游的tomat了),具体应用对不对,在检查下Nginx.conf配置:
          server{

            listen   80;
server_name xxx.xxx.com;
location /{
proxy_pass http://localhost:8103/;
}
}

     检查后发现是对的,那就是说,请求到了正确的tomcat实例。注意,这里还有一中简单的方法,就是直接在服务器上wget 一下这个uri,从而绕过nginx,直接看tomcat对不对。
 
     2. 再排查问题是否出在tomcat上,那就去看下tomcat的日志和我们的业务日志,具体来说Catalina.out只会输出tomcat在启动过程中初始化各个组件时的日志以及启动失败时tomcat本身的日志,
比如Coyote框架监听的端口,启动耗时等等。而通常导致tomcat失败的原因,比如:数据库注册失败,spring ioc容器崩溃等信息则会在localhost.log和业务日志中,所以,有问题优先看localhost.log和业务日志。
         言归正传,排查一圈后,发现各个日志都正常,tomcat启动正常(事实上,如果tomat启动失败,通过浏览器访问应用时通常会看到 502 Getway timeout的异常,即Nginx连接tomcat超时),
再仔细查看日志后,发现Catalina.out 日中中有一句:
     INFO: No default web.xml

     这句话指的是Tomcat_Home目录下的conf/web.xml文件不存在,检查应用部署环境后,确认没有改文件,重新下载tomat后,看到web.xml中配置了DefaultServlet,和JspServlet,
这两个servlet的作用分别为:为静态资源和jsp文件提供访问。
      即:我们印象中webapp目录下静态资源以及jsp能够被访问的根本原因在于配置了以上两个servlet,否则,无法访问相关文件。
 
     说道这里,那么问题来了,为什么我们团队的其他应用的静态资源没有遇到过这个问题?
     答案是,因为有Spring MVC。
     Spring MVC提供了mvc:resources标签来支持静态资源的访问,没有DefaultServlet没有关系,因为我们通过工程中的web.xml的配置将所有请求都丢给了Spring MVC,再配合mvc:resources标签,
Spring MVC同样可以帮我们完成访问静态资源的请求。
     Spring MVC中mvc:resources标签的配置
    <!– 对静态资源文件的访问 –>
<mvc:resources mapping=”/misc/**” location=”/misc/”     cache-period=”31556927″ />
 
     说道这里,问题的解决办法就很简单了,要么将tomcat/conf下的web.xml加到应用部署路径中,要么加上mvc:resources标签的配置。
 
 

总结:

     这是一个非常简单的问题排查的过程,过程中透露的排查问题的方式和细节同样可以适用于更复杂问题的排查中,只有我们对问题中涉及到的每一个环节都能够做到了如指掌,仔细分析才能更快速的定位及解决问题。
任何细小的问题,都一定可以学习成长。
 
     
     
0.00 avg. rating (0% score) - 0 votes

发表评论

电子邮件地址不会被公开。 必填项已用*标注