Padrão Publisher-Subscriber

Permita que uma aplicação anuncie os eventos para vários consumidores interessados de forma assíncrona, sem acoplar os remetentes aos destinatários.

Também chamado: Pub/sub mensagens

Contexto e problema

Em aplicações baseadas em nuvem e distribuídas, os componentes do sistema muitas vezes precisam fornecer informações a outros componentes à medida que os eventos acontecem.

As mensagens assíncronos são uma forma eficaz de separar os remetentes dos consumidores e evitar bloquear o remetente para esperar por uma resposta. No entanto, a utilização de uma fila de mensagens dedicada para cada consumidor não escala efetivamente para muitos consumidores. Além disso, alguns dos consumidores podem estar interessados apenas num subconjunto da informação. Como pode o remetente anunciar eventos a todos os consumidores interessados sem conhecer as suas identidades?

Solução

Introduza um subsistema de mensagens assíncronos que inclui o seguinte:

  • Um canal de mensagens de entrada usado pelo remetente. O remetente embala eventos em mensagens, utilizando um formato de mensagem conhecido, e envia estas mensagens através do canal de entrada. O remetente neste padrão também é chamado de editor.

    Nota

    Uma mensagem é um pacote de dados. Um evento é uma mensagem que notifica outros componentes sobre uma mudança ou uma ação que ocorreu.

  • Um canal de mensagens de saída por consumidor. Os consumidores são conhecidos como assinantes.

  • Um mecanismo para copiar cada mensagem do canal de entrada para os canais de saída para todos os assinantes interessados nessa mensagem. Esta operação é normalmente tratada por um intermediário, como um corretor de mensagens ou um autocarro de eventos.

O diagrama a seguir mostra os componentes lógicos deste padrão:

Publicar-subscrever padrão usando um corretor de mensagens

Pub/sub-mensagem tem os seguintes benefícios:

  • Separa subsistemas que ainda precisam de comunicar. Os subsistemas podem ser geridos de forma independente e as mensagens podem ser corretamente geridas mesmo que um ou mais recetores estejam offline.

  • Aumenta a escalabilidade e melhora a capacidade de resposta do remetente. O remetente pode enviar rapidamente uma única mensagem para o canal de entrada e, em seguida, voltar às suas principais responsabilidades de processamento. A infraestrutura de mensagens é responsável por garantir que as mensagens são entregues aos assinantes interessados.

  • Melhora a fiabilidade. As mensagens assíncronos ajudam as aplicações a continuar a funcionar sem problemas sob cargas aumentadas e a lidar com falhas intermitentes de forma mais eficaz.

  • Permite o processamento diferido ou programado. Os assinantes podem esperar para recolher mensagens até horas de ponta, ou as mensagens podem ser encaminhadas ou processadas de acordo com um horário específico.

  • Permite uma integração mais simples entre sistemas que utilizam diferentes plataformas, linguagens de programação ou protocolos de comunicação, bem como entre sistemas e aplicações no local que estão a decorrer na nuvem.

  • Facilita fluxos de trabalho assíncronos em toda uma empresa.

  • Melhora a capacidade de teste. Os canais podem ser monitorizados e as mensagens podem ser inspecionadas ou registadas como parte de uma estratégia global de teste de integração.

  • Proporciona a separação das suas aplicações. Cada aplicação pode focar-se nas suas capacidades centrais, enquanto a infraestrutura de mensagens lida com tudo o que é necessário para encaminhar as mensagens de forma fiável para vários consumidores.

Problemas e considerações

Na altura de decidir como implementar este padrão, considere os seguintes pontos:

  • Tecnologias existentes. Recomenda-se vivamente a utilização de produtos e serviços de mensagens disponíveis que suportem um modelo de subscrição de publicação, em vez de construir o seu próprio. Em Azure, considere usar o Service Bus, Event Hubs ou Event Grid. Outras tecnologias que podem ser usadas para mensagens pub/sub incluem Redis, RabbitMQ e Apache Kafka.

  • Tratamento de assinaturas. A infraestrutura de mensagens deve fornecer mecanismos que os consumidores possam utilizar para subscrever ou cancelar a subscrição dos canais disponíveis.

  • A segurança. A ligação a qualquer canal de mensagem deve ser restringida pela política de segurança para evitar escutas por utilizadores ou aplicações não autorizadas.

  • Subconjuntos de mensagens. Normalmente, os assinantes só estão interessados no subconjunto das mensagens distribuídas por um editor. Os serviços de mensagens permitem frequentemente que os assinantes reduzam o conjunto de mensagens recebidas por:

    • Tópicos. Cada tópico tem um canal de saída dedicado, e cada consumidor pode subscrever todos os tópicos relevantes.
    • Filtragem de conteúdo. As mensagens são inspecionadas e distribuídas com base no conteúdo de cada mensagem. Cada subscritor pode especificar o conteúdo em que está interessado.
  • Assinantes wildcard. Considere permitir que os subscritores subscrevam vários tópicos através de wildcards.

  • Comunicação bidisal. Os canais de um sistema de subscrição de publicação são tratados como unidirecionais. Se um assinante específico precisar de enviar o estado de reconhecimento ou de comunicação ao editor, considere utilizar o Padrão de Pedido/Resposta. Este padrão utiliza um canal para enviar uma mensagem ao assinante e um canal de resposta separado para comunicar de volta ao editor.

  • Pedido de mensagem. A ordem em que os casos de consumidores recebem mensagens não está garantida, e não reflete necessariamente a ordem em que as mensagens foram criadas. Desenhe o sistema para garantir que o processamento de mensagens é idempotente para ajudar a eliminar qualquer dependência da ordem de tratamento de mensagens.

  • Prioridade da mensagem. Algumas soluções podem exigir que as mensagens sejam processadas numa ordem específica. O padrão de Fila Prioritária fornece um mecanismo para garantir que mensagens específicas são entregues antes de outras.

  • Mensagens venenosas. Uma mensagem incorretamente formada ou uma tarefa que requer acesso a recursos indisponíveis pode fazer com que uma instância de serviço falhe. O sistema deve evitar que tais mensagens sejam devolvidas à fila. Em vez disso, capture e guarde os detalhes destas mensagens em outros lugares para que possam ser analisadas se necessário.

  • Mensagens repetidas. A mesma mensagem pode ser enviada mais de uma vez. Por exemplo, o remetente pode falhar depois de publicar uma mensagem. Em seguida, uma nova instância do remetente pode começar e repetir a mensagem. A infraestrutura de mensagens deve implementar a deteção e remoção de mensagens duplicadas (também conhecida como descodução) com base em IDs de mensagens, a fim de fornecer no máximo uma vez a entrega de mensagens.

  • Expiração da mensagem. Uma mensagem pode ter uma vida limitada. Se não for processado dentro deste período, pode deixar de ser relevante e deve ser descartado. Um remetente pode especificar um tempo de validade como parte dos dados na mensagem. Um recetor pode examinar esta informação antes de decidir se executa a lógica de negócio associada à mensagem.

  • Agendamento de mensagens. Uma mensagem pode ser temporariamente embargada e não deve ser processada até uma data e hora específicas. A mensagem só deve estar disponível para um recetor desta vez.

Quando utilizar este padrão

Utilize este padrão quando:

  • Um pedido precisa de transmitir informações a um número significativo de consumidores.

  • Uma aplicação precisa de comunicar com uma ou mais aplicações ou serviços desenvolvidos de forma independente, que podem utilizar diferentes plataformas, linguagens de programação e protocolos de comunicação.

  • Um pedido pode enviar informações aos consumidores sem exigir respostas em tempo real dos consumidores.

  • Os sistemas que estão a ser integrados destinam-se a suportar um modelo de consistência eventual para os seus dados.

  • Uma aplicação precisa de comunicar informação a vários consumidores, que podem ter diferentes requisitos de disponibilidade ou horários de atualização do que o remetente.

Este padrão poderá não ser prático quando:

  • Um pedido tem apenas alguns consumidores que precisam de informações significativamente diferentes da aplicação de produção.

  • Uma aplicação requer uma interação quase em tempo real com os consumidores.

Exemplo

O diagrama seguinte mostra uma arquitetura de integração empresarial que usa o Service Bus para coordenar fluxos de trabalho, e Grade de Eventos para notificar subsistemas de eventos que ocorrem. Para obter mais informações, consulte a integração da Enterprise no Azure utilizando filas de mensagens e eventos.

Arquitetura de integração empresarial

Passos seguintes

As seguintes orientações podem ser relevantes na implementação deste padrão:

Os seguintes padrões podem ser relevantes na implementação deste padrão:

  • Padrão de observador. O padrão Publish-Subscribe baseia-se no padrão do Observador, dissociando os sujeitos dos observadores através de mensagens assíncronos.

  • Padrão de corretor de mensagens. Muitos subsistemas de mensagens que suportam um modelo de subscrição de publicação são implementados através de um corretor de mensagens.