Padrão de fila de prioridade

Priorize as solicitações enviadas aos serviços para que uma carga de trabalho processe solicitações de alta prioridade mais rapidamente do que as de prioridade mais baixa. Essa abordagem usa mensagens enviadas para uma ou mais filas e é útil para aplicativos que fornecem diferentes níveis de serviço ou SLAs (contratos de nível de serviço) para diferentes tipos de solicitação ou clientes.

Contexto e problema

As cargas de trabalho podem precisar gerenciar 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 ao lidar com tarefas de alta prioridade pode afetar a experiência do usuário e violar SLAs.

Para lidar com tarefas com eficiência com base em sua prioridade, as cargas de trabalho precisam de um mecanismo para processar e executar tarefas adequadamente. Por padrão, a maioria das cargas de trabalho processa tarefas na ordem em que chegam, usando uma estrutura de fila de primeiro a entrar e sair (FIFO). Essa abordagem não considera a importância da tarefa variável.

Solução

As filas de prioridade permitem que as cargas de trabalho processem tarefas com base em sua prioridade, em vez de estritamente por sua ordem de chegada. O aplicativo ou produtor que envia uma solicitação atribui um valor de prioridade à mensagem e os consumidores processam as mensagens por prioridade. O padrão fila de prioridade atende aos seguintes requisitos:

  • Lida com tarefas de urgência e importância variáveis: Você tem tarefas com diferentes níveis de urgência e importância e precisa garantir que você processe tarefas mais críticas antes das menos críticas.

  • Lida com SLAs diferentes: Você oferece SLAs diferentes para clientes diferentes e precisa garantir que os clientes de alta prioridade recebam melhor desempenho e disponibilidade.

  • Acomoda diferentes necessidades de gerenciamento de carga de trabalho: Você tem uma carga de trabalho que precisa lidar com determinadas 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.

  • Várias filas: Cada mensagem recebe um valor de prioridade e mensagens de prioridade diferente usam filas separadas.

Fila única

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

Diagrama ilustrando um mecanismo de enfileiramento que dá suporte à priorização de mensagens.

Várias filas

Várias filas separam mensagens por prioridade. O aplicativo atribui uma prioridade a cada mensagem e direciona a mensagem para a fila que corresponde à sua prioridade, em que os consumidores processam as mensagens. Uma solução de várias filas pode usar um único pool de consumidores ou vários pools de consumidores.

Pool de consumidores únicos

Em uma única configuração de pool, todas as filas compartilham o mesmo pool de consumidores. Os consumidores processam mensagens da fila de prioridade mais alta primeiro e processam mensagens de filas de menor prioridade somente quando não há mais mensagens de alta prioridade. Como resultado, os pools de consumidores únicos sempre processam mensagens de prioridade mais alta antes das de menor prioridade. Essa configuração pode levar a mensagens de menor prioridade sendo continuamente atrasadas e potencialmente nunca processadas.

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

Use um único pool de consumidores pelos seguintes motivos:

  • Gerenciamento simples. Use um único pool de consumidores quando a instalação e a manutenção fáceis forem uma prioridade. Um único pool reduz a complexidade de configuração e monitoramento.

  • Necessidades de processamento unificadas. Use um único pool de consumidores quando as tarefas de entrada forem semelhantes no tipo.

Vários pools de consumidores

Em um pool de vários consumidores, cada fila tem um pool de consumidores dedicado. Filas de prioridade mais alta usam mais consumidores ou camadas de desempenho mais altas 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 vários pools de consumidores pelos seguintes motivos:

  • Requisitos de desempenho estritos. Use vários pools de consumidores quando diferentes prioridades de tarefa tiverem requisitos de desempenho estritos que devem ser atendidos de forma independente.

  • Necessidades de alta confiabilidade. Use vários pools de consumidores para aplicativos quando a confiabilidade e o isolamento de falhas forem críticos e os problemas em uma fila não devem afetar outras filas.

  • Aplicativos complexos. Use vários pools de consumidores para aplicativos complexos em que diferentes tarefas exigem diferentes características de processamento e garantias de desempenho.

Problemas e considerações

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

Recomendações gerais

  • Defina as prioridades com clareza. Estabeleça níveis de prioridade distintos e claros relevantes para sua solução. Por exemplo, você pode definir mensagens de alta prioridade como aquelas que exigem processamento dentro de 10 segundos. Identifique os requisitos do consumidor para lidar com itens de alta prioridade e aloque os recursos necessários adequadamente.

  • Ajuste os grupos de consumidores dinamicamente. Dimensione o tamanho dos pools de consumidores com base no comprimento da fila que eles estão atendendo.

  • Monitore a integridade da fila. Acompanhe a profundidade da fila, a latência de processamento, a contagem de entrega e a taxa de transferência para que você possa detectar pendências e lentidão antes que elas afetem o trabalho.

  • Use filas de mensagens mortas. Mova mensagens suspeitas para uma fila de mensagens mortas após um número configurável de tentativas de entrega para que uma mensagem incorreta 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, os clientes de alta prioridade podem receber um nível de serviço mais alto para que eles experimentem melhor desempenho e disponibilidade.

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

  • Otimize e minimize os 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 você usar uma única fila, otimize os custos redimensionando o número de consumidores. Mensagens de alta prioridade processam primeiro, mas possivelmente mais lentamente, enquanto mensagens de prioridade mais baixa podem enfrentar atrasos mais longos.

  • Proteja os processadores contra picos de demanda. Se a taxa de chegada do produtor puder exceder a capacidade de processamento do consumidor, combine esse padrão com o padrão Queue-Based Load Leveling. Essa abordagem armazena em buffers intermitências de tráfego e ajuda a impedir que os recursos de processamento downstream sobrecarreguem.

Várias recomendações de fila

  • Monitore as velocidades de processamento. Para garantir que as mensagens sejam processadas com as taxas esperadas, monitore continuamente a velocidade de processamento de filas de alta e baixa prioridade.

  • Implemente preempção e suspensão. Se você usar várias filas com um único pool de consumidores, implemente um algoritmo que garanta que filas de alta prioridade sejam sempre atendidas antes das filas de prioridade mais baixa.

  • Considere os custos da fila. Lembre-se dos custos financeiros associados às filas de verificação e processamento. Alguns serviços de fila cobram taxas por postar, recuperar e consultar mensagens. Essas taxas podem aumentar com o número de filas.

Quando usar esse padrão

Use esse padrão quando:

  • Você deve atender a diferentes objetivos de latência ou de nível de serviço para diferentes classes de trabalho, como solicitações premium versus padrão do cliente.

  • O trabalho chega em intermitências e você deve proteger as operações críticas processando mensagens de alta prioridade primeiro, ao adiar o trabalho de prioridade mais baixa.

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

  • Todos os itens de trabalho têm importância de negócios semelhante e o processamento estrito de FIFO é mais importante do que o agendamento baseado em prioridade.

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

Design de carga de trabalho

Avalie como usar o padrão de Fila de Prioridade no design de uma carga de trabalho para abordar as metas e os princípios abordados nos pilares do Azure Well-Architected Framework. A tabela a seguir fornece diretrizes sobre como esse padrão dá suporte às metas de cada pilar.

Pilar Como esse padrão apoia os objetivos do pilar
As decisões de design 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. A separação de 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 com eficiência às demandas por meio de otimizações no dimensionamento, nos dados e no código. A separação de itens com base na prioridade de negócios permite que você concentre os esforços de desempenho no trabalho mais urgente.

- PE:09 Fluxos críticos

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

Example

O exemplo de padrão de Fila de Prioridade em GitHub demonstra uma implementação do padrão de Fila de Prioridade que usa Barramento de Serviço do Azure tópicos e assinaturas. O exemplo implanta uma conta de armazenamento segura, um recurso do Application Insights para monitoramento e um namespace Barramento de Serviço para habilitar a comunicação entre o remetente e as funções de consumidor.

A implantação inclui três aplicativos de funções: um remetente e dois consumidores. Os aplicativos de consumidor usam diferentes contagens máximas de instância para simular a priorização da mensagem. A funcPriorityQueueConsumerHigh função pode ser expandida para 200 instâncias, enquanto a funcPriorityQueueConsumerLow função é limitada a 40 instâncias. Todos os aplicativos de funções usam o plano de consumo flex e estão conectados ao Application Insights para diagnóstico e monitoramento.

As atribuições de função concedem acesso seguro a Barramento de Serviço e armazenamento usando identidades gerenciadas. Todos os aplicativos de funções compartilham a mesma conta de armazenamento e o recurso do Application Insights. Essa configuração centraliza a capacidade de observação e o registro em log.

O diagrama a seguir mostra a arquitetura da fila de prioridade:

Diagrama que mostra como implementar uma fila de prioridade usando Barramento de Serviço.

No diagrama anterior:

  1. Aplicativo (produtor). O PriorityQueueSender aplicativo cria mensagens, atribui uma propriedade de aplicativo personalizada chamada Priority a cada mensagem e define o Priority valor como High ou Low.

  2. Agente de mensagens e tópico. O Barramento de Serviço agente de mensagens envia mensagens para um único tópico de Barramento de Serviço chamado messages. Barramento de Serviço usa filtros SQL para rotear cada mensagem para a assinatura de alta prioridade ou baixa prioridade, com base em seu Priority valor.

  3. Vários pools de consumidores. Os PriorityQueueConsumerHigh pools de consumidores e PriorityQueueConsumerLow de consumidores respondem às mensagens das assinaturas de alta prioridade ou de baixa prioridade usando gatilhos Azure Functions Barramento de Serviço.

Função no exemplo Serviço Azure no exemplo Nome no exemplo
Aplicativo (produtor) Aplicativo Azure Functions PriorityQueueSender
Agente de mensagens Barramento de Serviço do Azure <seu namespace do barramento de serviço>
Tópico da mensagem tópico do Barramento de Serviço do Azure messages
Assinaturas de mensagem Barramento de Serviço do Azure assinaturas highPriority
lowPriority
Consumidores Aplicativo Azure Functions PriorityQueueConsumerHigh
PriorityQueueConsumerLow

Próximas Etapas 

Os seguintes padrões podem ser úteis quando você implementa esse padrão:

  • Queue-Based padrão de Nivelamento de Carga: use uma fila como um buffer entre a entrada de solicitação e o processamento. Use-o com o padrão de Fila de Prioridade quando precisar de proteção contra intermitência e tratamento diferenciado.

  • Padrão consumidores concorrentes: implemente vários consumidores que escutam a mesma fila e processam tarefas em paralelo para aumentar a taxa de transferência. Apenas um consumidor processa cada mensagem.

  • Padrão de limitação: implemente a limitação usando filas para gerenciar as taxas de solicitação. Use mensagens prioritárias para priorizar solicitações de aplicativos críticos ou clientes de alto valor em vez de menos importantes.