异步上下文没有超时

4

我一直在尝试使用异步上下文的超时功能,但行为非常不稳定。有时超时会发生,而很多时候则没有。我在这里贴出我的代码。

@WebServlet(name = "TestServlet", urlPatterns = {"/test"},asyncSupported = true)
public class TestServlet extends HttpServlet{

private static final long serialVersionUID = 1L;

private static PriorityBlockingQueue<Runnable> pq = new PriorityBlockingQueue<Runnable>(1000);

private static ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1,1,10, TimeUnit.SECONDS,pq);

public void service(final ServletRequest servletRequest, final ServletResponse response)
    throws ServletException, IOException {
    TestListener listener = new TestListener();
    final AsyncContext asyncContext = servletRequest.startAsync();
    asyncContext.addListener(listener);
    asyncContext.setTimeout(100);
    Handler handler = new Handler(asyncContext);
    threadPoolExecutor.execute(handler);
}
}

以下是监听器和处理器的代码:

监听器和处理器的代码如下。

public class TestListener implements AsyncListener {
public void onComplete(AsyncEvent event) throws IOException {
    System.out.println("Event completed");
}

public void onError(AsyncEvent event) throws IOException {
    event.getAsyncContext().complete();
}

public void onStartAsync(AsyncEvent event) throws IOException {
    // TODO Auto-generated method stub
}



public void onTimeout(AsyncEvent event){
    System.out.println("Timeout ");
    event.getAsyncContext().complete();
}
}

public class Handler implements Runnable {

private AsyncContext asyncContext;

public Handler(AsyncContext asyncContext){
    this.asyncContext = asyncContext;
}
public void run(){
    try {
        long currtime = System.currentTimeMillis();
        Thread.sleep(500);
        System.out.println("slept for " + (System.currentTimeMillis() - currtime));
    } catch (InterruptedException e) {
        System.out.println("Error in thread ");
    }

    try{
        if(asyncContext != null){
            System.out.println("Completing async context " + " timeout is " + asyncContext.getTimeout());
            asyncContext.complete();
        }
    }catch (Exception e){
        System.out.println("Exception in completing async context ");
    }
}
}

输出是间歇性的。包括以下内容 -

[ops@root combinedlogs]$ time curl "http://localhost:9001/mockresponse/test"

real    0m0.506s
user    0m0.001s
sys 0m0.003s
[ops@root combinedlogs]$ time curl "http://localhost:9001/mockresponse/test"

real    0m0.159s
user    0m0.001s
sys 0m0.003s

Catalina日志 -

slept for 500
Completing async context  timeout is 100
Event completed

Timeout 
Event completed
slept for 500
Exception in completing async context

我不理解这件事为什么会发生。请帮我一下!谢谢你的时间。
PS: Tomcat版本为7.0.37
1个回答

0

尝试将超时时间和睡眠间隔增加到1秒以上。
例如:尝试2秒的超时间隔和5秒的睡眠时间。
可能Servlet容器无法始终检测到小于1秒的超时。
以前在Tomcat中有几个(微不足道的)与此类子秒超时相关的错误,如this one
我知道您正在使用比该错误中提到的更高版本的Tomcat,但仍然值得一试。


谢谢您的回复!更高的超时时间和睡眠值确保在每种情况下都有超时。我之前也检查过!但是对于我来说,它并没有达到目的,因为我的超时时间可以从100毫秒到10000毫秒不等。我之前也遇到过这个错误,这就是为什么我决定使用最新版本的Tomcat。无论如何,我认为我不能使用上下文超时,我应该使用计时器线程或HashWheeledTimer。谢谢! - Rahul Jha

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接