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.
A nível arquitetónico, uma mensagem é um datagrama criado por uma entidade (produtor), para distribuir informação de modo a que outras entidades (consumidores) possam estar conscientes e agir em conformidade. O produtor e o consumidor podem comunicar direta ou opcionalmente através de uma entidade intermediária (corretor de mensagens). Este artigo se concentra em mensagens assíncronas usando um agente de mensagens.
Podemos classificar as mensagens em duas categorias principais. Se o produtor espera uma ação do consumidor, essa mensagem é um comando. Se a mensagem informar o consumidor de que uma ação ocorreu, então a mensagem é um evento.
Comandos
O produtor envia um comando com a intenção de que o(s) consumidor(es) realize(m) uma operação no âmbito 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. Fazer isso pode causar uma transação errada. Um cliente pode receber pedidos duplicados ou faturados duas vezes.
Os comandos são frequentemente usados para gerenciar o fluxo de trabalho de uma transação comercial de várias etapas. Dependendo da lógica do negócio, 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 uma linha de ação adequada.
Eventos
Um evento é um tipo de mensagem que um produtor levanta para anunciar fatos.
O produtor (conhecido como a editora neste contexto) não tem expectativas de que os eventos resultem em qualquer ação.
O(s) consumidor(es) interessado(s) pode(m) subscrever, ouvir eventos e tomar medidas dependendo do seu cenário de consumo. Os eventos podem ter vários subscritores ou nenhum subscritor. Dois subscritores diferentes podem reagir a um evento com ações diferentes e não estar cientes um do outro.
O produtor e o consumidor estão ligados de forma flexível e são geridos 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 inscrição, o que remove o consumidor do pipeline sem afetar o produtor ou a funcionalidade geral do sistema.
Existem duas categorias de eventos:
O produtor levanta eventos para anunciar fatos discretos. Um caso de uso comum é a notificação de eventos. 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 e-mails de alerta.
O produtor levanta eventos relacionados em uma sequência, ou um fluxo de eventos, ao longo de um período de tempo. Normalmente, um fluxo é consumido para avaliação estatística. A avaliação pode acontecer dentro de uma janela temporal ou à medida que os eventos chegam. A telemetria é um caso de uso comum (por exemplo, monitoramento de integridade e carga de um sistema). Outro caso é o streaming de eventos de dispositivos IoT.
Um padrão comum para implementar mensagens de eventos é o padrão Publisher-Subscriber .
Função e benefícios de um agente de mensagens
Um agente de mensagens intermediário fornece a funcionalidade de mover mensagens do produtor para o consumidor e pode oferecer mais benefícios.
Desacoplamento
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 corretor 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 ao consumidor para iniciar uma operação. O consumidor reconhece a mensagem em uma fila separada reservada para alinhar as respostas para o produtor. Só depois de receber a resposta é que 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 dissociação temporal. O produtor e o consumidor não precisam correr simultaneamente. Um produtor pode enviar uma mensagem para o corretor de mensagens independentemente da disponibilidade do consumidor. Por outro lado, o consumidor não está limitado pela 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. O 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.
Algumas operações podem levar muito tempo para serem concluídas. Depois de emitir um comando, o produtor não deve ter que esperar até que o consumidor o complete. Um agente de mensagens ajuda o 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 executar em servidores diferentes para distribuir a carga. Os consumidores podem ser adicionados dinamicamente para expandir 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 atuar como um buffer, e os consumidores drenam gradualmente as mensagens em seu próprio ritmo sem estressar 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 que a comunicação entre o produtor e o consumidor falhe. O produtor pode postar mensagens no corretor 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 broker.
Opções de tecnologia para um agente de mensagens
O Azure fornece vários serviços de 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.
Mensagens 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 tração
Um consumidor de uma fila do Service Bus pesquisa constantemente o Service Bus para verificar se novas mensagens estão disponíveis. Os SDKs de cliente e o gatilho do Azure Functions para o Service Bus 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 Service Bus permite que um consumidor espie a fila e bloqueie uma mensagem de outros consumidores.
É da responsabilidade do consumidor comunicar o estado de processamento da mensagem. Somente quando o consumidor marca a mensagem como consumida é que o Service Bus remove a mensagem da fila. Se ocorrer uma falha, tempo limite ou falha, o Service Bus desbloqueia a mensagem para que outros consumidores possam recuperá-la. Desta forma, as mensagens não são perdidas na transferência.
Um produtor pode acidentalmente enviar 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 um recurso interno de eliminação de duplicação que deteta 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á devolvida à fila e 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.
Encomenda de mensagens
Se você quiser que os consumidores recebam as mensagens na ordem em que são enviadas, as filas do Barramento de Serviço garantem a entrega ordenada 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 . As mensagens que fazem parte de uma sessão, nunca expiram. Uma sessão pode ser bloqueada para um consumidor para evitar que suas mensagens sejam tratadas por um consumidor diferente.
Para obter mais informações, consulte Sessões de mensagens.
Persistência de mensagens
As filas do barramento de serviço oferecem suporte ao desacoplamento temporal. Mesmo quando um consumidor não está disponível ou não consegue processar a mensagem, ele permanece na fila.
Transações de longa duração do ponto de verificação
As transações comerciais podem durar 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 no caso de uma transação falhar.
As filas do Barramento de Serviço permitem o checkpoint através da capacidade 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 Service Bus tem uma subfila padrão, chamada de fila de letras mortas (DLQ) para armazenar mensagens que não puderam ser entregues ou processadas. O Service Bus ou a lógica de processamento de mensagens no consumidor podem adicionar mensagens ao DLQ. O DLQ mantém as mensagens até que sejam recuperadas da fila.
Aqui estão exemplos de quando uma mensagem pode acabar por estar no DLQ:
Uma mensagem suspeita é 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 detetar 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 Service Bus moverá a mensagem para o DLQ.
Uma mensagem pode deixar de ser 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 time-to-live. Se este período expirar antes de a mensagem ser recebida, a mensagem é colocada no DLQ.
Examine as mensagens no DLQ para determinar o motivo da falha.
Solução híbrida
O Service Bus faz a ponte entre sistemas locais e soluções na nuvem. Os sistemas locais são muitas vezes difíceis de alcançar devido às restrições de firewall. Tanto o produtor quanto o consumidor (podem ser locais ou na nuvem) podem usar o ponto de extremidade da fila do Service Bus como o local de retirada e entrega de mensagens.
O padrão Messaging Bridge é outra maneira de lidar com esses cenários.
Tópicos e subscrições
O Service Bus suporta o padrão Editor-Assinante por meio de tópicos e assinaturas do Service Bus.
Esse recurso fornece uma maneira para o produtor transmitir mensagens para vários consumidores. Quando um tópico recebe uma mensagem, ela é encaminhada para todos os consumidores inscritos. Opcionalmente, uma assinatura pode ter critérios de filtro que permitem ao consumidor receber um subconjunto de mensagens. Cada consumidor recupera mensagens de uma assinatura de forma semelhante a uma fila.
Para obter mais informações, consulte Tópicos do Barramento de Serviço do Azure.
Grelha de Eventos do Azure
Recomendamos a Grade de Eventos do Azure para eventos discretos. A Grade de Eventos segue o padrão Editor-Assinante. Quando as fontes de eventos acionam eventos, elas são publicadas nos tópicos da Grade de Eventos. Os consumidores desses eventos criam assinaturas de Grade de Eventos especificando tipos de evento e manipulador de eventos que processará os eventos. Se não houver assinantes, os eventos são descartados. Cada evento pode ter várias subscrições.
Modelo Push
A Grade de Eventos propaga mensagens para os assinantes em um modelo push. Suponha que você tenha uma assinatura da Grade de Eventos com um webhook. Quando um novo evento chega, a Grade de Eventos publica o evento no ponto de extremidade do webhook.
Integrado com o Azure
Escolha Grade de Eventos se quiser receber notificações sobre 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 subscrever esses tópicos para encaminhar eventos para manipuladores de eventos à sua escolha. Por exemplo, você pode usar a Grade de Eventos para invocar uma Função do Azure quando um armazenamento de blob é criado ou excluído.
Tópicos personalizados
Crie tópicos personalizados da Grade de Eventos se quiser enviar eventos do 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 comercial 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 empresariais enviam eventos para o tópico personalizado, a Grelha de Eventos envia-os para a sua aplicação 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. Você especifica os filtros no esquema de assinatura. Qualquer evento enviado para o tópico com valores que correspondam ao filtro é automaticamente encaminhado para essa assinatura.
Por exemplo, o conteúdo em vários formatos é carregado para o Armazenamento de Blobs. Cada vez que um arquivo é adicionado, um evento é gerado e publicado na Grade de Eventos. A assinatura de 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 grade de eventos.
Débito elevado
A Grade de Eventos pode rotear 10.000.000 de eventos por segundo por região. As primeiras 100 000 operações por mês são gratuitas. Para obter considerações de custo, consulte Quanto custa a grade de eventos?
Entrega resiliente
Mesmo que a entrega bem-sucedida para eventos não seja tão crucial quanto os comandos, você ainda pode querer 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 obter mais informações, consulte 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 novas tentativas, 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 muito tempo. Para obter mais informações, consulte Agenda de novas tentativas.
Você pode persistir eventos não entregues em uma conta de armazenamento de blob habilitando o dead-lettering. Há um atraso na entrega da mensagem ao ponto de extremidade de armazenamento de blob e, se esse ponto de extremidade não estiver respondendo, a Grade de Eventos descartará o evento. Para obter mais informações, consulte Definir local de letra morta e política de novas tentativas.
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 grande buffer capaz de receber grandes volumes de dados com baixa latência. Os dados recebidos podem ser lidos rapidamente através 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 apenas anexados ao fluxo e são ordenados por tempo.
Modelo de tração
Assim como a Grade de Eventos, os Hubs de Eventos também oferecem recursos de Editor-Assinante. Uma diferença fundamental entre a Grade de Eventos e os Hubs de Eventos está na forma como os dados de eventos são disponibilizados aos assinantes. A Grade de Eventos envia os dados ingeridos para os assinantes, enquanto os Hubs de Eventos disponibilizam os dados em um modelo 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 no fluxo, selecionar um deslocamento de tempo e reproduzir uma sequência em seu ritmo.
Os processadores de fluxo são assinantes que extraem dados de 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, janelas ou deteção de anomalias.
Se quiser agir em cada evento por partição, você pode extrair os 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.
Criação de partições
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 movem-nos 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.
Os casos do mesmo consumidor constituem 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 detetar anomalias, como um pico de temperatura. Outro pode ler o mesmo fluxo para calcular uma temperatura média móvel em uma janela temporal.
Os Hubs de Eventos suportam o padrão Editor-Assinante, permitindo vários grupos de consumidores. Cada grupo de consumidores é assinante.
Para obter mais informações sobre o particionamento de Hubs de Eventos, consulte Partições.
Recolha dos Hubs de Eventos
O recurso Capturar permite armazenar o fluxo de eventos em um armazenamento de Blob do Azure ou Armazenamento Data Lake. 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, em seguida, grava no armazenamento depois que eles estiverem 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 blob, você pode armazenar eventos em uma camada de acesso para dados que precisam de acesso frequente. Você pode usar esses dados para visualização. Como alternativa, você pode armazenar dados na camada de arquivamento e recuperá-los ocasionalmente para fins de auditoria.
O Capture armazena todos os eventos ingeridos pelos Hubs de Eventos e é útil para processamento em lote. Você pode gerar relatórios sobre os dados usando uma função MapReduce. Os dados capturados também podem servir como fonte da verdade. Se certos fatos foram perdidos durante a agregação dos dados, você pode consultar os 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 Armazenamento do Azure Data Lake.
Suporte para clientes Apache Kafka
Os Hubs de Eventos fornecem um ponto de extremidade para clientes Apache Kafka . Os clientes existentes podem atualizar sua configuração para apontar para o ponto de extremidade e começar a enviar eventos para Hubs de Eventos. Você não precisa fazer nenhuma alteração no código.
Para obter mais informações, consulte Hubs de eventos para Apache Kafka.
Cenários cruzados
Em alguns casos, é vantajoso combinar dois serviços de mensagens.
A combinação de serviços pode aumentar a eficiência do seu sistema de mensagens. Por exemplo, em sua transação comercial, você usa filas do Barramento de Serviço do Azure para lidar com mensagens. As filas que, em sua maioria, estão ociosas e recebem mensagens ocasionalmente são ineficientes, porque o consumidor está constantemente pesquisando a fila em busca de novas mensagens. Você pode configurar uma assinatura de Grade de Eventos com uma Função do Azure como manipulador de eventos. Cada vez que a fila recebe uma mensagem e não há consumidores ouvindo, 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 Service Bus à Grade de Eventos, consulte Visão geral da integração do Barramento de Serviço do Azure para a 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 Service Bus com a Grade de Eventos.
Aqui está 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 destinatários dessa fila podem tomar as medidas necessárias. Os eventos de notificação são enviados para Aplicativos Lógicos para enviar e-mails de alerta.
Padrões relacionados
Considere estes padrões ao implementar mensagens assíncronas:
- Padrão de 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 as mensagens de prioridade mais baixa.
- Padrão de Nivelamento de Carga Baseado na 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 capacidade de resposta de cargas pesadas intermitentes para ambas as entidades.
- Padrão 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 do Supervisor do Agente do Agendador. As mensagens são frequentemente usadas 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 permitir que um sistema recupere e repita ações que falham.
- Padrão coreográfico. Esse padrão mostra como os serviços podem usar mensagens para controlar o fluxo de trabalho de uma transação comercial.
- Padrão Claim-Check. Esse padrão mostra como dividir uma mensagem grande em uma verificação de declaração e uma carga útil.
Recursos de comunidade
Postagem no blog de Jonathon Oliver: Idempotência
Postagem no blog de Martin Fowler: O que você quer dizer com "Event-Driven"?