记一次jetty 404问题排查修复

问题现象:

最近遇到一个很奇怪的线上问题:线上的管理后台web应用,经常在跑了一段时间后,访问出现404。

image.png

之前查过好几次日志,并没有报错或是其他异常,重新部署后又能正常访问了。直到最近又出现了,遂决定彻底查一下原因。

观察到的现象是:

1.管理页面无法正常访问,显示404。如上图。

2.访问该应用的restful接口,可以正常返回。

image.png

原因定位

通过现象可见,该应用并没有彻底down掉,因为接口还可以正常访问。所以排除了内存泄漏等导致应用挂掉的原因。

直观感觉是可能真的是找不到这个页面文件了,所以才会404。抱着这个思路试图找到jetty查找index.html文件的位置,即jetty将应用war包解压的位置。

查看jetty官方文档找到下面这一段:

By default, Jetty will create this directory inside the directory named by the java.io.tmpdir System property. You can instruct Jetty to use a different parent directory by setting the context attribute org.eclipse.jetty.webapp.basetempdir to the name of the desired parent directory. The directory named by this attribute must exist and be writeable.

翻译一下就是jetty默认使用java.io.tmpdir这一系统变量的路径作为解压路径。

可以使用如下命令查看系统属性:

java -XshowSettings:properties -version

部分输出如下:

# java -XshowSettings:properties -version

Property settings:

    awt.toolkit = sun.awt.X11.XToolkit

    file.encoding = UTF-8

    file.encoding.pkg = sun.io

    file.separator = /

    java.awt.graphicsenv = sun.awt.X11GraphicsEnvironment

    java.awt.printerjob = sun.print.PSPrinterJob

    java.class.path = .

    java.class.version = 52.0

    java.endorsed.dirs = /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.20-3.b26.el6.x86_64/jre/lib/endorsed

    java.ext.dirs = /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.20-3.b26.el6.x86_64/jre/lib/ext

        /usr/java/packages/lib/ext

    java.home = /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.20-3.b26.el6.x86_64/jre

    java.io.tmpdir = /tmp

或者在java代码中使用如下语句获取系统属性:

System.getProperty("java.io.tmpdir")

可以看到linux系统下默认为/tmp目录。遂去/tmp目录查看,并没有发现跟jetty解压相关的文件夹。猜想可能是/tmp目录定期清理时把相关的文件夹删掉了,导致解压出来的页面相关文件找不到。

查看文件tmpwatch查看清理周期:

vim /etc/cron.daily/tmpwatch

#! /bin/sh

flags=-umc

/usr/sbin/tmpwatch "$flags" -x /tmp/.X11-unix -x /tmp/.XIM-unix \

        -x /tmp/.font-unix -x /tmp/.ICE-unix -x /tmp/.Test-unix \

        -X '/tmp/hsperfdata_*' 10d /tmp

/usr/sbin/tmpwatch "$flags" 30d /var/tmp

for d in /var/{cache/man,catman}/{cat?,X11R6/cat?,local/cat?}; do

    if [ -d "$d" ]; then

        /usr/sbin/tmpwatch "$flags" -f 30d "$d"

    fi

done

可以看出来清理周期为30天,基本跟问题复现的周期吻合。

解决问题

找到问题了,来看怎么解决。jetty官方文档给出几种设置解压路径的方法:

通过xml文件配置:

<Configure class="org.eclipse.jetty.webapp.WebAppContext">

<Set name="contextPath">/test</Set>

<Set name="war">foo.war</Set>

<Call name="setAttribute">

<Arg>org.eclipse.jetty.webapp.basetempdir</Arg>

<Arg>/home/my/foo</Arg>

</Call></Configure>

通过java代码配置:

WebAppContext context = new WebAppContext();

context.setContextPath("/test");

context.setWar("foo.war");

context.setAttribute("org.eclipse.jetty.webapp.basetempdir", "/tmp/foo");

或者还有一种最简单的方法,在jetty安装的根目录下建一个叫work的文件夹,jetty就会使用该文件夹作为解压的路径了。我使用的是这种方法。

Mostly for backward compatibility, from Jetty 9.1.1 onwards, it is possible to create a directory named "work" in the ${jetty.base} directory. If such a directory is found, it is assumed you want to use it as the parent directory for all of the temporary directories of the webapps in ${jetty.base}.

image.png
image.png

新建完work目录后,重新部署应用,会发现该目录下jetty自动创建的解压文件夹,文件夹下有页面相关的文件。

到此,问题的原因和解决方案都有了,问题也算解决了。

更进一步

仔细想一想,还有一个问题没有解决。为什么应用解压的文件夹被删除,页面文件肯定找不到了,但是跟页面无关的接口却正常工作呢?

是否是jetty把静态资源放在上述的解压文件夹下,class等文件放在别的地方了呢。

我们都知道,jetty和tomcat要部署war包都只要把war包放在根目录的webapps目录下。查看原始的war包文件,内容如下。

image.png

可以看到war包原始内容跟work下解压出的内容完全一致。其中WEB-INF目录下包括了class、lib引入的jar包等文件夹,符合servlet规范要求。

1)/WEB-INF/

专门的Servlet API定义文件夹,通常存储和Web应用相关但不为外部访问的任何东西。

如果你有内容被你的Web应用内部访问,但不会被web浏览器直接地访问,你就应该把他们放在这里。

2)/WEB-INF/web.xml

必须的部署描述符,用于定义你的Web应用的各种行为。

3)/WEB-INF/classes/

Web应用的java classes文件放置目录。

4)/WEB-INF/lib/

JAR文件放置的目录。

image.png

此时尝试把work目录下解压出来的文件夹删除,依然是页面404无法访问,接口可以。

继续查看jetty部署相关章节文档,并没有找到相关的描述,只能大胆的猜测:

1.class文件、jar包等内容,jetty是在解压后就加在到内存中的,jvm在运行时,并不会访问之前解压出来的文件,所以删除没有影响。

2.html、css等静态资源,当有页面访问时,是从之前解压的文件夹中读取的,所以删除会报404异常。

如有不同看法,欢迎指正。

参考:

http://www.eclipse.org/jetty/documentation/current/ref-temporary-directories.html

http://www.eclipse.org/jetty/documentation/current/configuring-deployment.html

http://blog.csdn.net/u011479200/article/details/79200788

https://stackoverflow.com/questions/26459904/reading-java-system-properties-from-command-line

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容