2
public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {

        if ((request instanceof HttpServletRequest)
                && (response instanceof HttpServletResponse)) {
            HttpServletRequest httpServletRequest = (HttpServletRequest) request;
            HttpServletResponse httpServletResponse = (HttpServletResponse) response;

            if (isSessionControlRequiredForThisResource(httpServletRequest)) {

                if (isSessionInvalid(httpServletRequest)) {

                    String encodedURL = httpServletRequest.getContextPath() + this.timeoutPage;

                    try {
                        httpServletResponse.sendRedirect(encodedURL);
                    } catch (Exception e) {
                        logger.error("[Error happened in filter] : ", e.fillInStackTrace());
                    }

                    return;
                }
            }

            if (!httpServletRequest.getRequestURI().startsWith(httpServletRequest.getContextPath() + ResourceHandler.RESOURCE_IDENTIFIER)) {
                httpServletResponse.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
                httpServletResponse.setHeader("Pragma", "no-cache");                    
                httpServletResponse.setDateHeader("Expires", 0);
                }
            }
            chain.doFilter(request, response);
        }

上面显示的代码有时可能会在任务期间失败,导致出现以下错误SystemOut.log

[8/26/13 8:38:39:873 MYT] 0000002c ThreadMonitor W WSVR0605W:线程“WebContainer:9”(00000037) 已活动 611221 毫秒,可能已挂起。服务器中总共有 7 个线程可能被挂起。

诊断这个错误并不容易,因为它后面总是有一个很长的堆栈跟踪列表,它不属于我的应用程序。通常它可能会在一段时间内(大约 15 到 20 分钟)发生几次,但线程 ID 可能不同。

我无法在 UAT 服务器的单元测试中模拟这一点,我不确定这个问题的根本原因是什么。它偶尔会发生。是否有捕获此错误的模式?它是否发生在其他一些异常发生后,比如数据库连接丢失或者某个后台进程正在运行,比如在生产服务器中检索巨大的结果集?我只是想了解什么情况会导致这个问题,这样我就可以在编码过程中避免这种情况。

4

2 回答 2

4
  • 确定 WebSphere 进程的 PID,例如使用jps

$ jps
1039 爪哇


  • 使用创建完整的线程转储jstack

$ jstack 1039

  • 或者(如果您在 UNIX 系统上):

$杀-QUIT 1039

$杀死-3 1039


  • 识别挂起的线程(您从日志文件中的警告中获得名称)
  • 确定线程挂起的行
    • 寻找竞争条件、非并发对象/迭代器中的并发修改等。
  • 还要检查死锁(它们可能附加到完整的线程转储中)
    • 这里有一个死锁的例子(在 state 中寻找线程BLOCKED)。

有关的:

于 2013-08-26T10:08:28.787 回答
1

诊断这个错误并不容易,因为它后面总是有一个很长的堆栈跟踪列表,它不属于我的应用程序。

您可能希望在此处共享堆栈跟踪 - 与 ThreadMonitor 挂起线程消息 (WSVR0605W) 相关联的堆栈跟踪。

基于 Beryllium 关于生成线程转储的答案(kill -3 <pid>工作正常),您可以使用IBM Thread and Monitor Analyzer工具查看生成的线程转储文件。该工具将显示线程状态 - 您将要查找名称以“Web Container:”开头的阻塞线程,并查看是否有关于监视器和其他线程的任何线索。事实上,我建议运行kill -3 <pid>一次,等待大约 15-30 秒,然后kill -3 <pid>再次运行。线程和监视器分析器将允许您查看两者的“差异”,以查看真正挂起的线程与可能只是运行缓慢的线程。它还会提醒您任何堆耗尽。

于 2013-09-15T20:30:52.453 回答