java – 如何处理Jetty异常 – 长时间运行的HTTP请求超时,但它所调用的进程永远不会终止,Jetty不满意

前端之家收集整理的这篇文章主要介绍了java – 如何处理Jetty异常 – 长时间运行的HTTP请求超时,但它所调用的进程永远不会终止,Jetty不满意前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个处理长时间运行的HTTP请求的Jetty服务器 – 响应由不同的进程X生成,最终在Jetty请求定期检查的收集器哈希中.

有3例:

>进程X在HTTP请求的超时时间之前完成 –
没问题
>进程X在请求的超时时间结束 – 否
问题
>进程X从不完成 – 发生异常

如何检测这种情况(3)并防止异常,同时允许其他两种情况正常工作?

例外:

  1. 2012-06-18 00:13:31.055:WARN:oejut.QueuedThreadPool:
  2. java.lang.IllegalStateException: IDLE,initial
  3. at org.eclipse.jetty.server.AsyncContinuation.complete(AsyncContinuation.java:569)
  4. at server.AsyncHTTPRequestProcessor.run(AsyncHTTPRequestProcessor.java:72)
  5. at org.eclipse.jetty.server.handler.ContextHandler.handle(ContextHandler.java:1119)
  6. at org.eclipse.jetty.server.AsyncContinuation$1.run(AsyncContinuation.java:875)
  7. at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:599)
  8. at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:534)
  9. at java.lang.Thread.run(Thread.java:679)

Jetty继续HTTP请求:

  1. public class AsyncHTTPRequestProcessor implements Runnable {
  2.  
  3. private ConcurrentHashMap<String,String> collector;
  4. private Logger logger;
  5. private AsyncContext ctx;
  6. //Defined this here because of strange behavIoUr when running junit
  7. //tests and the response json string being empty...
  8. private String responseStr = null;
  9.  
  10. public AsyncHTTPRequestProcessor(AsyncContext _ctx,ConcurrentHashMap<String,String> _collector,Logger _logger) {
  11. ctx = _ctx;
  12. collector = _collector;
  13. logger = _logger;
  14. }
  15.  
  16. @Override
  17. public void run() {
  18.  
  19. logger.info("AsyncContinuation start");
  20.  
  21. //if(!((AsyncContinuation)ctx).isInitial()){
  22. String rid = (String) ctx.getRequest().getAttribute("rid");
  23. int elapsed = 0;
  24. if(rid !=null)
  25. {
  26.  
  27. logger.info("AsyncContinuation rid="+rid);
  28.  
  29. while(elapsed<ctx.getTimeout())
  30. {
  31. if(collector.containsKey(rid)){
  32. responseStr = collector.get(rid);
  33. collector.remove(rid);
  34.  
  35. logger.info("--->API http request in collector:"+responseStr);
  36. ctx.getRequest().setAttribute("status",200);
  37. ctx.getRequest().setAttribute("response",responseStr);
  38. ctx.getRequest().setAttribute("endTime",System.currentTimeMillis());
  39. //ctx.complete();
  40. break;
  41. }
  42. try {
  43. Thread.sleep(10);
  44. elapsed+=10;
  45. } catch (InterruptedException e) {
  46. e.printStackTrace();
  47. }
  48. }
  49. //}
  50. logger.info("Collector in async stuff:");
  51. for(String key:collector.keySet()){
  52. logger.info(key+"->"+collector.get(key));
  53. }
  54.  
  55. for(Entry<String,String> x:collector.entrySet()){
  56. logger.info(x.getKey()+"->"+x.getValue());
  57. }
  58. ctx.complete(); <---- this line 72
  59. }
  60. }
  61.  
  62. }

解决方法

这里的问题不是您调用AsyncContext#complete(),而是代码的泛型设计.

连续性(Servlet异步同样的事情)被设计为异步的.使用内部连续超时的while循环不能在这里.通过这样做,您正在将异步设计转变为同步设计.正确的做法是使用Continuation#addContinuationListener()注册一个监听器,并实现onTimeout()方法来适当地处理超时情况.

一旦你的超时逻辑出来,我建议将过程X逻辑移到AsyncHTTPRequestProcessor类,并从需要使用收集器移出.在处理过程中,您应该假设当前线程永远不会被超时.通过这样做,您对complete()的调用会产生敏感,您将无法收集收集器上的并发故障.

猜你在找的Java相关文章