DBMNG数据库管理与应用

书籍是全世界的营养品。生活里没有书籍,就好像没有阳光;智慧里没有书籍,就好像鸟儿没有翅膀。
当前位置:首页 > 经验分享 > Java开发

servlet3中异步请求AsyncContext AsyncListener超时的问题

在用tomcat来搞servlet异步化请求,当然异步化下异常处理也很重要,servlet3默认带一个监听器,可以监听onComplete,onError,onStartAsync,onTimeout事件,当然onTimeout可以选择在系统server.xml当中Connector 设置asyncTimeout="100"单位是毫秒,如果不设置,默认就是10秒,当然
Java代码
AsyncContext asyncContext = request.startAsync();  
asyncContext.setTimeout(100);  
在代码中也可以去设置,tomcat会以此为准,当然你必须得addListener。
 
 
调试中发现这100毫秒不会生效,当服务端返回超过100ms,可以请求就是不会报超时,这是为什么呢?看tomcat源码了
找啊找啊找,一切都明了了,原来超时线程在那sleep(1000)呢,因此要得到很短的超时并且能够生效,要么自己搞,要么改tomcat的源码吧
 
bio && apr实现

Java代码

/** 
* Async timeout thread 
*/  
protected class AsyncTimeout implements Runnable {  
   /** 
	* The background thread that checks async requests and fires the 
	* timeout if there has been no activity. 
	*/  
   @Override  
   public void run() {  

	   // Loop until we receive a shutdown command  
	   while (running) {  
		   try {  
			   Thread.sleep(1000);  
		   } catch (InterruptedException e) {  
			   // Ignore  
		   }  
		   long now = System.currentTimeMillis();  
		   Iterator<SocketWrapper<Socket>> sockets =  
			   waitingRequests.iterator();  
		   while (sockets.hasNext()) {  
			   SocketWrapper<Socket> socket = sockets.next();  
			   long access = socket.getLastAccess();  
			   if (socket.getTimeout() > 0 &&  
					   (now-access)>socket.getTimeout()) {  
				   processSocketAsync(socket,SocketStatus.TIMEOUT);  
			   }  
		   }  

		   // Loop if endpoint is paused  
		   while (paused && running) {  
			   try {  
				   Thread.sleep(1000);  
			   } catch (InterruptedException e) {  
				   // Ignore  
			   }  
		   }  

	   }  
   }  
}  
 
nio实现 
Java代码 
Poller线程当中,存在  
//process timeouts  
timeout(keyCount,hasEvents);  
也是在有新的事件到来,或者selectorTimeout=1000ms超时后,都会去触发  
// Async requests with a timeout of 0 or less never timeout  
  long delta = now - ka.getLastAccess();  
  long timeout = (ka.getTimeout()==-1)?((long) socketProperties.getSoTimeout()):(ka.getTimeout());  
  boolean isTimedout = delta > timeout;  
  if (isTimedout) {  
	  // Prevent subsequent timeouts if the timeout event takes a while to process  
	  ka.access(Long.MAX_VALUE);  
	  processSocket(ka.getChannel(), SocketStatus.TIMEOUT, true);  
  }
 




本站文章内容,部分来自于互联网,若侵犯了您的权益,请致邮件chuanghui423#sohu.com(请将#换为@)联系,我们会尽快核实后删除。
Copyright © 2006-2023 DBMNG.COM All Rights Reserved. Powered by DEVSOARTECH            豫ICP备11002312号-2

豫公网安备 41010502002439号