Padrão de Fila de Prioridade

Priorize os pedidos enviados aos serviços para que uma carga de trabalho processe pedidos de alta prioridade mais rapidamente do que os de menor prioridade. Esta abordagem utiliza mensagens enviadas para uma ou mais filas e é útil para aplicações que fornecem diferentes níveis de serviço ou acordos de nível de serviço (SLAs) a diferentes tipos de pedidos ou clientes.

Contexto e problema

As cargas de trabalho podem precisar de gerir e processar tarefas com diferentes níveis de importância e urgência. Algumas tarefas requerem atenção imediata, enquanto outras podem esperar. A falha em abordar tarefas de alta prioridade pode afetar a experiência do utilizador e violar SLAs.

Para tratar as tarefas de forma eficiente com base na sua prioridade, as cargas de trabalho precisam de um mecanismo para processar e executar as tarefas em conformidade. Por predefinição, a maioria das cargas de trabalho processa as tarefas pela ordem em que chegam, utilizando uma estrutura de fila do tipo primeiro a entrar, primeiro a sair (FIFO). Esta abordagem não tem em conta a importância variável da tarefa.

Solução

As filas de prioridade permitem que as cargas de trabalho processem tarefas com base na sua prioridade, em vez de estritamente pela ordem de chegada. A aplicação ou produtor que envia um pedido atribui um valor de prioridade à mensagem, e os consumidores processam as mensagens por prioridade. O padrão Priority Queue responde aos seguintes requisitos:

  • Trata tarefas de diferentes urgências e importâncias: Tens tarefas com diferentes níveis de urgência e importância e precisas de garantir que processas tarefas mais críticas antes das menos críticas.

  • Lida com diferentes SLAs: Oferece diferentes SLAs a diferentes clientes e precisa de garantir que os clientes de alta prioridade recebam melhor desempenho e disponibilidade.

  • Acomoda diferentes necessidades de gestão de carga de trabalho: Tens uma carga de trabalho que precisa de tratar de certas tarefas imediatamente, enquanto tarefas menos urgentes podem esperar.

Há duas abordagens principais para implementar o padrão de fila de prioridade:

  • Fila única: Cada mensagem recebe um valor de prioridade, e todas as mensagens usam a mesma fila.

  • Múltiplas filas: Cada mensagem recebe um valor de prioridade, e as mensagens de prioridade diferente usam filas separadas.

Fila única

Numa abordagem de fila única, a aplicação atribui uma prioridade a cada mensagem e envia todas as mensagens para uma única fila. A fila ordena mensagens por prioridade, garantindo que os consumidores processem mensagens de prioridade mais alta antes de mensagens de prioridade mais baixa.

Diagrama que ilustra um mecanismo de fila que suporta a priorização de mensagens.

Várias filas

Múltiplas filas separam as mensagens por prioridade. A aplicação atribui uma prioridade a cada mensagem e direciona a mensagem para a fila correspondente à sua prioridade, onde os consumidores processam as mensagens. Uma solução de múltiplas filas pode usar um único grupo de consumidores ou múltiplos grupos de consumidores.

Agrupamento único de consumidores

Numa configuração de pool única, todas as filas partilham o mesmo pool de consumidores. Os consumidores processam as mensagens da fila de prioridade mais alta primeiro e processam as mensagens das filas de prioridade mais baixa apenas quando não há mais mensagens de alta prioridade. Como resultado, os pools de um único consumidor processam sempre mensagens de maior prioridade antes das de menor prioridade. Esta configuração pode levar a que mensagens de menor prioridade sejam continuamente atrasadas e potencialmente nunca processadas.

Diagrama que ilustra o uso de um único grupo de consumidores para todas as prioridades.

Utilize um único grupo de consumidores pelas seguintes razões:

  • Gestão simples. Use um único grupo de consumidores quando a instalação e manutenção facilitadas são prioridade. Um único pool reduz a complexidade da configuração e monitorização.

  • Necessidades de processamento unificado. Use um único grupo de consumidores quando as tarefas recebidas forem semelhantes em tipo.

Vários grupos de consumidores

Num conjunto de consumidores múltiplos, cada fila tem um conjunto dedicado de consumidores. As filas de prioridade mais elevada utilizam mais consumidores ou níveis de desempenho superiores para processar mensagens mais rapidamente do que filas de prioridade mais baixa.

Diagrama que ilustra o uso de pools de consumidores separados para cada prioridade.

Use múltiplos grupos de consumidores pelas seguintes razões:

  • Requisitos rigorosos de desempenho. Use múltiplos pools de consumidores quando diferentes prioridades de tarefas têm requisitos rigorosos de desempenho que devem ser cumpridos de forma independente.

  • Necessidades de alta fiabilidade. Utilize múltiplos pools de consumidores para aplicações quando a fiabilidade e o isolamento de falhas são críticos, e os problemas numa fila não devem afetar outras filas.

  • Aplicações complexas. Utilize múltiplos pools de consumidores para aplicações complexas onde diferentes tarefas exigem características de processamento e garantias de desempenho distintas.

Problemas e considerações

Considere os seguintes pontos ao decidir como implementar esse padrão:

Recomendações gerais

  • Definir prioridades com clareza. Estabeleça níveis de prioridade distintos e claros que sejam relevantes para a sua solução. Por exemplo, pode definir mensagens de alta prioridade como aquelas que requerem processamento em 10 segundos. Identifique os requisitos dos consumidores para o tratamento de itens de alta prioridade e aloque os recursos necessários em conformidade.

  • Ajuste os grupos de consumidores dinamicamente. Escala o tamanho dos pools de consumidores com base no comprimento da fila que estão a servir.

  • Monitoriza a saúde da fila. Acompanhe a profundidade da fila, a latência de processamento, a contagem de entregas e a taxa de processamento para detetar acumulações e abrandamentos antes de afetarem o trabalho.

  • Utilize filas de mensagens não entregues. Mover as mensagens venenosas para uma fila de letras mortas após um número configurável de tentativas de entrega, para que uma mensagem má não bloqueie o caminho de prioridade.

  • Priorize os níveis de serviço. Implemente filas prioritárias para atender às necessidades de negócios que exigem disponibilidade ou desempenho priorizados. Por exemplo, clientes de alta prioridade podem receber um nível de serviço superior para terem melhor desempenho e disponibilidade.

  • Considere o processamento de baixa prioridade. Decida se todos os itens de alta prioridade devem ser processados antes dos itens de menor prioridade. Se possível, aumente dinamicamente a prioridade das mensagens antigas para garantir que as mensagens de baixa prioridade sejam eventualmente processadas.

  • Otimize e minimize custos. Processe tarefas críticas imediatamente com os consumidores disponíveis. Agende tarefas em segundo plano menos críticas durante horários menos movimentados.

    Se usar uma única fila, otimize os custos reduzindo o número de consumidores. Mensagens de alta prioridade processam-se primeiro, mas possivelmente mais lentamente, enquanto mensagens de menor prioridade podem enfrentar atrasos mais longos.

  • Proteger os processadores contra picos de procura. Se a taxa de chegada do produtor puder exceder a capacidade de processamento do consumidor, combine este padrão com o padrão de nivelamento de carga baseado em filas. Esta abordagem armazena os surtos de tráfego e ajuda a evitar que os recursos de processamento a jusante sobrecarreguem.

Recomendações para várias filas

  • Monitore as velocidades de processamento. Para garantir que as mensagens são processadas às taxas esperadas, monitorize continuamente a velocidade de processamento das filas de alta e baixa prioridade.

  • Implementar preempção e suspensão. Se usar várias filas com um único pool de consumidores, implemente um algoritmo que garanta que as filas de alta prioridade são sempre atendidas antes das filas de menor prioridade.

  • Considere os custos da fila. Esteja atento aos custos financeiros associados às filas de verificação e processamento. Alguns serviços de fila cobram taxas pela publicação, recuperação e consulta de mensagens. Estas taxas podem aumentar com o número de filas.

Quando utilizar este padrão

Utilize este padrão quando:

  • Tem de cumprir diferentes objetivos de latência ou de nível de serviço para diferentes tipos de carga de trabalho, como pedidos de clientes premium face a pedidos de clientes padrão.

  • O trabalho chega em rajadas, e deve proteger operações críticas processando primeiro mensagens de alta prioridade, adiando trabalhos de menor prioridade.

Este padrão pode não ser adequado quando:

  • Todos os itens de trabalho têm importância empresarial semelhante, e o processamento rigoroso do FIFO é mais importante do que o agendamento baseado em prioridades.

  • As tarefas têm fortes dependências de ordenação entre os níveis de prioridade, e reordenar o trabalho por prioridade pode causar resultados inconsistentes ou exigir uma lógica de coordenação complexa.

Design da carga de trabalho

Avalie como utilizar o padrão de Fila de Prioridade no design de uma carga de trabalho para abordar os objetivos e princípios abordados 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 a garantir que ela se recupere para um estado totalmente funcional após a ocorrência de uma falha. Separar os itens com base na prioridade de negócios permite que você concentre os esforços de confiabilidade no trabalho mais crítico.

- RE:02 Fluxos críticos
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. Separar os itens com base na prioridade do negócio permite que você concentre os esforços de desempenho no trabalho mais sensível ao tempo.

- PE:09 Fluxos críticos

Se este padrão introduzir compensações dentro de um pilar, considere-as em relação aos objetivos dos outros pilares.

Exemplos:

O exemplo do padrão Priority Queue no GitHub demonstra uma implementação do padrão Priority Queue que utiliza tópicos e subscrições do Azure Service Bus. O exemplo implementa uma conta de armazenamento segura, um recurso Application Insights para monitorização e um namespace Service Bus para permitir a comunicação entre as funções do remetente e do consumidor.

A implementação inclui três aplicações funcionais: um remetente e dois consumidores. As aplicações de consumo utilizam diferentes contagens máximas de instâncias para simular a priorização de mensagens. A função funcPriorityQueueConsumerHigh pode expandir até 200 instâncias, enquanto a função funcPriorityQueueConsumerLow está limitada a 40 instâncias. Todas as aplicações funcionais utilizam o plano de consumo Flex e estão ligadas ao Application Insights para diagnóstico e monitorização.

As atribuições de funções concedem acesso seguro ao Service Bus e armazenamento através do uso de identidades geridas. Todas as aplicações funcionais partilham a mesma conta de armazenamento e o mesmo recurso Application Insights. Esta configuração centraliza a observabilidade e o registo.

O diagrama seguinte mostra a arquitetura da fila de prioridade:

Diagrama que mostra como implementar uma fila de prioridade usando o Service Bus.

No diagrama anterior:

  1. Aplicação (produtor). A PriorityQueueSender aplicação cria mensagens, atribui uma propriedade personalizada chamada Priority a cada mensagem e define o Priority valor como High ou Low.

  2. Corretor de mensagens e tema. O broker de mensagens do Service Bus envia mensagens para um único tópico do Service Bus chamado messages. O Service Bus utiliza filtros SQL para encaminhar cada mensagem para a subscrição de alta ou baixa prioridade, com base no seu Priority valor.

  3. Múltiplos grupos de consumidores. Os agrupamentos de consumidores PriorityQueueConsumerHigh e PriorityQueueConsumerLow respondem a mensagens das subscrições de prioridade elevada ou reduzida utilizando os acionadores do Service Bus do Funções do Azure .

Papel no exemplo Serviço Azure no exemplo Nome no exemplo
Aplicação (produtor) Aplicação de Funções do Azure PriorityQueueSender
Corretor de mensagens Azure Service Bus <o namespace do seu barramento de serviço>
Tema da mensagem Tópico do Azure Service Bus messages
Subscrições de mensagens Subscrições do Azure Service Bus highPriority
lowPriority
Consumidores Aplicação de Funções do Azure PriorityQueueConsumerHigh
PriorityQueueConsumerLow

Passos seguintes

Os seguintes padrões podem ser úteis ao implementar este padrão:

  • Padrão de nivelamento de carga baseado em filas: Utilize uma fila como buffer entre a receção de pedidos e o respetivo processamento. Usa-o com o padrão Priority Queue quando precisares tanto de proteção contra rajadas como de manuseamento diferenciado.

  • Padrão de Consumidores Concorrentes: Implementar múltiplos consumidores que ouçam a mesma fila e processem tarefas em paralelo para aumentar o rendimento. Apenas um consumidor processa cada mensagem.

  • Padrão de limitação: Implemente a limitação usando filas para gerir as taxas de pedido. Use mensagens prioritárias para priorizar pedidos de aplicações críticas ou clientes de alto valor em detrimento de clientes menos importantes.