Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Use uma fila que funcione como um buffer entre uma tarefa e o serviço que ela invoca. Esta abordagem suaviza cargas pesadas intermitentes que podem causar falhas no serviço ou a expiração da tarefa. Ajuda a minimizar o efeito dos picos de procura na disponibilidade e na capacidade de resposta da tarefa e do serviço.
Contexto e problema
Muitas soluções na cloud executam tarefas que invocam serviços. Neste ambiente, cargas pesadas intermitentes podem causar problemas de desempenho ou fiabilidade para um serviço.
Um serviço pode fazer parte da mesma solução das tarefas que o utilizam, ou pode ser um serviço parceiro que fornece acesso a recursos frequentemente utilizados. Exemplos destes tipos de serviços incluem uma cache ou um serviço de armazenamento. Quando várias tarefas são executadas em simultâneo e usam o mesmo serviço, é difícil prever o volume de pedidos em qualquer momento.
Um serviço pode experienciar picos de procura que o sobrecarreguem e tornem o serviço incapaz de responder rapidamente a pedidos. Sobrecarregar um serviço com muitos pedidos concorrentes também pode fazer com que o serviço falhe se este não conseguir lidar com a contenção causada por esses pedidos.
Solução
Coloque uma fila entre a tarefa e o serviço. A tarefa e o serviço são executados de forma assíncrona. A tarefa coloca na fila uma mensagem que contém os dados de que o serviço necessita. A fila atua como um buffer e armazena a mensagem até que o serviço a recupere. O serviço recupera mensagens da fila e processa-as. Pedidos de múltiplas tarefas, que podem ser gerados a taxas altamente variáveis, podem ser encaminhados para o serviço através da mesma fila de mensagens. O diagrama seguinte mostra como uma fila pode nivelar a carga de um serviço.
A fila desacopla as tarefas do serviço para que este possa tratar as mensagens ao seu próprio ritmo, mesmo quando tarefas concorrentes geram um elevado volume de pedidos. Além disso, as tarefas não sofrem atrasos se o serviço não estiver disponível ao publicarem mensagens para a fila.
Este padrão fornece os benefícios seguintes:
Ajuda a maximizar a disponibilidade porque atrasos no serviço não afetam imediatamente e diretamente a aplicação. A aplicação pode continuar a publicar mensagens na fila mesmo quando o serviço não está disponível ou não está atualmente a processar mensagens.
Ajuda a maximizar a escalabilidade porque o número de filas e o número de serviços podem variar para responder à procura.
Ajuda a controlar custos porque só precisa de instâncias de serviço suficientes para satisfazer os requisitos de uma carga média em vez da carga máxima.
Observação
Alguns serviços aplicam limitação quando a procura atinge um limiar suscetível de causar falha do sistema. A limitação pode reduzir a funcionalidade disponível. Implemente o nivelamento de carga nestes serviços para garantir que a procura não atinja esse limiar.
Problemas e considerações
Considere os seguintes pontos ao decidir como implementar este padrão:
Implemente lógica de aplicação que controle a taxa a que os serviços tratam mensagens para evitar sobrecarregar o recurso alvo. Evite propagar picos na procura para a etapa seguinte do sistema. Teste o sistema sob carga para garantir que fornece o nivelamento necessário. Para alcançar o nivelamento necessário, ajusta o número de filas e o número de instâncias de serviço que tratam mensagens.
As filas de mensagens são um mecanismo de comunicação unidirecional. Se uma tarefa espera uma resposta de um serviço, pode ser necessário implementar um mecanismo que o serviço possa usar para enviar uma resposta. Para mais informações, consulte as opções de mensagens Assíncronas em Azure.
O escalonamento automático sem limitar a taxa agregada de saída dos consumidores apenas transfere a sobrecarga para as dependências a jusante. Esta sobrecarga pode aumentar a contenção pelos recursos que estes serviços partilham e diminuir a eficácia da fila para nivelar a carga.
Se a sua taxa média de produtor ultrapassar a taxa do consumidor, a fila continua a crescer e a latência aumenta. Monitorize a profundidade da fila e aumente o número de consumidores dentro de limites seguros, ou reduza a carga no produtor.
Este padrão depende da durabilidade da fila para evitar a perda de mensagens. Se o intermediário de mensagens não persistir as mensagens em armazenamento durável, uma falha ou um limite de capacidade pode fazer com que os dados em fila se percam antes de os consumidores os processarem. Escolha um serviço de fila que grave mensagens em disco ou em armazenamento com replicação e compreenda as suas quotas de tamanho e limites de retenção. Para cargas de trabalho que exigem que as mensagens sobrevivam a falhas regionais, avalie as opções de recuperação após desastre geográfico.
A maioria dos serviços de fila entrega mensagens com pelo menos uma semântica, o que significa que os consumidores podem receber a mesma mensagem mais do que uma vez. Conceber a lógica do consumidor para ser idempotente, de modo que o processamento da mesma mensagem várias vezes produza o mesmo resultado e evite problemas como registos duplicados ou cobranças repetidas.
Algumas mensagens não podem ser processadas porque contêm dados deformados, referenciam recursos em falta ou desencadeiam erros persistentes. Em vez de deixar estas mensagens circularem indefinidamente e bloquear a fila, encaminhe-as para uma fila de letras mortas. Monitorize a dimensão da fila de mensagens mortas para que a sua equipa de operações possa investigar as falhas, corrigir o problema subjacente e reenviar as mensagens quando adequado.
Introduzir uma fila entre um produtor e um consumidor não preserva a ordem de submissão original em todas as condições, especialmente quando vários consumidores processam mensagens em paralelo. Se a sua carga de trabalho exigir uma ordenação rigorosa, utilize funcionalidades como sessões de mensagens no Azure Service Bus. Se não for necessária uma ordenação estrita, conceba os consumidores para tratarem as mensagens por qualquer ordem, o que simplifica a escalabilidade.
Quando utilizar este padrão
Utilize este padrão quando:
A sua carga de trabalho sofre picos intermitentes que podem sobrecarregar os serviços a jusante.
É necessário desacoplar a entrada de pedidos do throughput de processamento para melhorar a resiliência e o controlo de custos.
Este padrão pode não ser adequado quando:
O chamador requer uma resposta síncrona e de baixa latência.
O volume de carga de trabalho é previsivelmente baixo e estável, pelo que adicionar complexidade de fila traz pouco benefício.
Design da carga de trabalho
Avalie como utilizar o padrão de nivelamento de carga baseado em filas na conceção de uma carga de trabalho para cumprir os objetivos e princípios descritos nos pilares do Azure Well-Architected Framework. A tabela a seguir fornece orientação sobre como esse padrão suporta as metas de cada pilar.
| Pilar | Como esse padrão suporta os objetivos do pilar |
|---|---|
| As decisões de projeto de confiabilidade ajudam sua carga de trabalho a se tornar resiliente ao mau funcionamento e garantem que ela se recupere para um estado totalmente funcional após a ocorrência de uma falha. | A abordagem que este padrão descreve pode proporcionar resiliência contra picos súbitos de procura ao desacoplar a chegada de tarefas do seu processamento. Ele também pode isolar falhas no processamento de filas para que elas não afetem a entrada. - RE:06 Dimensionamento |
| A Otimização de Custos foca-se em manter e melhorar o retorno do investimento da sua carga de trabalho. | Como o processamento de carga é dissociado da solicitação ou da entrada de tarefas, você pode usar essa abordagem para reduzir a necessidade de provisionar recursos em excesso para lidar com a carga de pico. - CO:12 Custos de escala |
| A Eficiência de Desempenho ajuda sua carga de trabalho a atender às demandas de forma eficiente por meio de otimizações em escala, dados e código. | Esta abordagem permite um design intencional para o desempenho do throughput porque a receção de pedidos não precisa de se correlacionar com a taxa de processamento. - PE:05 Dimensionamento e particionamento |
Se este padrão introduzir compensações dentro de um pilar, considere-as em relação aos objetivos dos outros pilares.
Example
Um aplicativo Web grava dados em um armazenamento de dados externo. Se várias instâncias da aplicação web correrem em simultâneo, o armazenamento de dados pode não conseguir responder a pedidos com rapidez suficiente, o que faz com que os pedidos expirem, sejam limitados ou falhem de outra forma. O diagrama seguinte mostra um armazenamento de dados sobrecarregado por pedidos simultâneos de instâncias de uma aplicação.
Para resolver este problema, use uma fila para nivelar a carga entre as instâncias da aplicação e o armazenamento de dados. Uma aplicação do Funções do Azure lê mensagens de uma fila do Service Bus e efetua pedidos de leitura e escrita no armazenamento de dados. O Funções do Azure pode escalar instâncias com base no backlog do Service Bus usando escalabilidade baseada em alvo, dentro dos seus limites de escalabilidade configurados. Também pode ajustar as definições de concorrência dos gatilhos para proteger o armazenamento de dados. Para orientações de implementação, consulte Dimensionamento baseado em destino e Limitar a expansão horizontal. Sem este ajuste, a camada de processamento pode reintroduzir contenção no back-end.
Como variação tecnológica, pode implementar o mesmo padrão usando Azure Container Apps em vez do Funções do Azure. Nessa abordagem, um trabalhador contentorizado consome mensagens de Service Bus e escreve no armazenamento de dados. O Container Apps escala o worker entre réplicas mínimas e máximas configuradas com base nas regras de escala relacionadas com a fila. Também pode implementar a mesma abordagem usando Armazenamento de Filas do Azure como fonte de eventos. Para orientações de implementação, consulte Definir regras de escalonamento em Aplicações Container e Implementar um trabalho orientado a eventos usando Aplicações Container.
Passos seguintes
As seguintes orientações também podem ser relevantes ao implementar este padrão:
Opções de mensagens assíncronas em Azure: As filas de mensagens são inerentemente assíncronas. Pode ser necessário redesenhar a lógica da aplicação de uma tarefa, caso esta comunique diretamente com um serviço. De forma semelhante, pode ser necessário refatorar um serviço para aceitar pedidos de uma fila de mensagens.
Escolha entre os serviços de mensagens do Azure: Obtenha mais informações para o ajudar a escolher um mecanismo de mensagens e de colocação em fila em aplicações do Azure.
Recomendações para desenvolver trabalhos em segundo plano: Aplique este padrão a trabalhos em segundo plano para que as filas de mensagens possam armazenar pedidos para tarefas em segundo plano quando a aplicação sofre grande carga.
Estilo de arquitetura Web-Queue-Worker: A aplicação Web e o worker não têm estado. O estado da sessão pode ser armazenado numa cache distribuída. O processo de trabalho executa tarefas de longa duração de forma assíncrona e pode ser acionado por mensagens na fila ou executado de acordo com uma programação para processamento em lote.
Recursos relacionados
Padrão de Consumidores Concorrentes: Pode ser possível executar múltiplas instâncias de um serviço, cada uma atuando como consumidor de mensagens da fila de nivelamento de carga. Pode utilizar esta abordagem para ajustar a velocidade a que as mensagens são recebidas e transmitidas para um serviço.
Padrão de limitação: Uma forma simples de implementar a limitação num serviço é usar nivelamento de carga baseado em fila e encaminhar todos os pedidos para um serviço através de uma fila de mensagens. O serviço pode processar pedidos a uma taxa que garante que não esgota os recursos necessários e reduz a quantidade de possíveis contendas.