最近我为了节省成本改用了 amazon ec2 + jetty9 + oracle jdk7_u45。我发现 jetty 服务器非常不稳定。它会随机崩溃,没有任何 jvm 转储文件。
尝试使用 dumpBeforeStop=TRUE 启用 stdout。它不会在崩溃前将转储消息附加到 stderrout.log。
似乎它与 OutOfMemoryError 无关,因为我已启用 gc 详细选项并发现它在崩溃之前仍有许多可用内存。:162604K->3340K(176960K),0.2240040 秒] 248332K->89101K(373568K),0.2736860 秒] [时间:用户=0.01 系统=0.01,实际=0.28 秒]
尝试降级到使用不同 jdk 组合 (jdk6 / jdk7) 的 jetty8。仍然遇到同样的问题。
尝试删除所有 jvm 选项并使用“sudo java -jar start.jar”来运行 jetty。仍然崩溃。
还有其他方法可以解决问题吗?
答案1
这里有很多话题......
首先,Jetty 9 是什么版本?(请具体说明!使用这些详细信息编辑您的问题)
您dumpBeforeStop=TRUE
提到的不是 Jetty 的已知配置。如果您指的是启动属性,jetty.dump.stop=true
那么它用于在正式/正常关闭期间转储服务器 + 处理程序树的状态。它与服务器内存或服务器崩溃无关。
如果您想要查看服务器和处理程序树转储,而不停止服务器,那么您可以使用启动属性jetty.dump.start=true
或启用 JMX 并访问org.eclipse.jetty.server:type=server,id=0
MBean 并使用该dump()
操作。
OutOfMemoryError 可能因各种原因而发生。(您没有粘贴完整的错误消息和堆栈跟踪来缩小原因范围)。它可能由于堆不足、permgen、线程或文件描述符等而发生...如果没有 OutOfMemoryError 错误消息中的额外信息,建议您查看哪条路径几乎是不可能的。
GC 事件日志提供的关于正在发生的事情的信息太少了。您可能有一个尝试分配 4GB 的操作,这不会显示在 GC 上,但仍会导致 OutOfMemoryError。您可能遇到这样的情况:服务器尝试分配一个新线程,但操作系统阻止了它,这也会导致OutOfMemoryError: Failed to Create Thread
切换 Jetty 或 JVM 版本对 OutOfMemoryError 不会产生任何影响。
“删除所有 JVM 选项”也可能没有效果,这取决于您如何配置 Jetty,而您在问题中没有指定这一点。
根据您特定的 Jetty 版本,启动方式会有所不同。(例如:Jetty 7/8/9.0 与 Jetty 9.1)
根据您特定的 Jetty 安装技术,您的启动可能会有所不同。(例如:独立与嵌入式、来自官方 jetty 发行版、来自 linux 发行版/打包、来自云提供商打包、隔离与 unixfied 目录结构、拆分 jetty.home 与 jetty.base、服务启动与 shell 与 cron、shell 脚本或 java 命令行、没有 start.ini 与 start.ini 和/或 start.d 等...)
简而言之,您的问题有效但模糊,为您提供建议的可能途径太多(基于您提供的有限信息)
答案2
最后我通过添加交换内存解决了这个问题。
amazon t1.micro 实例的默认 AMI 没有交换内存,我遵循此邮政创建 1G 交换空间。jvm 可以在一周内启动并运行。
答案3
感谢您的快速回答。我尝试了 jetty-9.0.6、jetty-9.0.5 和 jetty-8.1.14。以上所有版本都遇到了同样的问题。
dumpBeforeStop,这是 jetty.xml 中的有效配置。默认值为 false,我同意如果它只在正常关闭时起作用,那么它与服务器崩溃无关。这里没有 OutOfMemoryError 的情况。我打开了 -XX:-HeapDumpOnOutOfMemoryError。崩溃时不会生成任何转储文件。
我尝试删除所有 jvm 选项,因为我想使用干净的默认设置来运行 jetty 以查看任何差异。
现在的问题是,jvm 随机崩溃,没有任何 hs 文件或任何有用的错误消息。如果 jetty 无法处理某些事情,则 stderr/stdout 中应该有错误。
如果某些事情无法由 jvm 处理,那么应该有一个热点文件。遗憾的是它只是默默地崩溃了。
昨晚尝试打开 jetty 调试模式,今天早上发现又崩溃了,崩溃前最后几行日志如下:
2013-11-13 06:26:00.891:DBUG:oejsh.ContextHandler:scope /||/article.jsp @ oejwWebAppContext{/,文件:/tmp/jetty-0.0.0.0-8080-put2012.war--xxx.xx-/webapp/,xxx.xx},/home/ec2-user/jetty/webapps/put2012.war 2013-11-13 06:26:00.891:DBUG:oejsh.ContextHandler:context=||/article.jsp @ oejwWebAppContext{/,文件:/tmp/jetty-0.0.0.0-8080-put2012.war--xxx.xx-/webapp/,xxx.xx},/home/ec2-user/jetty/webapps/put2012.war 2013-11-13 06:26:00.891:DBUG:oejs.session:sessionManager=org.eclipse.jetty.server.session.HashSessionManager@1acc0e01 2013-11-13 06:26:00.891:DBUG:oejs.session:session=null 2013-11-13 06:26:00.891:DBUG:oejs.ServletHandler:servlet |/article.jsp|null -> jsp 2013-11-13 06:26:00.891:DBUG:oejs.ServletHandler:chain=null 2013-11-13 06:26:00.894:DBUG:oejs.session:新会话和 ID 1hva53vl2jfs9m6voqnqdamyj 1hva53vl2jfs9m6voqnqdamyj 2013-11-13 06:26:01.885:DBUG:oejw.WebAppClassLoader:已加载类 com.sun.mail.handlers.text_plain 来自 WebAppClassLoader=put2012@3ef07355 2013-11-13 06:26:01.885:DBUG:oejw.WebAppClassLoader:已加载类 com.sun.mail.handlers.text_plain 来自 WebAppClassLoader=put2012@3ef07355
您可以看到没有任何线索表明它为什么会崩溃。
没有尸体,我就无法检查其被杀的原因。
我尝试用 jstack 进行线程转储,没有任何异常。它只有在崩溃时转储线程时才有用。