记一次tomcat无响应事件

栏目: 服务器 · 发布时间: 7年前

内容简介:在一次安全扫描的时候,进行到一半,nginx出现504错误。进行服务器内, 用 curl测试tomcat服务,发现无响应。使用htop查看内存及cpu占情况。

在一次安全扫描的时候,进行到一半,nginx出现504错误。

进行服务器内, 用 curl测试tomcat服务,发现无响应。

使用htop查看内存及cpu占情况。

内存没占满,CPU占用80%左右。

检查数据库连接。数据库连接正常。

于是使用jstack导出tomcat的调用栈。

jstack调用栈信息分析

整个文件2188行。(正常情况下该项目jstack在500行左右)

文件比较长,不好直接看,所以先搜索统计。

0x1

以关键字 http-bio-8080-exec- 搜索。

有66个匹配,说明tcomat线程池中大概开了60多个活跃线程。

从最前面查看重复的调用栈。

卡在 org.apache.tomcat.util.buf.UEncoder.initSafeChars 函数上有39处。每处 UEncoder.java 的行数,有一样,有不一样,129,132等。

下载tomcat的源代码 地址

第127行: safeChars=new BitSet(128);

感觉也没什么。

大概就是在UEncoder初始化的地方。

UEncoder是线程不安全的。

0x2

卡在 java.lang.Long.parseLong 上面有5处理。

这里是jdk的类,没有什么可以说的。

0x3

卡在 http.URLParameter.clear(URLParameter.java:104)
http.URLParameter.clear(URLParameter.java:127)

有18处。

URLParameter.java 是框架内的类。找到源码。

定位到104行: this.map.clear();

map的声明是 private Map<String, Set<String>> map = new HashMap(); 这样的。

定位到127行

else for (String key : this.keys) {

keys的声明是这样的 protected final String[] keys;

从感觉上猜测是回收map的时候出的问题。

0x4

找了下线程是阻塞状态的,只有两条 State: BLOCKED

0x5

其中重复比较多的一个片段

"http-bio-8080-exec-99" daemon prio=10 tid=0x00007f08b445a000 nid=0xaee runnable [0x00007f08975e9000]
   java.lang.Thread.State: RUNNABLE
	at org.apache.tomcat.util.buf.UEncoder.initSafeChars(UEncoder.java:127)
	at org.apache.tomcat.util.buf.UEncoder.<init>(UEncoder.java:45)
	at org.apache.catalina.connector.Response.<init>(Response.java:258)
	at org.apache.catalina.connector.Connector.createResponse(Connector.java:895)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:374)
	at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1040)
	at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
	at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:313)
	- locked <0x00000000d21c8568> (a org.apache.tomcat.util.net.SocketWrapper)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
	at java.lang.Thread.run(Thread.java:745)

总的来说

从栈信息来说,虽然是有很多重复的地方,但没有找到可能的原因。

如果是map的清除,引起的gc,占用cpu的情况,也是有可能。

gc占用的CPU优先级比较高,然后GC未完成之前,分配内存很慢,并其它线程等待时间片。

但无法解释UEncoder的问题,UEncoder有的是卡在分配set上,有的是在for循环上。

最终是没有找到原因。缺少更准确和能深入诊断的手段。

这类问题属于综合性的问题,重现一次需要很长时间。

解决的思路:

1,尽量找能快速重现的方法

2,查看外部资源状态,检查外部系统依赖问题

3,查看内部线程状态

当时只用CPU和内存方面查看了系统状态,没有看下磁盘IO及网络IO方面的情况。

目前只用到了jstack,还应该综合其它诊断 工具 来排查问题。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Programming Ruby

Programming Ruby

Dave Thomas、Chad Fowler、Andy Hunt / Pragmatic Bookshelf / 2004-10-8 / USD 44.95

Ruby is an increasingly popular, fully object-oriented dynamic programming language, hailed by many practitioners as the finest and most useful language available today. When Ruby first burst onto the......一起来看看 《Programming Ruby》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

html转js在线工具
html转js在线工具

html转js在线工具