web服务请求线程中带有输出语句时,频繁出现线程状态变成了BLOCKED,线程被无限阻塞,原来是“快速编辑模式”惹的祸

目录

 

问题现象:

问题分析:

原因查找:

挖掘一下问题:

进一步挖掘,锁定问题:

最终结果:



问题现象:

        最近在做一个项目,部署到服务器上后,后台某个接口频繁出现被阻塞的情况,发送请求长时间没有响应,甚至超过tomcat的超时时间,还是处于等待状态。

 

问题分析:

    1、出现问题的接口分析,代码中不存在锁,甚至连接数据库的都没有,代码上应该不会造成这种问题;

    2、本地测试没有出现这种问题,部署到服务器上问题出现很频繁,难道是服务器问题?

    3、某个晚上测试的时候,突然出现所有接口都不能使用的情况,不再是那几个接口有问题了。(这里埋下个伏笔)

    4、怀疑过框架、服务器等等,感觉都不合理,没有理由出现这种情况。

 

原因查找:

       用JCONSOLE看一下JVM内存和线程情况,看是否内存不足或者线程消耗后没有释放,导致不够用(虽然觉得不可能,因为有时候一启动就发生这种现象,但是还是试试看,毕竟没办法了)。

       发现一个现象,一旦出现阻塞情况,再发请求,活动线程数会增加,不会释放。

 

挖掘一下问题:

通过Java VisualVM等工具查看有问题的线程,发现带有输出语句的请求,线程状态都变成了BLOCKED,都在等待java.io.PrintStream的锁,同时发现有log日志打印到控制台的请求也出现了这个情况,即线程状态都变成了BLOCKED,都在等待java.util.logging.ConsoleHandler的锁:

具体如下:

web服务请求线程中带有输出语句时,频繁出现线程状态变成了BLOCKED,线程被无限阻塞,原来是“快速编辑模式”惹的祸_第1张图片

这个线程状态是BLOCKED,具体是到了输出语句,就一直在等待java.io.PrintStream的锁,而这个锁显示是被另一个线程“http-nio-80-exec-4”持有;那就看看这个线程:

web服务请求线程中带有输出语句时,频繁出现线程状态变成了BLOCKED,线程被无限阻塞,原来是“快速编辑模式”惹的祸_第2张图片

发现这个线程状态始终是RUNNABLE,但是这个java.io.PrintStream始终处于锁定状态,查看代码,没有发现任何可疑的情况。

 

进一步挖掘,锁定问题:

事实上,到了这里,问题解决是很好解决了,代码里不管是什么,不要输出到控制台就好了。

但是根源是什么呢?  还是不知道,甚至发了论坛帖子,希望得到一点帮助。

https://bbs.csdn.net/topics/392513724

但是始终没有得到有效信息,通过不断搜索和思考,终于获得了突破,想起一个问题来,tomcat窗口点击后,上面出现了“选定”,具体如下:

web服务请求线程中带有输出语句时,频繁出现线程状态变成了BLOCKED,线程被无限阻塞,原来是“快速编辑模式”惹的祸_第3张图片

web服务请求线程中带有输出语句时,频繁出现线程状态变成了BLOCKED,线程被无限阻塞,原来是“快速编辑模式”惹的祸_第4张图片

那会不会是这个问题造成的呢?

试验一下,果然!

 

最终结果:

原来,问题出在tomcat窗口的“快速编辑模式”:在tomcat窗口上面非输出区,右键点击菜单“默认值”,会有个选项:

web服务请求线程中带有输出语句时,频繁出现线程状态变成了BLOCKED,线程被无限阻塞,原来是“快速编辑模式”惹的祸_第5张图片

在这个模式下,点击tomcat窗口输出区,窗口上面会显示“选定”或者“选择”,这时候,所有的输出都会暂停,所以才会出现前面所描述的那些现象,当然,点击右键或者键盘按“回车键”,可以释放这种状态。

 

所以,到现在一切问题就清楚了,很多系统下默认这个“快速编辑模式”是打开的,不小心点击输出窗口导致窗口锁定,暂停所有的输出。

 

问题清楚了,解决办法也就容易了,去掉这个模式,重启tomcat就可以了。


问题分析中第三条,实际上我是为了测试其他接口为什么都没有问题,全部在开头加了输出语句,所以后来所有的请求都不能用了。但是当时并没有想这么多。。。

你可能感兴趣的:(java)