Compartir a través de


Patrón de publicador y suscriptor

El patrón Publisher-Subscriber permite a las aplicaciones difundir eventos de forma asincrónica a varios consumidores interesados sin acoplar los remitentes y los receptores. Este enfoque se conoce como mensajería pub/sub.

Contexto y problema

Las aplicaciones distribuidas y basadas en la nube suelen incluir componentes del sistema que envían información a otros componentes a medida que se producen eventos. Cuando un remitente se comunica directamente con sus consumidores, debe conocer la identidad y el punto de conexión de cada consumidor, entregar mensajes a cada consumidor y administrar errores individualmente. Agregar o quitar un consumidor requiere cambios en el remitente, lo que limita la forma en que los equipos independientes pueden desarrollar e implementar componentes.

Las colas de mensajes desacoplan a los remitentes de los consumidores e impiden que el remitente bloquee un proceso mientras espera una respuesta. Una cola estándar crea una relación directa entre un remitente y un único consumidor. Para soportar múltiples consumidores, el emisor debe crear una cola separada para cada consumidor, lo que aumenta la complejidad del enrutamiento y no escala bien. Algunos consumidores solo necesitan un subconjunto de la información que genera el remitente, pero las colas no proporcionan formas integradas de filtrar los mensajes por contenido o categoría.

Muchos escenarios requieren que un remitente anuncie eventos a muchos consumidores interesados sin saber quiénes son esos consumidores. Cada consumidor también necesita una manera de decidir de forma independiente qué eventos recibir.

Solución

Introduzca un subsistema de mensajería asincrónica que incluya los siguientes componentes:

  • Un canal de mensajería de entrada que usa el remitente. El remitente empaqueta eventos en mensajes mediante un formato de mensaje conocido y envía estos mensajes a través del canal de entrada. El remitente de este patrón también se conoce como publicador.

    Nota:

    Un mensaje es un paquete de datos. Un evento es un mensaje que notifica a otros componentes sobre un cambio o una acción que se produce. Este patrón normalmente funciona con eventos, pero también incluye cualquier tipo de mensaje, incluidos los comandos y las notificaciones de estado.

  • Un canal de mensajería de salida para cada consumidor. Los consumidores se conocen como suscriptores.

  • Un mecanismo para copiar cada mensaje del canal de entrada a los canales de salida para todos los suscriptores interesados en ese mensaje. Un intermediario como un agente de mensajes o un bus de eventos normalmente controla esta operación.

En el diagrama siguiente se muestran los componentes lógicos de este patrón.

El diagrama muestra un patrón de publicación-suscripción que utiliza un intermediario de mensajes.

El diagrama muestra un publicador a la izquierda. Una flecha apunta a un canal de entrada. Una flecha apunta desde el canal de entrada a un agente de mensajes en el centro. Una flecha apunta desde el agente de mensajes a un canal de salida. Tres flechas apuntan desde el canal de salida a tres suscriptores independientes a la derecha.

La mensajería de publicación y suscripción tiene las siguientes ventajas:

  • Desacopla los subsistemas que necesitan comunicarse. Los subsistemas admiten la administración independiente y el agente conserva los mensajes incluso si uno o varios receptores están sin conexión.

  • Aumenta la escalabilidad y mejora la capacidad de respuesta del remitente. El remitente envía un único mensaje al canal de entrada y, a continuación, vuelve a sus responsabilidades principales de procesamiento. La infraestructura de mensajería enruta los mensajes a los suscriptores interesados.

  • Aísla los errores. Un error de suscriptor no afecta al publicador u otros suscriptores, y el agente conserva los mensajes hasta que un suscriptor recuperado esté listo para procesarlos.

  • Admite el procesamiento diferido o programado. Los suscriptores pueden esperar a recoger mensajes hasta las horas no punta, o el sistema puede enrutar o procesar mensajes según una programación específica.

  • Admite la integración entre sistemas que usan diferentes plataformas, lenguajes de programación y protocolos de comunicación, y también conecta sistemas locales con aplicaciones que se ejecutan en la nube.

  • Mejora la capacidad de prueba. Los canales admiten la supervisión y los mensajes están disponibles para inspección o registro como parte de una estrategia de prueba de integración.

  • Proporciona separación de preocupaciones para las aplicaciones. Cada aplicación puede centrarse en sus funcionalidades principales, mientras que la infraestructura de mensajería controla el trabajo necesario para enrutar mensajes de forma confiable a varios consumidores.

Problemas y consideraciones

Tenga en cuenta los siguientes puntos a medida que decida cómo implementar este patrón:

  • Tecnologías existentes: Use servicios y productos de mensajería que admitan un modelo de publicación y suscripción en lugar de crear el suyo propio. En Azure, tenga en cuenta los siguientes servicios:

    • Azure Service Bus para la mensajería que requiere transacciones, pedidos, sesiones o colas de mensajes fallidos.

    • Azure Event Grid para las notificaciones de envío push basadas en eventos, especialmente cuando Azure recursos cambian el estado y necesitan notificar a los componentes suscritos.

    • Azure Event Hubs para escenarios de streaming de eventos de alto rendimiento, como la ingesta de telemetría y la agregación de registros. Event Hubs usa un modelo de streaming basado en registros en lugar de mensajería pub/sub tradicional, pero admite varios grupos de consumidores que leen la misma secuencia de forma independiente.

    Para obtener más información, vea Choose entre servicios de Azure que entregan mensajes. Otras tecnologías que admiten la mensajería pub/sub incluyen Redis, RabbitMQ y Apache Kafka.

    Bibliotecas como MassTransit y NServiceBus proporcionan compatibilidad integrada con el modelo publish-subscribe en Service Bus y otras tecnologías de mensajería.

  • Control de suscripciones: La infraestructura de mensajería debe proporcionar mecanismos que los consumidores usen para suscribirse a canales disponibles o cancelar la suscripción.

  • Seguridad: Autentíquese y autorice tanto a los publicadores como a los suscriptores por tema. Los publicadores no autorizados que insertan mensajes pueden dañar un sistema tanto como los suscriptores no autorizados que los lean. Cifre los mensajes en tránsito y, si el contenido es confidencial, cifréelos en reposo en el intermediario para evitar el espionaje.

  • Subconjuntos de mensajes: Los suscriptores suelen estar interesados en un subconjunto de mensajes de un publicador. A menudo, los servicios de mensajería permiten a los suscriptores seleccionar lo que reciben a través de los siguientes mecanismos:

    • Temas: Cada tema tiene un canal de salida dedicado y cada consumidor puede suscribirse a todos los temas pertinentes.

    • Filtrado de contenido: El agente inspecciona y distribuye los mensajes en función de su contenido. Cada suscriptor puede especificar el contenido que necesita.

    Elija la granularidad del tema deliberadamente. Los temas generales son más sencillos de administrar, pero requieren que los suscriptores filtren los mensajes que no necesitan. Los temas estrechos reducen el filtrado del lado suscriptor, pero aumentan el número de temas que se van a administrar. Algunos agentes admiten suscripciones con caracteres comodín, como , que permiten que los suscriptores coincidan con varios temas sin enumerar cada uno.

  • Comunicación bidireccional: Los canales de un sistema de publicación y suscripción son unidireccionales. Si un suscriptor necesita confirmar o comunicar el estado al publicador, use el patrónRequest-Reply. Este patrón usa un canal para enviar un mensaje al suscriptor y un canal de respuesta independiente para comunicarse con el publicador.

  • Ordenación de mensajes: El orden en que los suscriptores reciben mensajes no está garantizado y no refleja necesariamente el orden en el que el remitente los creó. Si el orden es importante, el broker podría admitir la entrega ordenada dentro de una partición o sesión, pero esto limita la escalabilidad. Diseñe suscriptores para gestionar los mensajes independientemente del orden de llegada.

  • Prioridad del mensaje: Algunas cargas de trabajo requieren que se procesen mensajes específicos antes que otros. El patrón Cola de prioridad proporciona un mecanismo para enrutar mensajes de mayor prioridad antes de los mensajes de prioridad inferior.

  • Mensajes dudosos: Un mensaje con formato incorrecto o una tarea que requiere acceso a recursos no disponibles puede provocar un error en una instancia de servicio. Capture y almacene estos detalles del mensaje en otra parte para su análisis. Algunos agentes de mensajes, como Service Bus, admiten este proceso a través de colas de mensajes muertos.

  • Tamaño del mensaje: Los brokers aplican límites al tamaño de los mensajes. Cuando las cargas son grandes, almacene el contenido, como archivos o imágenes, en un almacén de datos externo e incluya una referencia en el mensaje. El patrónClaim-Check describe este enfoque.

  • Garantías de entrega y mensajes duplicados: Los sistemas de mensajería proporcionan diferentes garantías de entrega que cada una tiene desventajas.

    • La entrega como máximo una vez minimiza la sobrecarga, pero puede perder mensajes si el agente o suscriptor falla.

    • La entrega al menos una vez garantiza la entrega de mensajes, pero puede dar lugar a duplicados, como cuando un remitente produce un error después de publicar un mensaje y una nueva instancia repite la publicación.

    • La entrega exactamente una vez quita duplicados, pero agrega sobrecarga y latencia de coordinación, y su disponibilidad depende de la infraestructura de mensajería.

    Si el agente no proporciona desduplicación, diseñe los suscriptores para que gestionen los mensajes de manera idempotente. Es posible que distintos suscriptores de la misma carga de trabajo requieran garantías diferentes.

  • Expiración del mensaje: Algunos mensajes tienen una duración limitada. Si un receptor no procesa un mensaje dentro de ese período, el mensaje pasa a ser irrelevante y el sistema lo descarta. Establezca una marca de tiempo de expiración en los datos del mensaje para que los receptores puedan comprobar su relevancia antes de procesarla.

  • Programación de mensajes: Un mensaje puede estar embargado y no disponible para su procesamiento hasta una fecha y hora específicas. Establezca una marca de tiempo de liberación para que el sistema de mensajería retenga el mensaje hasta ese punto.

  • Evolución del esquema de mensajes: Los publicadores y suscriptores se implementan de forma independiente, por lo que los esquemas de mensajes cambian con el tiempo. Prefiere cambios compatibles con versiones anteriores, como agregar campos opcionales, para que los suscriptores existentes sigan funcionando. Para cambios disruptivos, utiliza la versión a través de nombres de tema, como , o mediante un campo de versión en los metadatos del mensaje. Los suscriptores deben omitir los campos que no reconocen.

  • Correlación: El agente desacopla publicadores de suscriptores, lo que dificulta el seguimiento del flujo de extremo a extremo de un mensaje. Incluya un identificador de correlación en cada mensaje para que los suscriptores y los sistemas de registro puedan conectar operaciones relacionadas a un único seguimiento.

  • Contrapresión y escalado: Cuando los suscriptores no pueden mantenerse al día, los mensajes sin procesar se acumulan en el intermediario y es posible que se agoten sus recursos. Utilice la configuración del control de flujo del intermediario para limitar los mensajes no reconocidos de cada suscriptor. Aumentar suscriptores utilizando el patrón de Consumidores Competidores cuando el control de flujo por sí solo no es suficiente.

Cuándo usar este patrón

Use este patrón en los siguientes supuestos:

  • Una aplicación necesita difundir información a un número significativo de consumidores.

  • Una aplicación debe comunicarse con aplicaciones o servicios desarrollados de forma independiente. Pueden usar diferentes plataformas, lenguajes de programación o protocolos de comunicación.

  • Una aplicación puede enviar información a los consumidores sin necesidad de respuestas en tiempo real de ellos.

  • Los sistemas que se están integrando están diseñados para admitir un eventual modelo de consistencia para sus datos.

  • Una aplicación debe comunicar información a varios consumidores que tienen diferentes requisitos de disponibilidad o programaciones de tiempo de actividad que el remitente.

Este patrón podría no ser adecuado cuando:

  • Una aplicación solo tiene unos pocos consumidores que necesitan información significativamente diferente de la aplicación de producción. La sobrecarga de un agente agrega complejidad sin ninguna ventaja de escalado. La comunicación directa o las colas independientes pueden ser más adecuadas.

  • Una aplicación requiere una interacción casi en tiempo real con los consumidores. El modelo pub/sub introduce latencia a través del bróker. Use un patrón de solicitud-respuesta cuando el publicador requiera una respuesta sincrónica.

  • Los consumidores deben procesar mensajes en un orden específico garantizado. Los sistemas pub/sub generalmente no garantizan el orden entre los suscriptores, y mantener dicho orden agrega restricciones significativas al diseño del intermediario y del consumidor.

  • La operación requiere una única transacción atómica entre el editor y sus consumidores. La mensajería pub/sub es intrínsecamente asincrónica y finalmente coherente. Si necesita garantías transaccionales, considere una transacción directa de base de datos o el patrón Saga para coordinar transacciones distribuidas.

Diseño de cargas de trabajo

Evalúe cómo usar el patrón de Publisher-Subscriber en el diseño de una carga de trabajo para abordar los objetivos y principios descritos en los pilares de Azure Well-Architected Framework. En la tabla siguiente se proporciona una guía sobre cómo este patrón apoya los objetivos de cada pilar.

Fundamento Cómo apoya este patrón los objetivos de los pilares
Las decisiones de diseño de fiabilidad ayudan a que su carga de trabajo sea resiliente a fallos y garantizan que se recupere a un estado de pleno funcionamiento después de que se produzca un fallo. Este patrón desacopla los componentes para que pueda establecer destinos de confiabilidad independientes y quitar dependencias directas.

RE:03 Análisis del modo de error
RE:07 Trabajos en segundo plano
Las decisiones de diseño de seguridad ayudan a garantizar la confidencialidad, integridad y disponibilidad de los datos y sistemas de su carga de trabajo. Este patrón presenta un límite claro de segmentación de seguridad. Úselo para aislar los suscriptores de cola del publicador en el nivel de red.

SE:04 Segmentación
La optimización de costos se centra en mantener y mejorar el retorno de la inversión (ROI) de su carga de trabajo. Este diseño desacoplado admite arquitecturas controladas por eventos que se alinean con los modelos de facturación basados en el consumo y ayudan a evitar el sobreaprovisionamiento.

CO:05 Optimización de velocidad
CO:12 Costos de escalado
La excelencia operativa ayuda a ofrecer calidad de carga de trabajo a través de procesos estandarizados y cohesión de equipos. El agente como intermediario le permite cambiar la implementación en el lado publicador o suscriptor sin coordinar los cambios en ambos componentes.

OE:06 Desarrollo de carga de trabajo
OE:11 Procedimientos de implementación seguros
Eficiencia del rendimiento ayuda a su carga de trabajo a satisfacer eficientemente las demandas mediante optimizaciones en el escalado, los datos y el código. El desacoplamiento de publicadores de consumidores permite optimizar el proceso y el código de las tareas específicas que cada consumidor gestiona para un tipo determinado de mensaje.

PE:02 Planeamiento de capacidad
PE:05 Escalado y particionamiento

Si este patrón introduce concesiones dentro de un pilar, considérelas en relación con los objetivos de los otros pilares.

Ejemplo

En el diagrama siguiente se muestra una arquitectura de integración empresarial que usa Service Bus para coordinar flujos de trabajo y Event Grid para notificar a los subsistemas de eventos que se producen. Para obtener más información, consulte la integración empresarial en Azure mediante colas de mensajes y eventos.

Diagrama de arquitectura de un patrón de integración empresarial que usa un agente de mensajes y eventos.

En el extremo izquierdo, una flecha sólida con la etiqueta HTTPS apunta directamente desde las aplicaciones cliente a un icono de puerta de enlace de API. Las aplicaciones cliente se conectan a Microsoft Entra ID a través de una autenticación con etiqueta de flecha. Una flecha sólida con la etiqueta HTTPS apunta desde la puerta de enlace de API a un servicio web REST o SOAP (protocolo simple de acceso a objetos). Dos regiones están a la derecha de la puerta de enlace de API. La región superior central, con la etiqueta flujo de trabajo y orquestación, incluye tres iconos de Logic App. Una flecha punteada apunta desde un icono de aplicación lógica a Service Bus. Una flecha de puntos apunta de Service Bus al segundo icono de Logic App. Una flecha sólida con la etiqueta HTTPS apunta desde esta aplicación lógica al servicio de software como servicio (SaaS). Una flecha sin etiqueta se divide de esta línea y apunta a los servicios de Azure. Otra flecha punteada apunta de Event Grid a la tercera aplicación lógica. Una flecha sólida etiquetada como HTTPS señala desde esta aplicación lógica al servicio SaaS. Una flecha sin etiqueta se divide de esta línea y apunta a los servicios de Azure. La región inferior intermedia etiquetada colas, temas, suscripciones y eventos incluye Service Bus y Event Grid. Una flecha de puntos etiquetada con mensajes apunta al servicio de mensajería. En el extremo derecho, una sección etiquetada como sistemas back-end contiene tres iconos: servicio SaaS, servicios Azure y servicio basado en mensajes. Una flecha de puntos etiquetada como "eventos" apunta desde los servicios de Azure a Event Grid. Una flecha de puntos etiquetada como enviar o recibir mensajes apunta desde el servicio basado en mensajes hacia el Service Bus.

Pasos siguientes

  • Opciones de mensajería asincrónica
  • No necesita la entrega ordenada
  • Estilo de arquitectura controlada por eventos
  • Procesamiento de mensajes idempotentes
  • Integración empresarial en Azure mediante colas de mensajes y eventos