Boas Práticas do Servlet Assíncrono
O recurso de servlet assíncrono permite processar pedidos e respostas recebidos sem estar limitado ao encadeamento original que iniciou o pedido.
Considere as seguintes boas práticas ao usar os servlets assíncronos:
- Os aplicativos não devem gerar um novo encadeamento para cada operação assíncrona necessária. No mínimo, os aplicativos devem usar um conjunto de encadeamentos ou usar o método AsyncContext start(Runnable).
- Do lado do cliente/navegador, você pode usar AJAX para ativar determinadas partes da página a ser atualizada de forma assíncrona.
- O contêiner de servlet assegura que as chamadas a serem concluídas ou despachadas não sejam iniciadas até que o encadeamento do contêiner da Web que iniciou o comando startAsync exista. No entanto, o contêiner do servlet não trata de múltiplos encadeamentos usando o mesmo pedido e resposta simultaneamente. O aplicativo pode tratar de seus próprios problemas de concorrência ou sincronização neste caso, mas isso não é recomendado porque ele pode estar propenso a conflito ou condições de disputa. Se o método de despacho ou conclusão for chamado a partir de um encadeamento criado pelo cliente ou executável iniciado com start(Runnable), então o despacho ou a conclusão poderá iniciar imediatamente em um novo encadeamento e quaisquer modificações adicionais para o pedido ou resposta do encadeamento que iniciou essas chamadas serão perigosas. Dois encadeamentos terão acesso ao pedido e à resposta, que podem ter resultados indeterminados se ambos os encadeamentos estiverem modificando esses objetos. Portanto, não chame nenhum método no pedido ou na resposta após um despacho a partir do mesmo encadeamento que chamou o despacho. Não chame nenhum método no pedido ou na resposta depois que uma operação completa for chamada.
- Os listeners assíncronos possuem um método onTimeout que é iniciado quando um limite de tempo é atingido para a
operação assíncrona. Entretanto, a operação assíncrona ainda pode estar em execução em um encadeamento enquanto onTimeout
é executado em um encadeamento diferente. Esse cenário é a maneira mais comum de que diversos encadeamentos usam
acidentalmente o mesmo pedido e resposta simultaneamente. Uma abordagem simples para este cenário é usar um método AtomicBoolean compartilhado a partir de AsyncListener e da operação assíncrona, como a seguir:
Com esta abordagem, apenas um encadeamento pode obter acesso para gravar a resposta.AtomicBoolean isOkayToRun = (AtomicBoolean) request.getAttribute("isOkayToRun"); if (isOkayToRun.setAndGet(false)){ //do a dispatch }
- O contêiner da Web tenta cancelar quaisquer executáveis que estejam enfileirados por chamadas para o método start(Runnable) quando o tempo limite é atingido. Entretanto, os executáveis que já foram iniciados não poderão ser interrompidos porque a interrupção gerará um vazamento de memória.
- O número de encadeamentos que fazem as notificações de tempo limite é muito pequeno. Tentar qualquer operação intensa ou qualquer operação de gravação a partir de um tempo limite não é recomendado, pois mesmo uma pequena operação de gravação pode demorar um pouco, se o cliente tiver uma conexão lenta. Ao desativar o tempo limite assíncrono, é mais fácil passar por erros de OutOfMemory ou esgotar o número conexões de canal TCP. O tempo limite padrão é de 30 segundos.
- É possível configurar algumas opções de servlet assíncrono, como as configurações de tempo limite e o método AsyncContext start(Runnable), no console administrativo clicando em . Consulte o tópico de configurações de contêiner da Web para aprender sobre a configuração do contêiner da Web.
Importante: O Asynchronous Request Dispatcher (ARD) e o Remote Request Dispatcher (RRD) não são suportados
quando estiver usando servlets assíncronos.
Dica: Visualize o tópico de contadores de aplicativos da Web para aprender sobre métricas para servlets
assíncronos.