【问题标题】:jetty replay request on timeout超时时码头重播请求
【发布时间】:2015-08-27 12:16:37
【问题描述】:

我们在 Jetty 中遇到了一个问题,如果我们没有完成来自异步上下文的请求,它会在超时时再次重播原始请求。这是行为,对于每个请求,我们都设置了一个带有超时的异步侦听器,因此我们有 2 个线程在运行,一个 (Jetty Thread1) 正在侦听超时,另一个 (Thread2) 正在服务线程。现在让我们说向客户端写入数据的时间比超时时间长,因为请求未完成超时线程被触发,它会检查是否有人正在写入数据,因此它会静默返回。 Jetty 不喜欢静默返回,它会重播请求,因此会创建另一个服务和超时线程,并继续运行,直到写入数据并完成异步上下文。

有问题的代码在这里 - 在HttpChannelStateexpired() 方法中

if (aListeners!=null)
{
   for (AsyncListener listener : aListeners)
   {
       try
       {
           listener.onTimeout(event);
       }
       catch(Exception e)
       {
           LOG.debug(e);
           event.setThrowable(e); 
           _channel.getRequest().setAttribute(RequestDispatcher.ERROR_EXCEPTION,e);
           break;
        }
    }
}


boolean dispatch=false;
synchronized (this)
{
    if (_async==Async.EXPIRING)
    {
        _async=Async.EXPIRED;
        if (_state==State.ASYNC_WAIT)
        {
            _state=State.ASYNC_WOKEN;
            dispatch=true;
        }
    }
}
if (dispatch)
scheduleDispatch();   // <------------ dispatch again why
}

【问题讨论】:

    标签: timeout jetty redo replay


    【解决方案1】:

    这是正常行为。您已将请求置于异步状态,然后未处理超时,因此使用 ASYNC 的 DispatcherType 重新调度请求。

    如果您添加自己的超时侦听器,并且在该超时内您完成或调度 asyncContext,那么码头将不会重新调度它(除非您的侦听器调用调度)。

    您还可以通过对 DispatcherType 的测试来保护您的异步 servlet 代码,但如果您有多个可能被异步处理的问题,这可能会造成混淆。

        asyncContext.addListener(new AsyncListener()
        {
    
            @Override
            public void onTimeout(AsyncEvent event) throws IOException
            {
                event.getAsyncContext().complete();
    
            }
    
            @Override
            public void onStartAsync(AsyncEvent event) throws IOException
            {                
            }
    
            @Override
            public void onError(AsyncEvent event) throws IOException
            {
            }
    
            @Override
            public void onComplete(AsyncEvent event) throws IOException
            {
            }
        });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-11-08
      • 2011-02-26
      • 2017-11-17
      • 2012-10-14
      • 2021-01-08
      • 2016-01-06
      • 1970-01-01
      相关资源
      最近更新 更多