异步Servlet-首选实现 [英] Async Servlet - preferred implementation
问题描述
最近,在研究Servlets
中的异步处理期间,我至少遇到了三种实现方式
使用这种方法的一些功能.
Lately, during my research about asynchronous processing in Servlets
, I came across at at least three ways to implement
some functionality using this approach.
问题是:
- 哪个是最好的?
- 也许不建议使用其中某些方法?
- 也许还有比下面提到的所有方法更好的一种方法?
找到的方法:
-
使用
AsyncContext.start(Runnable)
.
这种方法非常简单明了.但是许多服务器在为HTTP
请求创建的线程池中执行这样的作业
(有关详细信息,请参见 http://www.nurkiewicz.com/2012/05/javaxservletservletrequeststartasync .html )
This approach is quite simple and straightforward. But many serwers executes such a job in thread pool created for HTTP
requests
(more about it here http://www.nurkiewicz.com/2012/05/javaxservletservletrequeststartasync.html)
使用在Servlet上下文初始化期间创建的自定义线程池
Using custom threads pool created during Servlet context initialization
(此处的示例: http://www.journaldev .com/2008/async-servlet-feature-of-servlet-3 ).
但是我可以在Servlet容器中创建自己的线程吗?在EJB
中(在JavaEE7
之前)不建议(甚至禁止).
我可以使用JavaSE
执行器还是应该使用JavaEE7
中的ManagedExecutors
(假设我使用JavaEE7
)?
(sample here: http://www.journaldev.com/2008/async-servlet-feature-of-servlet-3).
But can I create my own threads in Servlet container? It was not recommended (or even prohibited) in EJB
(before JavaEE7
).
Can I use JavaSE
Executors or should I use ManagedExecutors
from JavaEE7
(assuming that I use JavaEE7
)?
使用EJB
和@Asynchronious
批注
(此处的示例: https://github.com/wildfly/quickstart/tree/master/servlet-async/src/main/java/org/jboss/as/quickstarts/servlet/async ). 但是在这里我无法控制执行任务的线程(即应创建多少个线程等等)
(example here: https://github.com/wildfly/quickstart/tree/master/servlet-async/src/main/java/org/jboss/as/quickstarts/servlet/async). But here I have no control over threads executing my task (i.e. how many thread should by created etc.)
很高兴听到您对这个问题的想法以及您对AsyncContext
的经验.
I would by glad to hear your thoughts on this issue and your experience with AsyncContext
.
推荐答案
所有功能都具有相同的性能,在后端,所有线程都将请求处理线程替换为另一个线程,以便可以处理更多请求.
All will have the same performance, at the backend all threads are replacing the request processing thread to another thread, so that more requests can be served.
下面您将找到一个简单的实现:
Below you'll find a simple implementation:
@WebServlet(urlPatterns = "/AsyncLongRunningServlet", asyncSupported = true)
public class AsyncLongRunningServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
System.out.println("Request Processing Thread "+Thread.currentThread().getName());
request.setAttribute("org.apache.catalina.ASYNC_SUPPORTED", true);
response.setContentType("text/html");
PrintWriter printWriter=response.getWriter();
printWriter.println("<html><head><title>Asynchronous servlet</title></head><body>");
printWriter.println("Request Processing Thread "+Thread.currentThread().getName());
printWriter.println("<br>");
printWriter.println("<progress id='progress' max='100')></progress>");
printWriter.println("<br>");
AsyncContext asyncCtx = request.startAsync();
asyncCtx.addListener(new AppAsyncListener());
asyncCtx.setTimeout(12000);
//release of request processing thread
asyncCtx.start(() ->{
printWriter.println("<br>");
printWriter.println("Async thread Name "+Thread.currentThread().getName());
printWriter.println("<br>");
int i=0;
while(i<100)
{
printWriter.println("<script>document.getElementById('progress').value=\""+i+"\";</script>");
printWriter.flush();
try {
Thread.sleep(100);
} catch (Exception e) {
}
i++;
}
printWriter.println("</body></html>");
asyncCtx.complete();
}
);
printWriter.println("<br>");
printWriter.println("End of response");
}
}
package com.journaldev.servlet.async;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.AsyncEvent;
import javax.servlet.AsyncListener;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebListener;
@WebListener
public class AppAsyncListener implements AsyncListener {
@Override
public void onComplete(AsyncEvent asyncEvent) throws IOException {
System.out.println("AppAsyncListener onComplete");
// we can do resource cleanup activity here
}
@Override
public void onError(AsyncEvent asyncEvent) throws IOException {
System.out.println("AppAsyncListener onError");
//we can return error response to client
}
@Override
public void onStartAsync(AsyncEvent asyncEvent) throws IOException {
System.out.println("AppAsyncListener onStartAsync");
//we can log the event here
}
@Override
public void onTimeout(AsyncEvent asyncEvent) throws IOException {
System.out.println("AppAsyncListener onTimeout");
//we can send appropriate response to client
ServletResponse response = asyncEvent.getAsyncContext().getResponse();
PrintWriter out = response.getWriter();
out.write("TimeOut Error in Processing");
}
}
这篇关于异步Servlet-首选实现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!