Sistema multimedia en la nube de Gridwich

Azure Blob Storage
Azure Event Grid
Azure Functions
Azure Logic Apps

Las canalizaciones de Gridwich ingieren, procesan, almacenan y entregan recursos multimedia con la ayuda de dos nuevos métodos, el sándwich de Azure Event Grid y el sándwich de Terraform.

Architecture

La arquitectura de Gridwich incluye dos sándwiches que solucionan los requisitos del procesamiento de eventos asincrónicos y la infraestructura como código:

  • El sándwich de Event Grid abstrae los procesos remotos y de ejecución prolongada, como la codificación multimedia del sistema de flujo de trabajo de saga externo, situándolos entre dos controladores de Event Grid, como un sándwich. Este sándwich permite que el sistema externo envíe un evento de solicitud, supervise los eventos programados y espere a que se produzca una respuesta de realización correcta o error, que puede llegar minutos u horas más tarde.

    Diagram showing the Event Grid handler sandwich.

    Descargue un archivo Visio de esta arquitectura.

  • El sándwich de Terraform es un patrón de Terraform de varias fases que se ha actualizado para admitir el uso de la infraestructura como código. La separación de la infraestructura y el lanzamiento del software implica que la aplicación de Azure Functions debe haberse lanzado y estar ejecutándose antes de que Terraform pueda implementar la suscripción de Event Grid. Para cumplir con este requisito, la canalización de CI/CD incluye dos trabajos de Terraform:

    Diagram showing the Terraform sandwich jobs.

    • Terraform 1 crea todos los recursos excepto las suscripciones de Azure Event Grid.
    • Terraform 2 crea las suscripciones de Event Grid después de que el software esté en funcionamiento.

    De esta manera, Terraform puede ocuparse de toda la administración e implementación de la infraestructura de la solución, incluso aunque no se puedan crear todos los recursos de Azure antes de que se implementen los artefactos de software.

Flujo de trabajo

El proceso de solicitud y respuesta de Gridwich cubre los siguientes aspectos de las solicitudes siguientes:

  • Creación
  • Transporte
  • Reception
  • Distribución a componentes de Gridwich
  • Confirmación y acciones
  • Respuestas

En los pasos siguientes se describe el proceso de solicitud y respuesta entre un sistema externo y Gridwich. En Gridwich, el sistema externo es un sistema MAM y de orquestación de flujos de trabajo de saga. Para conocer los formatos exactos de los eventos de mensajes de operaciones de Gridwich, consulte Formatos de mensaje de Gridwich.

Diagram showing the Gridwich request-response process.

  1. El sistema externo crea una solicitud y la envía al agente de solicitudes.

  2. El agente de solicitudes es responsable de enviar las solicitudes a los clientes de escucha de solicitudes de Gridwich según un modelo tradicional de publicación-suscripción. En esta solución, el agente de solicitudes es Azure Event Grid. Todas las solicitudes se encapsulan con el esquema de eventos de Event Grid.

  3. La aplicación de Azure Functions de Gridwich consume eventos de Event Grid. Para mejorar el rendimiento, Gridwich define un punto de conexión HTTP como un modelo de inserción que se inicia en Event Grid, en lugar del modelo de sondeo de enlaces de Event Grid que proporciona Azure Functions.

  4. La aplicación de Azure Functions lee las propiedades de los eventos y distribuye estos a las partes del código de Gridwich que se ocupan del tipo y versión de evento correspondientes.

  5. Cualquier controlador que vaya a trabajar con la solicitud actual utiliza la clase común EventGridHandlerBase para enviar un mensaje de confirmación tan pronto como recibe la solicitud. Después, el controlador envía el trabajo a la clase derivada.

    Los flujos de trabajo de solicitudes de Gridwich pueden ser sincrónicos o asincrónicos por naturaleza. En el caso de las solicitudes que son fáciles de realizar y que se completan rápidamente, es un controlador sincrónico el que realiza el trabajo y devuelve el evento de realización correcta o de error casi inmediatamente después de que se envíe la confirmación.

    En el caso de las solicitudes de ejecución prolongada, es un controlador asincrónico el que evalúa la solicitud, valida los argumentos e inicia la operación de ejecución prolongada. A continuación, el controlador devuelve una respuesta de evento programado para confirmar que solicitó la actividad de trabajo. Cuando se completa la actividad de trabajo, el controlador de la solicitud es responsable de proporcionar un evento de realización correcta o error del trabajo.

    El servicio de publicación de eventos comunica los mensajes de confirmación, error, evento programado o realización correcta al agente de solicitudes de Event Grid.

  6. El publicador de eventos de la función de Azure envía el evento de respuesta a un tema de Event Grid, que actúa como agente de mensajes confiable. El sistema externo se suscribe al tema y consume los mensajes. La plataforma de Event Grid proporciona su lógica de reintento normal para la publicación en el sistema externo.

Orden de los mensajes

Aunque una confirmación precede a las respuestas de realización correcta y evento programado, Gridwich no garantiza que una respuesta de evento programado vaya siempre antes de la respuesta de realización correcta correspondiente. Una secuencia de respuesta válida podría ser Confirmado > Evento programado > Realización correcta o Confirmado >Realización correcta > Evento programado.

Errores de solicitud

Los errores de solicitud pueden deberse a solicitudes incorrectas, falta de condiciones previas, errores de procesamiento, excepciones de seguridad o excepciones no controladas. Casi todos los errores tienen el mismo formato de mensaje e incluyen el valor de contexto de operación original. Por lo general, la clase EventGridHandlerBase común envía las respuestas de error a Event Grid por medio de la interfaz del publicador de eventos de Azure Functions. Application Insights también registra los errores a través de un registro estructurado.

Contexto de operación

El sistema externo puede generar miles de solicitudes por día, por hora o por segundo. Cada evento de solicitud a Gridwich debe incluir una propiedad de objeto JSON denominada operationContext.

Si una solicitud contiene un contexto de operación, como {"id"="Op1001"}, cada {"id"="Op1001"} de Gridwich debe incluir un contexto de operación opaco correspondiente, tanto si la solicitud es de ejecución breve como de ejecución prolongada. Este contexto de operación se mantiene mientras dura la solicitud, incluso en el caso de las solicitudes de ejecución muy prolongada.

El requisito de respuesta pide un objeto JSON "correspondiente" más que el "mismo" objeto JSON. Características de Gridwich como el silenciamiento del contexto aprovechan el hecho de que el sistema externo procese el objeto JSON devuelto de forma descendente.

En concreto, el sistema externo cuenta con las siguientes ventajas:

  • No tiene ninguna dependencia sobre el orden de las propiedades, por lo que Gridwich puede devolver un objeto con las mismas propiedades, posiblemente en un orden diferente. Por ejemplo, {"a":1,"b":2} en lugar de {"b":2,"a":1}.

  • No tiene ningún problema si recibe propiedades adicionales, por lo que Gridwich, habiendo recibido {"b":2,"a":1}, podría devolver {"a":1,"b":2,"~somethingExtra":"yes"} y ser válido. Para reducir la posibilidad de colisiones, Gridwich antepone a los nombres de las propiedades agregadas una tilde (~); por ejemplo, ~muted.

  • No tiene dependencia del formato JSON. Por ejemplo, no se produce ninguna suposición sobre dónde se aplicará el relleno de espacios en blanco dentro de la representación de cadena del objeto JSON. Gridwich aprovecha que no existe dependencia del formato y elimina los espacios en blanco innecesarios de las representaciones de cadena de los objetos JSON. Consulte JSONHelpers.SerializeOperationContext.

Participantes de saga y contexto de operación

En el sistema de orquestación de saga de Gridwich, cada participante de saga aporta una o varias actividades de trabajo al sistema. Cada participante de saga funciona con independencia de los demás participantes y en una única solicitud puede actuar más de un participante de saga.

Cada participante de saga debe conservar el contexto de la operación, pero puede implementarlo de forma diferente. Por ejemplo:

  • Las operaciones sincrónicas de ejecución breve conservan el contexto de la operación.
  • Azure Storage proporciona una propiedad de cadena opaca denominada ClientRequestId para la mayoría de las operaciones.
  • Algunos servicios tienen una propiedad Job.CorrelationData.
  • Otras API en la nube ofrecen conceptos similares a un contexto de operación opaco que pueden devolver para señalar el progreso, la finalización o el error.

Para obtener más información acerca de las sagas y los participantes de saga, consulte Orquestación de sagas.

Controladores sincrónicos y asincrónicos

Cada controlador de eventos del sistema utiliza una clase común EventGridHandlerBase para proporcionar servicios genéricos, como la confirmación de solicitudes, el control de errores y la publicación de eventos de respuesta. El servicio de publicación de eventos comunica los mensajes de confirmación, error, evento programado o realización correcta al agente de solicitudes de Event Grid.

Cualquier controlador que planee trabajar con la solicitud actual debe proporcionar una confirmación cuando reciba la solicitud. La clase base envía inmediatamente un mensaje de confirmación y, a continuación, envía el trabajo a la clase derivada.

Diagram showing the Acknowledgment message flow.

Procesamiento de eventos sincrónicos

En el caso de las solicitudes que son fáciles de realizar y que se completan rápidamente, el controlador hace el trabajo sincrónicamente y devuelve el evento de realización correcta, con su contexto de operación, casi inmediatamente después de que se envíe la confirmación.

Diagram showing a synchronous request-response message flow..

Por ejemplo, ChangeBlobTierHandler sigue un flujo sincrónico sencillo. El controlador obtiene un objeto de transferencia de datos (DTO) de solicitud, llama y espera a que un único servicio realice el trabajo, y devuelve una respuesta de realización correcta o error.

Diagram showing the ChangeBlobTierHandler synchronous flow example.

Procesamiento de eventos asincrónicos

Algunas solicitudes son de ejecución prolongada. Por ejemplo, la codificación de archivos multimedia puede tardar horas. En estos casos, un controlador asincrónico de solicitudes evalúa la solicitud, valida los argumentos e inicia la operación de ejecución prolongada. A continuación, el controlador devuelve una respuesta de evento programado para confirmar que solicitó la actividad de trabajo.

Diagram showing an asynchronous request-response message flow.

Cuando se completa la actividad de trabajo, el controlador de la solicitud es responsable de proporcionar un evento de realización correcta o error del trabajo. Aunque el controlador sigue sin tener estado, debe recuperar el contexto de operación original e incluirlo en la carga del mensaje de evento finalizado.

Por ejemplo, BlobCopyHandler sigue un flujo asincrónico simple. El controlador obtiene un DTO de solicitud, llama y espera que un único servicio inicie el trabajo, y publica una respuesta de evento programado o de error.

Diagram showing the BlobCopyHandler asynchronous flow example with event scheduled.

Para completar el flujo de solicitud de ejecución prolongada, BlobCreatedHandler consume el evento de plataforma Microsoft.Storage.BlobCreated, extrae el contexto de operación original y publica una respuesta de finalización correcta o con errores.

Diagram showing the BlobCopyHandler asynchronous flow example with event successful.

Funciones de ejecución prolongada

Cuando Gridwich implementa una nueva aplicación de Functions, puede anular procesos actuales de ejecución prolongada. Si estos procesos finalizan repentinamente, no se genera ningún estado y no se devuelve ningún informe al autor de la llamada. Gridwich debe implementar las nuevas aplicaciones de Functions mientras mantiene un control estable de la transición de las funciones de ejecución prolongada y evita perder mensajes.

La solución tiene que evitar ciertos comportamientos:

  • No puede mantener el estado de las instancias en ejecución de la aplicación de Gridwich.
  • No puede eliminar procesos simplemente porque se está implementando algo nuevo o porque un nuevo mensaje solicita la misma actividad.
  • No puede invocar cargas de trabajo de Azure adicionales, como las de Durable Functions, aplicaciones de Functions, Logic Apps o Azure Container Instances.

Gridwich usa la implementación de espacios y los tokens de cancelación de Azure Functions para cumplir estos requisitos y conseguir funciones confiables de larga ejecución.

En el diagrama siguiente se muestra cómo funcionan la mayoría de los trabajos de Gridwich. El cuadro verde representa un trabajo que Gridwich pasa a un servicio externo. A continuación, Gridwich reacciona de manera controlada por eventos al estado. En el cuadro rojo se muestra una función de ejecución prolongada en Gridwich.

Diagram showing short-running and long-running functions.

El sistema en tiempo de ejecución de Functions agrega el token de cancelación cuando se está cerrando la aplicación. Gridwich detecta el token y devuelve códigos de error para todas las solicitudes y los procesos que se están ejecutando en ese momento.

La implementación de espacios implementa nuevas versiones de software. El espacio de producción tiene la aplicación en ejecución y el espacio de ensayo tiene la nueva versión. Azure realiza una serie de pasos de implementación y, a continuación, intercambia las instancias de los espacios. La instancia antigua se reinicia como último paso del proceso.

Gridwich espera 30 segundos después de volver a asignar los nombres de host; por tanto, para las funciones desencadenadas por HTTP, Gridwich garantiza al menos 30 segundos antes del reinicio del espacio de producción antiguo. Otros desencadenadores pueden estar controlados por configuraciones de la aplicación que no cuentan con un mecanismo para esperar por las actualizaciones de la configuración de la aplicación. Estas funciones se arriesgan a ser interrumpidas si la ejecución se inicia justo antes de que se reinicie el antiguo espacio de producción.

Para obtener más información, consulte qué sucede durante un intercambio de espacios para Azure Functions y la página sobre espacios de implementación de Azure Functions.

Componentes

La solución Gridwich de procesamiento de elementos multimedia usa Azure Event Grid, Azure Functions, Azure Blob Storage, Azure Logic Apps y Azure Key Vault. Los procesos de CI/CD y de orquestación de saga usan Azure Repos, Azure Pipelines y Terraform.

  • Azure Event Grid administra el enrutamiento de los eventos de Gridwich, con dos trabajos de Event Grid en sándwich que permiten el procesamiento asincrónico de eventos multimedia. Event Grid es un punto de conexión de entrega de solicitudes de gran confiabilidad. La plataforma Azure proporciona la estabilidad y el tiempo de actividad necesarios para los puntos de conexión de entrega de solicitudes.

    Gridwich encapsula los eventos en el objeto de propiedad del esquema de Event GridEvent.Data, opaco para el agente de Event Grid y el nivel de transporte. Gridwich también utiliza los campos de objeto eventType y dataVersion para enrutar los eventos. Para que el agente de solicitudes de Event Grid se pueda sustituir por otros agentes de eventos de publicación-suscripción, Gridwich depende del menor número posible de campos de evento y no usa los campos topic ni subject.

  • Azure Functions permite ejecutar código desencadenado por eventos sin tener que aprovisionar ni administrar explícitamente la infraestructura. Gridwich es una aplicación de Azure Functions que hospeda la ejecución de varias funciones.

  • Azure Blob Storage proporciona un almacenamiento en la nube escalable y rentable, así como acceso a datos no estructurados, como recursos multimedia. Gridwich usa tanto blobs en bloques como contenedores de Azure Storage.

  • Azure Key Vault protege las claves criptográficas, las contraseñas y otros secretos que se usan tanto en Azure como en servicios y aplicaciones de terceros.

  • Azure DevOps es un conjunto de servicios para desarrolladores y operaciones, incluidos los repositorios de código basados en Git y las canalizaciones automatizadas de compilación y lanzamiento, que se integran con Azure. Gridwich usa Azure Repos para almacenar y actualizar los proyectos de código y Azure Pipelines para CI/CD y otros flujos de trabajo.

  • Terraform es una herramienta de código abierto que usa la infraestructura como código para aprovisionar y administrar infraestructuras y servicios.

Alternativas

  • Durable Functions, que tiene un almacén de estado integrado para operaciones de ejecución prolongada, también puede proporcionar un contexto de operación opaco. Durable Functions podría crear una serie de tareas dentro de una operación y guardar el contexto de operación como entrada o salida de la operación. De hecho, Gridwich podría usar Durable Functions para todas las actividades de trabajo, pero este enfoque aumentaría la complejidad del código.

  • Podría lograr un mejor desacoplamiento de la infraestructura de Event Grid si refactorizase la clase EventGridHandlerBase en RequestHandlerBase y quitase cualquier vinculación con objetos o tipos de Event Grid. Esta clase refactorizada solo se ocuparía de DTO base y no de tipos de objeto específicos del transporte. Del mismo modo, la clase IEventGridDispatcher podría convertirse en IResponseDispatcher con una implementación específica de EventGridDispatcher.

  • La biblioteca Gridwich.SagaParticipants.Storage.AzureStorage también contiene servicios de almacenamiento que utilizan otros participantes de la saga. Contar con las interfaces en un proyecto principal evita problemas de inversión de control (IoC), pero podría extraer las interfaces a una biblioteca de puerta de enlace de la infraestructura de almacenamiento principal independiente.

  • La aplicación de Functions de Gridwich usa la inserción de dependencias para registrar uno o varios controladores de solicitud para tipos de eventos y versiones de datos específicos. La aplicación inserta EventGridDispatcher con la colección de controladores de eventos de Event Grid y este distribuidor consulta los controladores para determinar cuáles procesarán el evento.

    También puede usar el mecanismo de suscripción y filtrado de eventos que proporciona la plataforma de Event Grid. Este mecanismo impone un modelo de implementación 1:1, según el cual una función de Azure solo hospeda un controlador de eventos. Aunque Gridwich usa un modelo 1:muchos, su arquitectura limpia implica que la refactorización de la solución al modelo 1:1 no sería difícil.

  • Para conocer un microservicio alternativo a la arquitectura monolítica de Gridwich, consulte Alternativa de microservicios.

Detalles del escenario

Un conocido conglomerado de la industria del entretenimiento y los medios de comunicación de masas sustituyó su servicio de streaming de vídeo local por una solución basada en la nube para la ingesta, el procesamiento y la publicación de recursos de vídeo. La empresa tenía como principales objetivos aprovechar la capacidad, el costo y la flexibilidad de la nube de Azure en las siguientes acciones:

  • Ingerir archivos de vídeo sin procesar, procesarlos y publicarlos, y satisfacer las solicitudes de elementos multimedia.
  • Mejorar la codificación y las nuevas funcionalidades de incorporación y distribución a gran escala, y hacerlo con un enfoque de arquitectura limpia.
  • Implementar la integración y entrega continuas (CI/CD) para la canalización de administración de recursos multimedia (MAM).

Para cumplir estos objetivos, el equipo de ingeniería de Microsoft desarrolló Gridwich, una plataforma de procesamiento de eventos sin estado controlado por un sistema de orquestación de flujos de trabajo de saga externo.

Posibles casos de uso

El equipo de ingeniería desarrolló Gridwich para cumplir los principios y los estándares del sector relacionados con estos aspectos:

El sistema Gridwich es un ejemplo de los procedimientos recomendados para el procesamiento y la entrega de recursos multimedia en Azure. Aunque es específico para elementos multimedia, la plataforma de creación de eventos y procesamiento de mensajes se puede aplicar a cualquier flujo de trabajo de procesamiento de eventos sin estado.

Implementación de este escenario