异步上下文没有超时

时间:2013-05-13 11:46:38

标签: java tomcat7 servlet-3.0

我一直在尝试使用异步上下文的超时功能。但这种行为非常间歇性。有时会发生超时,很多时候都没有。我在这里粘贴我的代码。

@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 :(得分:0)

尝试将超时和睡眠间隔增加到1秒以上。
例如:尝试2秒的超时间隔和5秒的睡眠。
servlet容器可能不会始终检测到小于1秒的超时。
在早期的tomcat中,有几个错误(略微)与这种亚秒级超时相关,如this one。我知道你使用的是tomcat的更高版本而不是那个bug,但值得一试。