记录一次tomcat挂掉的问题

最近生产环境服务器突然挂掉,检查tomcat日志发现报了大量的ava.lang.IllegalStateException: getWriter() has already been called for this response错误。

 

这个错误,很明显是在一次请求中同时使用了getOutputStream()和getWriter()导致,立即检查代码,发现确实在自定义的LogUploadAsyncServle.java中显示的调用了getWriter(),

但是代码中并没有调用getOutputStream(),这就很奇怪了报错的UploadRest和LogUploadAsyncServle不是一个请求

随之几个问题就冒出来了

  1. getOutputStream()是在什么地方调用的?
  2. UploadRest和LogUploadAsyncServle为什么会相互影响?
  3. 该问题如何导致服务器挂掉?

 

继续浏览日志发现,竟然是第三方插件cxf调用的getOutputStream()。那么根据现有信息初步可以判定是因为自定义LogUploadAsyncServle中的getWriter()调用没有关闭,影响了cxf调用getOutputStream。

那么对于两个完全不相连的逻辑(cxf实现的UploadRest接口和自定义的LogUploadAsyncServle)是如何相互影响的,研究代码发现Apache CXF的实现是自定义了CXFServlet类,继承了javax.servlet.http.HttpServlet。我们自定义的LogUploadAsyncServle类也是继承了HttpServlet,而且都是在一个war包中,考虑到HttpServlet的特点,那么从这个父类这个层面考虑,真的有可能LogUploadAsyncServle与UploadRest相互影响了。

         既然相互会产生影响,根据错误日志那么肯定是LogUploadAsyncServle中含有未关闭的调用了getWriter()的请求。继续研究代码发现,是采用了AsyncContext异步关闭请求的方式,在关闭请求调用asyncContext.complete()超时后在监听器中又调用了getWriter(); 导致请求关闭彻底异常。猜测由于这个请求非常的频繁,很快的占用了所有的tomcat开启的请求池,导致新来的UploadRest请求不停的报 getWriter() has already been called for this response错误

     分析到这里,服务器挂掉的大致原因就清楚了,应该tomcat存在大量的未关闭的请求,并且还有源源不断的请求进来,大量的资源没有释放,引起了tomcat挂掉。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值