gpt4 book ai didi

java - 如何处理 Jetty 异常 - 长时间运行的 HTTP 请求超时,但它调用的进程永远不会终止并且 Jetty 不高兴

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:01:49 30 4
gpt4 key购买 nike

我有一个处理长时间运行的 HTTP 请求的 Jetty 服务器 - 响应由不同的进程 X 生成,并以 Jetty 请求定期检查的收集器散列结束。

有3种情况:

  1. 进程 X 在 HTTP 请求的超时期限之前完成 -没问题
  2. 进程 X 在请求的超时期限后完成 - 否问题
  3. 进程 X 永远不会完成 - 发生以下异常

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

异常(exception):

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


HTTP 请求的 Jetty 延续:

public class AsyncHTTPRequestProcessor implements Runnable {

private ConcurrentHashMap<String, String> collector;
private Logger logger;
private AsyncContext ctx;
//Defined this here because of strange behaviour when running junit
//tests and the response json string being empty...
private String responseStr = null;

public AsyncHTTPRequestProcessor(AsyncContext _ctx,
ConcurrentHashMap<String, String> _collector, Logger _logger) {
ctx = _ctx;
collector = _collector;
logger = _logger;
}

@Override
public void run() {

logger.info("AsyncContinuation start");

//if(!((AsyncContinuation)ctx).isInitial()){
String rid = (String) ctx.getRequest().getAttribute("rid");
int elapsed = 0;
if(rid !=null)
{

logger.info("AsyncContinuation rid="+rid);

while(elapsed<ctx.getTimeout())
{
if(collector.containsKey(rid)){
responseStr = collector.get(rid);
collector.remove(rid);

logger.info("--->API http request in collector:"+responseStr);
ctx.getRequest().setAttribute("status",200);
ctx.getRequest().setAttribute("response", responseStr);
ctx.getRequest().setAttribute("endTime",System.currentTimeMillis());
//ctx.complete();
break;
}
try {
Thread.sleep(10);
elapsed+=10;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//}
logger.info("Collector in async stuff:");
for(String key:collector.keySet()){
logger.info(key+"->"+collector.get(key));
}

for(Entry<String, String> x:collector.entrySet()){
logger.info(x.getKey()+"->"+x.getValue());
}
ctx.complete(); <---- this line 72
}
}

}

最佳答案

这里的问题不是你对 AsyncContext#complete() 的调用,而是代码的整体设计。

Continuations(Servlet async 也是如此)被设计为异步。使用内部延续超时的 while 循环一定不能在这里。通过这样做,您正在将异步设计转换为同步设计。正确的做法是使用 Continuation#addContinuationListener() 注册一个监听器并实现 onTimeout() 方法以适本地处理超时情况。

一旦您的超时逻辑结束,我会建议将流程 X 逻辑移至类 AsyncHTTPRequestProcessor 并不再需要使用收集器。在处理过程中,您应该假设当前线程永远不会超时。通过这样做,您对 complete() 的调用变得有意义,并且您将免受收集器上的并发问题的影响。

关于java - 如何处理 Jetty 异常 - 长时间运行的 HTTP 请求超时,但它调用的进程永远不会终止并且 Jetty 不高兴,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11075873/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com