aumentando a eficiência do web container usando chamadas assíncronas
DESCRIPTION
Palestra apresentada na track Java do TDC2012 edição Goiânia.TRANSCRIPT
Globalcode – Open4education
Trilha – Java
Rafael Torres Coelho Soares (Tuelho)[email protected]
@rafaeltuelho
Aumentando a eficiência do Web Container usando chamadas Assíncronas
Globalcode – Open4education
Agenda
Web 2.0
Web Assíncrona
Servlet 3.0 (JSR 315)
Demo
Globalcode – Open4education
Tuelho
Trabalho com Java desde 2004Desenvolvimento (back-end)
Infraestrutura Java
JBoss.orgrhq-project (contributor)
Red Hat (2010-2012)Serviços e consultoria
Oracle Fusion MiddlewareWeblogic Application Server (consultoria)
Globalcode – Open4education
Web interativa
Globalcode – Open4education
Web 2.0 (mais interativa e dinâmica)
Globalcode – Open4education
Novas tecnologias
Globalcode – Open4education
Novos modelos de comunicação
Server events
Client asynchronous requests
pooling
push
Globalcode – Open4education
Server busy!
Globalcode – Open4education
Comunicação HTTP
thread per connectionBaseado no http 1.1 (persistent connection)
thread per request modelnon-blocking I/O (NIO) – Java 1.4
Globalcode – Open4education
WebServer
Http Thread Pool
T#1
T#2
T#6
T#3
T#5T#
4
thread-per-connection
idle
Http Connection
T#5
response
request active
Keep alive timeout… ouConnection timeout
c1c1 c1
Connection Queue(backlog)
C#C1#
Globalcode – Open4education
c1c1 c1
thread-per-request
WebServer
Http Thread Pool
T#1
T#2
T#6
T#3
T#5T#
4 idle
T#5Response #1
Request #1 active
request #2
T#1Response #2
Response time…
Connection Queue(backlog)
C#C1#
Globalcode – Open4education
Web Assíncrona: problemas e motivações
Long Running Requests
Real time updates
Globalcode – Open4education
Servlet 3.0: melhorias
JSR 315 (2009)Asynchronous support
Ease of configuration
Annotations
Pluggability/Modularization: web fragments
Enhancements to existing APIs
Globalcode – Open4education
Async Context
Javax.servlet.AsyncContext.start()
“Causes the container to dispatch a thread, possibly from a managed thread pool, to run the specified Runnable.”
e daí? O que faço com isso?
Globalcode – Open4education
Ciclo de uma requsição assíncrona
① Cliente envia uma requisição
② Servidor invoca um Servlet (nova thread alocada)
③ O Servlet invoca request.startAsync(), salva AsyncContext, e
retorna
④ A thread alocada é liberada, mas o response permanece aberto
⑤ Outra thread (pool separado) utiliza o AsyncContext para concluir a
resposta (asyncContext.complete() ou
asyncContext.dispatch())
⑥ Cliente recebe a resposta do servidor.
Globalcode – Open4education
Processamento assíncrono
WebServer
Http Thread Pool
T#5T#2
T#6
T#3
T#4 idle
T#5
Response
Request active Servlet Context
Managed Thread Pool
request.startAsync()
asyncContext.complete()
1
3
2
5
6
4
Globalcode – Open4education
Sample code
@WebServlet(name = "MyAsyncServlet", urlPatterns = {"/MyAsyncServlet"}, asyncSupported = true)public class MyAsyncServlet extends HttpServlet {
public void doGet(...) { final AsyncContext asyncContext = request.startAsync();
asyncContext.start(new Runnable() { @ Override public void run() { // do some work here which involves waiting ... asyncContext.complete(); } });}
Globalcode – Open4education
JavaSE 5 Executor Framework
Globalcode – Open4education
JavaSE 5 Executor Framework: conceitos
Task
Runnable
Callable
Thread
Synchronous processing
Asynchronous processing
Thread pool
ExecutorService
ThreadPoolExecutor
SchedulePoolExecutor
Globalcode – Open4education
ThreadPoolExecutor
Thread pool
Work queue
Bounded
Unbounded
Handler (saturation policy)
Defaults: RejectedExecutionException runtime exception
Thread Factory
Globalcode – Open4education
Executor: main steps
① Criar uma instância de Executor
② Criar uma taskRunnable ou Callable
③ Submeter a task para execução
④ Executar a task
⑤ Finalizar o Executor
Globalcode – Open4education
ServletContextListener@WebListenerpublic class ServletContextListener implements javax.servlet.ServletContextListener { @Override public void contextInitialized(ServletContextEvent sce) { Executor executor = new ThreadPoolExecutor(10, 100, 60000L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(100)); sce.getServletContext(). setAttribute("threadPoolExecutor", executor); }
@Override public void contextDestroyed(ServletContextEvent sce) { ThreadPoolExecutor executor = (ThreadPoolExecutor)sce.getServletContext() .getAttribute("threadPoolExecutor"); executor.shutdownNow(); }}
Globalcode – Open4education
MyAsyncServlet
protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try { AsyncContext asyncCtx = request.startAsync(); ThreadPoolExecutor executor = (ThreadPoolExecutor) request.getServletContext(). getAttribute("threadPoolExecutor"); asyncCtx.setTimeout(-1L); asyncCtx.addListener(new ServletAsyncListener());
//delegate long running process to an "async" thread executor.execute(new AsyncTask(asyncCtx)); } finally { }}
Globalcode – Open4education
AsyncTask (Runnable instance)public class AsyncTask implements Runnable { private AsyncContext asyncContext;
public AsyncTask(AsyncContext asyncContext) { this.asyncContext = asyncContext; }
@Override public void run() { // acesso remoto, query, processamento pesado // escreve na resposta… asyncContext.complete(); // ou asyncContext.dispatch(); }}
Globalcode – Open4education
Demo: sync vs. async
Requisição Servlet Rest Service
Rest
Globalcode – Open4education
… mas eu não uso servlet
JEE 6EJB @Asynchronous
CDI Events
JSF Component FrameworkPrimefaces/RichFaces
ServerPush com Atmosphere
Ajax Pooling
JEE 7Java Websocket Spec (JSR 356)
Globalcode – Open4education
Web Assíncrona: implementações
CometTraditional pooling
Long pooling
Http Streaming
WebSocket protocol
Algumas implementações alternativasAtmosphere Framework (github.com/Atmosphere/)
Tomcat: CometProcessor class
Jetty 6: Continuations
Grizzly (glassfish): CometEngine class.
Globalcode – Open4education
DÚVIDAS?