Problema

Muitos aplicativos personalizados chamam serviços da Web do AEM.  Esses aplicativos usam Cliente HTTP Apache Commons ou outras bibliotecas.  Quando os sistemas de back-end enfrentam problemas de desempenho, o AEM enfrenta tempos de resposta lentos.  Além disso, se muitos segmentos travarem, isso pode levar à lentidão das coletas de lixo da JVM, erros de falta de memória, esgotamento do encadeamento do sistema operacional, etc.

Ao capturar despejos de segmento ou despejos de heap do AEM, você observa muitos segmentos aguardando as chamadas de serviço da web.

Exemplo de cenário:
abaixo [1], é um exemplo de rastreamento de pilha de um Descarga do Encadeamento da JVM.  Ele foi capturado de uma instância do AEM com um aplicativo executando um serviço de back-end com desempenho ruim.

O dump de thread mostrou alguns problemas:

  • O encadeamento de solicitação abaixo estava aguardando em um serviço da web que não estava respondendo.  Nenhum tempo limite de leitura de soquete foi definido, portanto, o segmento estava aguardando para sempre.  Veja a solução aqui.
  • Centenas de segmentos aguardavam o único thread de solicitação.  Isso ocorreu porque o conjunto de encadeamentos foi configurado para ser encadeado único, enfileirado primeiro, primeiro a sair.  Ter tantos encadeamentos pendentes causou alta utilização de memória.  Veja a solução aqui.
  • O serviço da web que estava sendo chamado estava demorando muito para responder.  Isso causou a pilha de discussão acima mencionada.

Observe as linhas de pilha destacadas:

  • Em amarelo, você pode ver que o aplicativo personalizado está usando a biblioteca RestTemplate do Spring Framework para fazer uma chamada de serviço da web.  
  • Em laranja, você pode ver que o Spring Framework usa o Apache Commons HTTP Client para suas chamadas de serviço da web.  
  • Em vermelho, você pode ver que o segmento estava preso em SocketInputStream.socketRead, o que significa que está aguardando no serviço da Web uma resposta.

[1]

capture

Causa

Abaixo estão algumas causas comuns:

  1. O host de serviço da web é inacessível eo soquete "tempo limite de conexão" não está definido ou está definido por muito tempo (por exemplo, 10 minutos).
  2. O serviço da Web está ativo, mas está respondendo com um erro que não está sendo manipulado pelo aplicativo.
  3. O serviço da Web está ativo, mas está respondendo muito lento ou interrompido durante a resposta.  O soquete "tempo limite de leitura" não está definido ou está definido por muito tempo.  Threads aguardam indefinidamente por uma resposta.
  4. O conjunto de encadeamentos está configurado para permitir uma solicitação por vez.  Isso faz com que os threads de solicitação simultâneos aguardem.

Resolução

Soluções para esses problemas são os seguintes:

  1. Defina o "tempo limite de conexão" para um valor razoável, por exemplo, 3 segundos.
  2. Defina o "tempo limite de leitura" para um valor razoável.  Esse valor depende de quanto tempo você espera que as respostas sejam dadas.  Para a maioria dos pequenos serviços web, 10 segundos é razoável.  No entanto, alguns serviços da Web que fazem muito processamento ou enviam e / ou recebem arquivos grandes exigem uma configuração de tempo limite de leitura mais alta.
  3. Consulte a documentação da biblioteca do cliente httpclient ou do serviço da Web sobre como gerenciar multi-threading eficientemente.  Por exemplo, no Apache Commons Http Client 3.x, você pode consultar esta página.
  4. Armazenar em cache as respostas das chamadas de serviço.  Isso se aplica quando você está chamando o serviço usando os mesmos parâmetros e recebe o mesmo resultado mais de uma vez.
  5. Se os dados forem compartilhados (não específicos do usuário), considere chamar o serviço da Web com antecedência em um encadeamento em segundo plano e armazenar o resultado para uso posterior.  Por exemplo, use um sling job, sling scheduler ou Importador de pesquisa AEM para gerenciar um thread de segundo plano.
  6. Se você tiver um alto volume de chamadas de saída, implemente um algoritmo de recuo para lidar com falhas.  É aqui que quando o aplicativo chama o serviço e ele falha X vezes, você pára de tentar por um determinado período de tempo e relata imediatamente os erros.  Em seguida, tente X vezes novamente e, se falhar ou expire novamente, espere por mais tempo e assim por diante.  Isso geralmente é feito com um aumento exponencial no tempo de espera com um limite máximo de tempo (também conhecido como "Algoritmo de Retorno Exponencial Truncado").

Esta obra está licenciada sob uma licença não adaptada da Creative Commons Attribution-Noncommercial-Share Alike 3.0  As publicações do Twitter™ e do Facebook não são cobertas pelos termos do Creative Commons.

Avisos legais   |   Política de privacidade online