Compartilhar via


Estilo de arquitetura controlada por evento

Azure Stream Analytics
Azure Functions
Barramento de Serviço do Azure

Uma arquitetura orientada a eventos consiste em produtores de eventos que geram um fluxo de eventos, consumidores de eventos que escutam esses eventos e canais de eventos que transferem eventos de produtores para consumidores.

Diagrama que mostra um estilo de arquitetura controlado por eventos.

Os eventos são entregues quase em tempo real, para que os consumidores possam responder imediatamente conforme os eventos ocorrem. Os produtores são dissociados dos consumidores: um produtor não sabe quais consumidores estão ouvindo. Os consumidores também são separados uns dos outros; e cada consumidor vê todos os eventos. Esse processo difere de um padrão consumidores concorrentes em que os consumidores retiram mensagens de uma fila e uma mensagem é processada apenas uma vez, supondo que não haja erros. Em alguns sistemas, como Azure Internet das Coisas (IoT), os eventos devem ser ingeridos em grandes volumes.

Uma arquitetura orientada a eventos pode usar um modelo de publicação-assinatura ou um modelo de fluxo de eventos.

  • Pub/sub: A infraestrutura de mensagens de publicação-assinatura rastreia assinaturas. Quando um evento é publicado, ele envia o evento para cada assinante. Um evento não pode ser reproduzido depois de recebido e novos assinantes não veem o evento.

  • Streaming de eventos: Os eventos são gravados em um log. Os eventos são estritamente ordenados dentro de uma partição e são duráveis. Os clientes não assinam o fluxo. Em vez disso, um cliente pode ler de qualquer parte do fluxo. O cliente é responsável por avançar sua posição no fluxo. Isso significa que um cliente pode ingressar a qualquer momento e pode reproduzir eventos.

No lado do consumidor, há algumas variações comuns:

  • Processamento de eventos simples: Um evento dispara imediatamente uma ação no consumidor. Por exemplo, você pode usar o Azure Functions com um gatilho do Barramento de Serviço do Azure para que uma função seja executada sempre que uma mensagem for publicada em um tópico do Barramento de Serviço.

  • Correlação básica de eventos: Um consumidor processa alguns eventos de negócios discretos, correlaciona-os por algum identificador e persiste informações de eventos anteriores para uso ao processar eventos posteriores. Bibliotecas como NServiceBus e MassTransit dão suporte a esse padrão.

  • Processamento de eventos complexos: Um consumidor usa uma tecnologia como o Azure Stream Analytics para analisar uma série de eventos e identificar padrões nos dados do evento. Por exemplo, você pode agregar leituras de um dispositivo inserido em uma janela de tempo e gerar uma notificação se a média móvel ultrapassar um determinado limite.

  • Processamento de fluxo de eventos: Use uma plataforma de streaming de dados, como o Hub IoT do Azure ou o Apache Kafka, como um pipeline para ingerir eventos e alimentá-los para transmitir processadores. Os processadores de fluxo agem para processar ou transformar o fluxo. Pode haver vários processadores de fluxo para diferentes subsistemas do aplicativo. Esta abordagem é uma boa opção para cargas de trabalho de IoT.

A origem dos eventos pode ser externa ao sistema, como dispositivos físicos em uma solução de IoT. Nesse caso, o sistema deve ser capaz de ingerir os dados no volume e na taxa de transferência necessárias para a fonte de dados.

Há duas abordagens primárias para estruturar cargas de eventos. Quando você tem controle sobre os consumidores de eventos, pode decidir sobre a estrutura de conteúdo para cada consumidor. Essa estratégia permite que você misture abordagens conforme necessário em uma única carga de trabalho.

  • Inclua todos os atributos necessários no conteúdo: Use essa abordagem quando quiser que os consumidores tenham todas as informações disponíveis sem a necessidade de consultar uma fonte de dados externa. No entanto, isso pode levar a problemas de consistência de dados devido a vários sistemas de registro, especialmente após as atualizações. O gerenciamento de contratos e o controle de versão também podem se tornar complexos.

  • Inclua somente chaves no conteúdo: Nessa abordagem, os consumidores recuperam os atributos necessários, como uma chave primária, para buscar independentemente os dados restantes de uma fonte de dados. Esse método fornece melhor consistência de dados porque tem um único sistema de registro. No entanto, ele pode ter um desempenho pior do que a primeira abordagem, pois os consumidores devem consultar a fonte de dados com frequência. Você tem menos preocupações em relação ao acoplamento, largura de banda, gerenciamento de contratos ou controle de versão porque eventos menores e contratos mais simples reduzem a complexidade.

No diagrama anterior, cada tipo de consumidor é mostrado como uma única caixa. Para evitar que o consumidor se torne um único ponto de falha no sistema, é comum ter várias instâncias de um consumidor. Várias instâncias também podem ser necessárias para lidar com o volume e a frequência dos eventos. Um único consumidor pode processar eventos em vários threads. Essa configuração pode criar desafios se os eventos precisarem ser processados em ordem ou exigirem semântica exatamente uma vez. Para obter mais informações, consulte Minimizar a coordenação.

Há duas topologias principais em muitas arquiteturas orientadas a eventos:

  • Topologia do agente: Os componentes transmitem ocorrências como eventos para todo o sistema. Outros componentes atuam no evento ou ignoram o evento. Essa topologia é útil quando o fluxo de processamento de eventos é relativamente simples. Não há coordenação ou orquestração central, portanto, essa topologia pode ser dinâmica. Essa topologia é altamente desacoplada, o que ajuda a fornecer escalabilidade, capacidade de resposta e tolerância a falhas de componentes. Nenhum componente possui ou está ciente do estado de qualquer transação comercial de várias etapas, e as ações são executadas de forma assíncrona. Posteriormente, as transações distribuídas são arriscadas porque não há nenhuma maneira nativa de ser reiniciada ou reproduzida. Você precisa considerar cuidadosamente o tratamento de erros e estratégias de intervenção manual, pois essa topologia pode ser uma fonte de inconsistência de dados.

  • Topologia do mediador: Essa topologia aborda algumas das deficiências da topologia do agente. Há um mediador de eventos que gerencia e controla o fluxo de eventos. O mediador de eventos mantém o estado e gerencia o tratamento de erros e os recursos de reinicialização. Ao contrário da topologia do agente, nessa topologia, os componentes transmitem ocorrências como comandos e apenas para canais designados. Esses canais geralmente são filas de mensagens. Espera-se que os consumidores processem esses comandos. Essa topologia fornece mais controle, melhor tratamento de erros distribuídos e potencialmente melhor consistência de dados. Essa topologia apresenta o aumento do acoplamento entre componentes e o mediador de eventos pode se tornar um gargalo ou uma preocupação de confiabilidade.

Quando usar essa arquitetura

Você deve usar essa arquitetura quando:

  • Vários subsistemas devem processar os mesmos eventos.
  • O processamento em tempo real com o atraso mínimo de tempo é necessário.
  • O processamento de eventos complexos, como correspondência de padrões ou agregação ao longo das janelas de tempo, é necessário.
  • É necessário alto volume e alta velocidade de dados, como com, por exemplo, IoT.

Benefícios

Os benefícios dessa arquitetura são:

  • Produtores e consumidores são separados.
  • Nenhuma integração de ponta a ponta. É fácil adicionar novos consumidores ao sistema.
  • Os consumidores podem responder a eventos imediatamente à medida que ocorrem.
  • Altamente escalável, elástico e distribuído.
  • Os subsistemas têm exibições independentes do fluxo de evento.

Desafios

  • Entrega garantida.

    Em alguns sistemas, especialmente em situações de IoT, é crucial garantir que os eventos sejam entregues.

  • Eventos processados em ordem ou exatamente uma vez.

    Para resiliência e escalabilidade, cada tipo de consumidor normalmente é executado em várias instâncias. Esse processo pode criar um desafio se os eventos precisarem ser processados em ordem dentro de um tipo de consumidor ou se a lógica de processamento de mensagens idempotente não for implementada.

  • Coordenação de mensagens entre serviços.

    Os processos empresariais geralmente têm vários serviços que publicam e assinam mensagens para obter um resultado consistente em toda uma carga de trabalho. Você pode usar padrões de fluxo de trabalho como o padrão Coreografia e a Orquestração de Saga para gerenciar de forma confiável os fluxos de mensagens em vários serviços.

  • Tratamento de erro.

    A arquitetura controlada por eventos usa principalmente a comunicação assíncrona. O desafio da comunicação assíncrona é o tratamento de erros. Uma maneira de resolver esse problema é usar um processador separado de manipulador de erros. Quando o consumidor do evento apresenta um erro, ele envia imediatamente e de forma assíncrona o evento errôneo para o processador do manipulador de erros e continua. O processador do manipulador de erros tenta corrigir o erro e envia o evento de volta ao canal de ingestão original. No entanto, se o processador do manipulador de erros falhar, ele poderá enviar o evento errôneo para um administrador para inspeção adicional. Se você usar um processador de manipulador de erros, os eventos incorretos serão processados fora da sequência quando forem reenviados.

  • Perda de dados.

    Outro desafio da comunicação assíncrona é a perda de dados. Se algum dos componentes falhar antes de processar e entregar com êxito o evento ao próximo componente, o evento será descartado e nunca chegará ao destino final. Para minimizar a chance de perda de dados, persista eventos em trânsito e remova ou desqueue os eventos somente quando o próximo componente reconhecer o recebimento do evento. Esses recursos são conhecidos como modo de confirmação do cliente e suporte ao último participante.

  • Implementação de um padrão de solicitação-resposta tradicional.

    Às vezes, o produtor de eventos requer uma resposta imediata do consumidor do evento, como obter a qualificação do cliente antes de prosseguir com um pedido. Em uma arquitetura controlada por eventos, a comunicação síncrona pode ser obtida usando mensagens de solicitação-resposta.

    Esse padrão geralmente é implementado com duas filas: uma fila de solicitação e uma fila de resposta. O produtor de eventos envia uma solicitação assíncrona para uma fila de solicitações, pausa outras operações nessa tarefa e aguarda uma resposta na fila de resposta. Essa abordagem efetivamente transforma esse padrão em um processo síncrono. Os consumidores de eventos processam a solicitação e enviam a resposta de volta por meio de uma fila de resposta. Essa abordagem geralmente usa uma ID de sessão para acompanhamento, portanto, o produtor de eventos sabe qual mensagem na fila de resposta está relacionada à solicitação específica. A solicitação original também pode especificar o nome da fila de resposta, potencialmente efêmera, em um cabeçalho de resposta ou outro atributo personalizado mutuamente acordado.

  • Manutenção do número apropriado de eventos.

    A geração de um número excessivo de eventos refinados pode saturar e sobrecarregar o sistema, dificultando a análise eficaz do fluxo geral de eventos. Esse problema é exacerbado quando as alterações precisam ser revertidas. Por outro lado, a consolidação excessiva de eventos também pode criar problemas, resultando em processamento e respostas desnecessários dos consumidores de eventos.

    Para alcançar o equilíbrio certo, considere as consequências dos eventos e se os consumidores precisam inspecionar as cargas úteis do evento para determinar suas respostas. Por exemplo, se você tiver um componente de verificação de conformidade, poderá ser suficiente publicar apenas dois tipos de eventos: compatível e não compatível. Essa abordagem ajuda a garantir que apenas os consumidores relevantes processem cada evento, o que impede o processamento desnecessário.

Outras considerações

  • A quantidade de dados a serem incluídos em um evento pode ser uma consideração significativa que afeta o desempenho e o custo. Você pode simplificar o código de processamento e eliminar pesquisas extras colocando todas as informações relevantes necessárias para processamento diretamente no evento. Quando você adiciona apenas uma quantidade mínima de informações a um evento, como alguns identificadores, reduz o tempo e o custo do transporte. No entanto, essa abordagem requer o código de processamento para recuperar as informações adicionais necessárias. Para obter mais informações, consulte Colocando seus eventos em uma dieta.

  • Uma solicitação só é visível para o componente de tratamento de solicitação. Mas os eventos geralmente são visíveis para vários componentes em uma carga de trabalho, mesmo que esses componentes não sejam ou não destinados a consumi-los. Para operar com uma mentalidade de "assumir violação", esteja atento a quais informações você inclui em eventos para evitar a exposição de informações não intencionais.

  • Muitos aplicativos usam a arquitetura orientada a eventos como sua arquitetura primária. Você pode combinar essa abordagem com outros estilos de arquitetura para criar uma arquitetura híbrida. Combinações típicas incluem microsserviços , pipes e filtros. Integre a arquitetura orientada a eventos para melhorar o desempenho do sistema eliminando gargalos e fornecendo pressão de retorno durante grandes volumes de solicitação.

  • Domínios específicos geralmente abrangem vários produtores de eventos, consumidores ou canais de eventos. Alterações em um domínio específico podem afetar muitos componentes.