Tomcat 增加并消耗所有可用的 CPU
Tomcat spiking and consuming all available CPU
Tomcat (8.0.14-1+deb8u1) in production server suddenly hogs all CPU, 可以做些什么来诊断原因?我知道分析器可能会派上用场,但在生产环境中没有用,有什么想法吗?
附加信息:
"top" command execution / lsb_release
@Gonzalo 我看到你已经提供了几乎所有必要的信息,但我将从 "beginning" 中写下我的答案,这样它可以对偶然发现它的经验不足的用户有所帮助。
您应该进行线程转储。您可以通过以下任一方式做到这一点:
- kill -3 PID
- jstack -F PID
查看 top
或 htop
命令输出。
- 对于
top
按"shift + h"显示线程(您也可以从顶部开始top -p PID
以过滤掉不相关的进程)
- 找出哪个线程消耗了CPU并记下线程ID
- 线程ID为十进制,需要转为十六进制。
打开线程转储并查找它的十六进制线程。这是消耗 CPU
的线程
PS:您的线程转储看起来很奇怪,并且缺少线程 ID。线程堆栈应该像这样开始:
"Finalizer" daemon prio=8 tid=0x02b3d000 nid=0x898 in Object.wait() [0x02d0f000]
...stack traces here...
其中 nid
是您从 top/htop 中找到的十六进制线程 ID。
尝试使用 kill -3
进行转储
我们的几台服务器都遇到了同样的问题。问题也出现在 tomcat 没有网络应用程序的服务器上,只提供静态页面。 cpu 使用率突然飙升至 200% 并且再也没有下降
这个问题在我们最近升级到 8.0.14 和 8_u_121
之前从未出现过
设置如下:
- debian 8.1,最新补丁
- tomcat 8.0.14
- oracle jvm 8_u_121(截至该日期最新)
- 2,4 和 8 GB 内存(取决于服务器)
- http/1.1 80 上的连接器重定向到 443; 443 上带有 https 的 nio1 连接器(实际上在 8080 和 8443 上,防火墙映射 80 到 8080 和 443 到 8443)
出现问题时症状如下:
- cpu 进程使用率 200% "java",没有下降
- 内存消耗正常
- apps.log
中没有日志条目
- 在catalina.out中约有20个条目如下:
30-Jan-2017 10:15:38.479 INFO [http-nio-8080-exec-16]
org.apache.coyote.http11.AbstractHttp11Processor.process Error parsing
HTTP request header Note: further occurrences of HTTP header parsing
errors will be logged at DEBUG level. 30-Jan-2017 10:15:40.022 INFO
[http-nio-8080-exec-17]
org.apache.coyote.http11.AbstractHttp11Processor.process Error parsing
HTTP request header Note: further occurrences of HTTP header parsing
errors will be logged at DEBUG level. 30-Jan-2017 10:15:41.574 INFO
[http-nio-8080-exec-18]
org.apache.coyote.http11.AbstractHttp11Processor.process Error parsing
HTTP request header
当我们升级到 8.0.14 时,我们在 catalina.out 中收到了类似的错误消息。这是因为此版本不再接受 url 中未转义的 { 和 }。我们通过更改客户端代码将这些字符编码为 %4B 和 %4D 来修复它。当时没有 cpu 问题
Tomcat (8.0.14-1+deb8u1) in production server suddenly hogs all CPU, 可以做些什么来诊断原因?我知道分析器可能会派上用场,但在生产环境中没有用,有什么想法吗?
附加信息: "top" command execution / lsb_release
@Gonzalo 我看到你已经提供了几乎所有必要的信息,但我将从 "beginning" 中写下我的答案,这样它可以对偶然发现它的经验不足的用户有所帮助。
您应该进行线程转储。您可以通过以下任一方式做到这一点:
- kill -3 PID
- jstack -F PID
查看
top
或htop
命令输出。- 对于
top
按"shift + h"显示线程(您也可以从顶部开始top -p PID
以过滤掉不相关的进程) - 找出哪个线程消耗了CPU并记下线程ID
- 线程ID为十进制,需要转为十六进制。
- 对于
打开线程转储并查找它的十六进制线程。这是消耗 CPU
的线程
PS:您的线程转储看起来很奇怪,并且缺少线程 ID。线程堆栈应该像这样开始:
"Finalizer" daemon prio=8 tid=0x02b3d000 nid=0x898 in Object.wait() [0x02d0f000]
...stack traces here...
其中 nid
是您从 top/htop 中找到的十六进制线程 ID。
尝试使用 kill -3
我们的几台服务器都遇到了同样的问题。问题也出现在 tomcat 没有网络应用程序的服务器上,只提供静态页面。 cpu 使用率突然飙升至 200% 并且再也没有下降
这个问题在我们最近升级到 8.0.14 和 8_u_121
之前从未出现过设置如下:
- debian 8.1,最新补丁
- tomcat 8.0.14
- oracle jvm 8_u_121(截至该日期最新)
- 2,4 和 8 GB 内存(取决于服务器)
- http/1.1 80 上的连接器重定向到 443; 443 上带有 https 的 nio1 连接器(实际上在 8080 和 8443 上,防火墙映射 80 到 8080 和 443 到 8443)
出现问题时症状如下:
- cpu 进程使用率 200% "java",没有下降
- 内存消耗正常
- apps.log 中没有日志条目
- 在catalina.out中约有20个条目如下:
30-Jan-2017 10:15:38.479 INFO [http-nio-8080-exec-16] org.apache.coyote.http11.AbstractHttp11Processor.process Error parsing HTTP request header Note: further occurrences of HTTP header parsing errors will be logged at DEBUG level. 30-Jan-2017 10:15:40.022 INFO [http-nio-8080-exec-17] org.apache.coyote.http11.AbstractHttp11Processor.process Error parsing HTTP request header Note: further occurrences of HTTP header parsing errors will be logged at DEBUG level. 30-Jan-2017 10:15:41.574 INFO [http-nio-8080-exec-18] org.apache.coyote.http11.AbstractHttp11Processor.process Error parsing HTTP request header
当我们升级到 8.0.14 时,我们在 catalina.out 中收到了类似的错误消息。这是因为此版本不再接受 url 中未转义的 { 和 }。我们通过更改客户端代码将这些字符编码为 %4B 和 %4D 来修复它。当时没有 cpu 问题