Opções de mensagens assíncronas
Este artigo descreve os diferentes tipos de mensagens e as entidades que participam de uma infraestrutura de mensagens. Com base nos requisitos de cada tipo de mensagem, o artigo recomenda os serviços de mensagens do Azure. As opções incluem Mensagens do Barramento de Serviço do Azure, Grade de Eventos do Azure e Hubs de Eventos do Azure. Para comparação de produtos, consulte Comparar serviços de mensagens.
Em um nível arquitetônico, uma mensagem é um datagrama criado por uma entidade (produtor), para distribuir informações para que outras entidades (consumidores) possam estar cientes e agir adequadamente. O produtor e o consumidor podem se comunicar diretamente ou opcionalmente por meio de uma entidade intermediária (agente de mensagens). Este artigo se concentra no sistema de mensagens assíncrono usando um agente de mensagens.
Podemos classificar mensagens em duas categorias principais. Se o produtor espera uma ação do consumidor, essa mensagem é um comando. Se a mensagem informar ao consumidor que uma ação ocorreu, a mensagem será um evento.
Comandos
O produtor envia um comando com a intenção de que os consumidores executem uma operação dentro do escopo de uma transação comercial.
Um comando é uma mensagem de alto valor e deve ser entregue pelo menos uma vez. Se um comando for perdido, toda a transação comercial poderá falhar. Além disso, um comando não deve ser processado mais de uma vez. Isso pode causar uma transação errônea. Um cliente pode receber pedidos duplicados ou cobrados duas vezes.
Os comandos geralmente são usados para gerenciar o fluxo de trabalho de uma transação de negócios de várias etapas. Dependendo da lógica de negócios, o produtor pode esperar que o consumidor reconheça a mensagem e relate os resultados da operação. Com base nesse resultado, o produtor pode escolher um curso de ação apropriado.
Eventos
Um evento é um tipo de mensagem que um produtor gera para anunciar fatos.
O produtor (conhecido como o editor neste contexto) não tem expectativas de que os eventos resultem em qualquer ação.
Os consumidores interessados podem se inscrever, escutar eventos e executar ações dependendo do cenário de consumo. Os eventos podem ter vários assinantes ou nenhum assinante. Dois assinantes diferentes podem reagir a um evento com ações diferentes e não estar cientes uns dos outros.
O produtor e o consumidor são vagamente acoplados e gerenciados de forma independente. O produtor não espera que o consumidor reconheça o evento de volta ao produtor. Um consumidor que não está mais interessado nos eventos pode cancelar a assinatura, o que remove o consumidor do pipeline sem afetar o produtor ou a funcionalidade geral do sistema.
Há duas categorias de eventos:
O produtor levanta eventos para anunciar fatos discretos. Um caso de uso comum é a notificação de evento. Por exemplo, o Azure Resource Manager gera eventos quando cria, modifica ou exclui recursos. Um assinante desses eventos pode ser um Aplicativo Lógico que envia emails de alerta.
O produtor gera eventos relacionados em uma sequência, ou um fluxo de eventos, durante um período de tempo. Normalmente, um fluxo é consumido para avaliação estatística. A avaliação pode ocorrer dentro de uma janela temporal ou à medida que os eventos chegam. Telemetria é um caso de uso comum (por exemplo, integridade e monitoramento de carga de um sistema). Outro caso é o streaming de eventos de dispositivos IoT.
Um padrão comum para implementar mensagens de evento é o padrão Publicador-Assinante .
Função e benefícios de um agente de mensagens
Um agente de mensagens intermediária fornece a funcionalidade de mover mensagens de produtor para consumidor e pode oferecer mais benefícios.
Dissociação
Um agente de mensagens separa o produtor do consumidor na lógica que gera e usa as mensagens, respectivamente. Em um fluxo de trabalho complexo, o agente pode incentivar as operações de negócios a serem dissociadas e ajudar a coordenar o fluxo de trabalho.
Por exemplo, uma única transação comercial requer operações distintas que são executadas em uma sequência de lógica de negócios. O produtor emite um comando que sinaliza um consumidor para iniciar uma operação. O consumidor reconhece a mensagem em uma fila separada reservada para alinhar respostas para o produtor. Somente depois de receber a resposta o produtor envia uma nova mensagem para iniciar a próxima operação na sequência. Um consumidor diferente processa essa mensagem e envia uma mensagem de conclusão para a fila de resposta. Usando mensagens, os serviços coordenam o fluxo de trabalho da transação entre si.
Um agente de mensagens fornece desacoplamento temporal. O produtor e o consumidor não precisam ser executados simultaneamente. Um produtor pode enviar uma mensagem ao agente de mensagens independentemente da disponibilidade do consumidor. Por outro lado, o consumidor não está restrito à disponibilidade do produtor.
Por exemplo, a interface do usuário de um aplicativo Web gera mensagens e usa uma fila como o agente de mensagens. Quando o consumidor estiver pronto, ele poderá recuperar mensagens da fila e executar o trabalho. A desacoplamento temporal ajuda a interface do usuário a permanecer responsiva. Ele não é bloqueado enquanto as mensagens são tratadas de forma assíncrona.
Determinadas operações podem levar muito tempo para serem concluídas. Depois de emitir um comando, o produtor não deverá esperar até que o consumidor o conclua. Um agente de mensagens ajuda no processamento assíncrono de mensagens.
Balanceamento de carga
Os produtores podem postar um grande número de mensagens que são atendidas por muitos consumidores. Use um agente de mensagens para distribuir o processamento entre servidores e melhorar a taxa de transferência. Os consumidores podem ser executados em servidores diferentes para espalhar a carga. Os consumidores podem ser adicionados dinamicamente para dimensionar o sistema quando necessário ou removidos de outra forma.
O padrão Consumidores Concorrentes explica como processar várias mensagens simultaneamente para otimizar a taxa de transferência, melhorar a escalabilidade e a disponibilidade e equilibrar a carga de trabalho.
Nivelamento de carga
O volume de mensagens geradas pelo produtor ou por um grupo de produtores pode ser variável. Às vezes, pode haver um grande volume causando picos nas mensagens. Em vez de adicionar consumidores para lidar com esse trabalho, um agente de mensagens pode agir como um buffer e os consumidores gradualmente drenam mensagens em seu próprio ritmo sem enfatizar o sistema.
O padrão de nivelamento de carga baseado em fila fornece mais informações.
Mensagens confiáveis
Um agente de mensagens ajuda a garantir que as mensagens não sejam perdidas mesmo se a comunicação falhar entre o produtor e o consumidor. O produtor pode postar mensagens no agente de mensagens e o consumidor pode recuperá-las quando a comunicação for restabelecida. O produtor não é bloqueado a menos que perca a conectividade com o agente de mensagens.
Mensagens resilientes
Um agente de mensagens pode adicionar resiliência aos consumidores em seu sistema. Se um consumidor falhar durante o processamento de uma mensagem, outra instância do consumidor poderá processar essa mensagem. O reprocessamento é possível porque a mensagem persiste no agente.
Opções de tecnologia para um agente de mensagens
O Azure fornece vários serviços do agente de mensagens, cada um com uma variedade de recursos. Antes de escolher um serviço, determine a intenção e os requisitos da mensagem.
Messaging do Barramento de Serviço do Azure
As filas de Mensagens do Barramento de Serviço do Azure são adequadas para transferir comandos de produtores para consumidores. Aqui estão algumas considerações.
Modelo de pull
Um consumidor de uma fila do Barramento de Serviço sonda constantemente o Barramento de Serviço para verificar se novas mensagens estão disponíveis. Os SDKs do cliente e o gatilho do Azure Functions para Barramento de Serviço abstraem esse modelo. Quando uma nova mensagem está disponível, o retorno de chamada do consumidor é invocado e a mensagem é enviada ao consumidor.
Entrega garantida
O Barramento de Serviço permite que um consumidor espie a fila e bloqueie uma mensagem de outros consumidores.
É responsabilidade do consumidor relatar o status de processamento da mensagem. Somente quando o consumidor marca a mensagem como consumida o Barramento de Serviço remove a mensagem da fila. Se ocorrer uma falha, tempo limite ou falha, o Barramento de Serviço desbloqueará a mensagem para que outros consumidores possam recuperá-la. Dessa forma, as mensagens não são perdidas na transferência.
Um produtor pode enviar acidentalmente a mesma mensagem duas vezes. Por exemplo, uma instância de produtor falha depois de enviar uma mensagem. Outro produtor substitui a instância original e envia a mensagem novamente. As filas do Barramento de Serviço do Azure fornecem uma funcionalidade interna de eliminação de duplicação que detecta e remove mensagens duplicadas. Ainda há uma chance de que uma mensagem seja entregue duas vezes. Por exemplo, se um consumidor falhar durante o processamento, a mensagem será retornada para a fila e será recuperada pelo mesmo ou por outro consumidor. A lógica de processamento de mensagens no consumidor deve ser idempotente para que, mesmo que o trabalho seja repetido, o estado do sistema não seja alterado.
Ordenação de mensagens
Se você quiser que os consumidores obtenham as mensagens na ordem em que são enviadas, as filas do Barramento de Serviço garantem a entrega ordenada por FIFO (first-in-first-out) usando sessões. Uma sessão pode ter uma ou mais mensagens. As mensagens são correlacionadas com a propriedade SessionId . Mensagens que fazem parte de uma sessão, nunca expiram. Uma sessão pode ser bloqueada para um consumidor para impedir que suas mensagens sejam tratadas por um consumidor diferente.
Para obter mais informações, confira Sessões de mensagem.
Persistência de mensagem
As filas do barramento de serviço dão suporte à desassociação temporal. Mesmo quando um consumidor não está disponível ou não consegue processar a mensagem, ela permanece na fila.
Verificação de transações de execução prolongada
As transações comerciais podem ser executadas por muito tempo. Cada operação na transação pode ter várias mensagens. Use o ponto de verificação para coordenar o fluxo de trabalho e fornecer resiliência caso uma transação falhe.
As filas do Barramento de Serviço permitem o ponto de verificação por meio da funcionalidade de estado da sessão. As informações de estado são registradas incrementalmente na fila (SetState) para mensagens que pertencem a uma sessão. Por exemplo, um consumidor pode acompanhar o progresso verificando o estado (GetState) de vez em quando. Se um consumidor falhar, outro consumidor poderá usar informações de estado para determinar o último ponto de verificação conhecido para retomar a sessão.
Fila de mensagens mortas (DLQ)
Uma fila do Barramento de Serviço tem uma subconsulta padrão, chamada DLQ (fila de mensagens mortas) para armazenar mensagens que não puderam ser entregues ou processadas. O Barramento de Serviço ou a lógica de processamento de mensagens no consumidor podem adicionar mensagens ao DLQ. O DLQ mantém as mensagens até serem recuperadas da fila.
Aqui estão exemplos de quando uma mensagem pode acabar sendo usada no DLQ:
Uma mensagem de veneno é uma mensagem que não pode ser tratada porque está malformada ou contém informações inesperadas. Nas filas do Barramento de Serviço, você pode detectar mensagens suspeitas definindo a propriedade MaxDeliveryCount da fila. Se o número de vezes que a mesma mensagem for recebida exceder esse valor de propriedade, o Barramento de Serviço moverá a mensagem para o DLQ.
Uma mensagem pode não ser mais relevante se não for processada dentro de um período. As filas do Barramento de Serviço permitem que o produtor poste mensagens com um atributo de vida útil. Se esse período expirar antes do recebimento da mensagem, a mensagem será colocada no DLQ.
Examine as mensagens no DLQ para determinar o motivo da falha.
Solução híbrida
O Barramento de Serviço conecta sistemas locais e soluções de nuvem. Os sistemas locais geralmente são difíceis de alcançar devido a restrições de firewall. O produtor e o consumidor (pode ser local ou na nuvem) podem usar o ponto de extremidade da fila do Barramento de Serviço como o local de retirada e entrega para mensagens.
O padrão ponte de mensagens é outra maneira de lidar com esses cenários.
Tópicos e assinaturas
O Barramento de Serviço dá suporte ao padrão Publisher-Subscriber por meio de tópicos e assinaturas do Barramento de Serviço.
Esse recurso fornece uma maneira para o produtor transmitir mensagens para vários consumidores. Quando um tópico recebe uma mensagem, ele é encaminhado para todos os consumidores inscritos. Opcionalmente, uma assinatura pode ter critérios de filtro que permitem ao consumidor obter um subconjunto de mensagens. Cada consumidor recupera mensagens de uma assinatura de maneira semelhante a uma fila.
Para obter mais informações, consulte os tópicos do Barramento de Serviço do Azure.
Grade de Eventos do Azure
Recomendamos a Grade de Eventos do Azure para eventos discretos. A Grade de Eventos segue o padrão de Publisher-Subscriber. Quando fontes de evento disparam eventos, elas são publicadas nos tópicos da Grade de Eventos. Os consumidores desses eventos criam assinaturas da Grade de Eventos especificando tipos de evento e manipulador de eventos que processarão os eventos. Se não houver assinantes, os eventos serão descartados. Cada evento pode ter várias assinaturas.
Modelo de push
A Grade de Eventos propaga mensagens para os assinantes em um modelo de push. Suponha que você tenha uma assinatura da Grade de Eventos com um webhook. Quando um novo evento chega, a Grade de Eventos posta o evento no ponto de extremidade do webhook.
Integrado ao Azure
Escolha a Grade de Eventos se quiser receber notificações sobre os recursos do Azure. Muitos serviços do Azure atuam como fontes de eventos que têm tópicos internos da Grade de Eventos. A Grade de Eventos também dá suporte a vários serviços do Azure que podem ser configurados como manipuladores de eventos. É fácil assinar esses tópicos para rotear eventos para manipuladores de eventos de sua escolha. Por exemplo, você pode usar a Grade de Eventos para invocar uma Função do Azure quando um armazenamento de blobs é criado ou excluído.
Tópicos personalizados
Crie tópicos personalizados da Grade de Eventos se quiser enviar eventos de seu aplicativo ou de um serviço do Azure que não esteja integrado à Grade de Eventos.
Por exemplo, para ver o progresso de uma transação de negócios inteira, você deseja que os serviços participantes gerem eventos à medida que processam suas operações comerciais individuais. Um aplicativo Web mostra esses eventos. Uma maneira de realizar essa tarefa é criar um tópico personalizado e adicionar uma assinatura com seu aplicativo Web registrado por meio de um WebHook HTTP. À medida que os serviços de negócios enviam eventos para o tópico personalizado, a Grade de Eventos os envia por push para seu aplicativo Web.
Eventos filtrados
Você pode especificar filtros em uma assinatura para instruir a Grade de Eventos a rotear apenas um subconjunto de eventos para um manipulador de eventos específico. Especifique os filtros no esquema de assinatura. Qualquer evento enviado para o tópico com valores que correspondem ao filtro é encaminhado automaticamente para essa assinatura.
Por exemplo, o conteúdo em vários formatos é carregado no Armazenamento de Blobs. Sempre que um arquivo é adicionado, um evento é gerado e publicado na Grade de Eventos. A assinatura do evento pode ter um filtro que envia apenas eventos para imagens para que um manipulador de eventos possa gerar miniaturas.
Para obter mais informações sobre filtragem, consulte Filtrar eventos para a Grade de Eventos.
Alta taxa de transferência
A Grade de Eventos pode rotear 10.000.000 eventos por segundo por região. As primeiras 100.000 operações por mês são gratuitas. Para considerações de custo, veja Quanto custa a Grade de Eventos?
Entrega resiliente
Embora a entrega bem-sucedida para eventos não seja tão crucial quanto os comandos, talvez você ainda queira alguma garantia dependendo do tipo de evento. A Grade de Eventos oferece recursos que você pode habilitar e personalizar, como políticas de repetição, tempo de expiração e letras mortas. Para saber mais, confira Event Grid message delivery and retry (Entrega e repetição de mensagens da Grade de Eventos).
O processo de repetição da Grade de Eventos pode ajudar na resiliência, mas não é à prova de falhas. No processo de repetição, a Grade de Eventos pode entregar a mensagem mais de uma vez, ignorar ou atrasar algumas novas tentativas se o ponto de extremidade não responder por um longo tempo. Para obter mais informações, consulte Agendamento de repetição.
Você pode persistir eventos não entregues em uma conta de armazenamento de blobs habilitando mensagens mortas. Há um atraso na entrega da mensagem para o ponto de extremidade de armazenamento de blobs e, se esse ponto de extremidade não responder, a Grade de Eventos descartará o evento. Para obter mais informações, consulte Definir o local de mensagens mortas e a política de repetição.
Hubs de eventos do Azure
Quando você está trabalhando com um fluxo de eventos, os Hubs de Eventos do Azure são o agente de mensagens recomendado. Essencialmente, é um buffer grande capaz de receber grandes volumes de dados com baixa latência. Os dados recebidos podem ser lidos rapidamente por meio de operações simultâneas. Você pode transformar os dados recebidos usando qualquer provedor de análise em tempo real. Os Hubs de Eventos também fornecem a capacidade de armazenar eventos em uma conta de armazenamento.
Ingestão rápida
Os Hubs de Eventos são capazes de ingerir milhões de eventos por segundo. Os eventos são acrescentados apenas ao fluxo e são ordenados por tempo.
Modelo de pull
Assim como a Grade de Eventos, os Hubs de Eventos também oferecem recursos de Publisher-Subscriber. Uma diferença importante entre a Grade de Eventos e os Hubs de Eventos é a maneira como os dados de evento são disponibilizados para os assinantes. A Grade de Eventos envia os dados ingeridos para os assinantes, enquanto os Hubs de Eventos disponibilizam os dados em um modelo de pull. À medida que os eventos são recebidos, os Hubs de Eventos os acrescentam ao fluxo. Um assinante gerencia seu cursor e pode avançar e voltar ao fluxo, selecionar um deslocamento de tempo e reproduzir uma sequência em seu ritmo.
Os processadores de fluxo são assinantes que extraem dados dos Hubs de Eventos para fins de transformação e análise estatística. Use o Azure Stream Analytics e o Apache Spark para processamento complexo, como agregação ao longo do tempo ou detecção de anomalias.
Se você quiser agir em cada evento por partição, poderá efetuar pull dos dados usando o host do processador de eventos ou usando o conector interno, como os Aplicativos Lógicos do Azure , para fornecer a lógica de transformação. Outra opção é usar o Azure Functions.
Particionamento
Uma partição é uma parte do fluxo de eventos. Os eventos são divididos usando uma chave de partição. Por exemplo, vários dispositivos IoT enviam dados do dispositivo para um hub de eventos. A chave de partição é o identificador do dispositivo. À medida que os eventos são ingeridos, os Hubs de Eventos os move para partições separadas. Dentro de cada partição, todos os eventos são ordenados por tempo.
Um consumidor é uma instância de código que processa os dados do evento. Os Hubs de Eventos seguem um padrão de consumidor particionado. Cada consumidor lê apenas uma partição específica. Ter várias partições resulta em um processamento mais rápido porque o fluxo pode ser lido simultaneamente por vários consumidores.
Instâncias do mesmo consumidor compõem um único grupo de consumidores. Vários grupos de consumidores podem ler o mesmo fluxo com intenções diferentes. Suponha que um fluxo de eventos tenha dados de um sensor de temperatura. Um grupo de consumidores pode ler o fluxo para detectar anomalias como um pico de temperatura. Outro pode ler o mesmo fluxo para calcular uma temperatura média sem interrupção em uma janela temporal.
Os Hubs de Eventos dão suporte ao padrão Publisher-Subscriber permitindo vários grupos de consumidores. Cada grupo de consumidores é um assinante.
Para obter mais informações sobre o particionamento de Hubs de Eventos, consulte Partições.
Capturar Hubs de Eventos
O recurso Captura permite que você armazene o fluxo de eventos em um Armazenamento de Blobs do Azure ou no Data Lake Storage. Essa maneira de armazenar eventos é confiável porque, mesmo que a conta de armazenamento não esteja disponível, o Capture mantém seus dados por um período e grava no armazenamento depois que eles estão disponíveis.
Os serviços de armazenamento também podem oferecer recursos adicionais para analisar eventos. Por exemplo, aproveitando as camadas de acesso de uma conta de armazenamento de blobs, você pode armazenar eventos em uma camada quente para dados que precisam de acesso frequente. Você pode usar esses dados para visualização. Como alternativa, você pode armazenar dados na camada de arquivo morto e recuperá-los ocasionalmente para fins de auditoria.
O Capture armazena todos os eventos ingeridos pelos Hubs de Eventos e é útil para o processamento em lote. Você pode gerar relatórios nos dados usando uma função MapReduce. Os dados capturados também podem servir como a fonte da verdade. Se determinados fatos foram perdidos durante a agregação dos dados, você pode se referir aos dados capturados.
Para obter detalhes sobre esse recurso, consulte Capturar eventos por meio dos Hubs de Eventos do Azure no Armazenamento de Blobs do Azure ou no Azure Data Lake Storage.
Suporte para clientes do Apache Kafka
Os Hubs de Eventos fornecem um ponto de extremidade para clientes do Apache Kafka . Os clientes existentes podem atualizar sua configuração para apontar para o ponto de extremidade e começar a enviar eventos aos Hubs de Eventos. Você não precisa fazer nenhuma alteração de código.
Para saber mais, consulte Hubs de Eventos para o Apache Kafka.
Cenários de crossover
Em alguns casos, é vantajoso combinar dois serviços de mensagens.
A combinação de serviços pode aumentar a eficiência do sistema de mensagens. Por exemplo, em sua transação comercial, você usa filas do Barramento de Serviço do Azure para lidar com mensagens. Filas que estão em sua maioria ociosas e recebem mensagens ocasionalmente são ineficientes, pois o consumidor está constantemente sondando a fila para novas mensagens. Você pode configurar uma assinatura da Grade de Eventos com uma Função do Azure como o manipulador de eventos. Sempre que a fila recebe uma mensagem e não há consumidores escutando, a Grade de Eventos envia uma notificação, que invoca a Função do Azure que drena a fila.
Para obter detalhes sobre como conectar o Barramento de Serviço à Grade de Eventos, consulte a visão geral da integração do Barramento de Serviço do Azure à Grade de Eventos.
A integração enterprise usando filas de mensagens e arquitetura de referência de eventos mostra uma implementação da integração do Barramento de Serviço à Grade de Eventos.
Veja outro exemplo: a Grade de Eventos recebe um conjunto de eventos em que alguns eventos exigem um fluxo de trabalho, enquanto outros são para notificação. Os metadados da mensagem indicam o tipo de evento. Uma maneira de diferenciar é verificar os metadados usando o recurso de filtragem na assinatura do evento. Se exigir um fluxo de trabalho, a Grade de Eventos o enviará para a fila do Barramento de Serviço do Azure. Os receptores dessa fila podem tomar as ações necessárias. Os eventos de notificação são enviados aos Aplicativos Lógicos para enviar emails de alerta.
Padrões relacionados
Considere esses padrões ao implementar mensagens assíncronas:
- Padrão consumidores concorrentes. Vários consumidores podem precisar competir para ler mensagens de uma fila. Esse padrão explica como processar várias mensagens simultaneamente para otimizar a taxa de transferência, melhorar a escalabilidade e a disponibilidade e equilibrar a carga de trabalho.
- Padrão de fila de prioridade. Para casos em que a lógica de negócios exige que algumas mensagens sejam processadas antes de outras, esse padrão descreve como as mensagens postadas por um produtor com prioridade mais alta são recebidas e processadas mais rapidamente por um consumidor do que mensagens de prioridade mais baixa.
- Padrão de nivelamento de carga baseado em fila. Esse padrão usa um agente de mensagens para atuar como um buffer entre um produtor e um consumidor para ajudar a minimizar o impacto na disponibilidade e na capacidade de resposta de cargas pesadas intermitentes para ambas as entidades.
- Padrão de repetição. Um produtor ou consumidor pode não conseguir se conectar a uma fila, mas os motivos dessa falha podem ser temporários e passar rapidamente. Esse padrão descreve como lidar com essa situação para adicionar resiliência a um aplicativo.
- Padrão Supervisor do Agente Agendador. O sistema de mensagens geralmente é usado como parte de uma implementação de fluxo de trabalho. Esse padrão demonstra como o sistema de mensagens pode coordenar um conjunto de ações em um conjunto distribuído de serviços e outros recursos remotos e habilitar um sistema para recuperar e repetir ações que falham.
- Padrão de coreografia. Esse padrão mostra como os serviços podem usar mensagens para controlar o fluxo de trabalho de uma transação comercial.
- Claim-Check padrão. Esse padrão mostra como dividir uma mensagem grande em uma verificação de declaração e um conteúdo.
Recursos da comunidade
Postagem no blog de Jonathon Oliver: Idempotency
Postagem no blog de Martin Fowler: O que você quer dizer com "Controlado por Eventos"?