Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Coordinar un conjunto de acciones distribuidas como una sola operación lógica para que la operación en su conjunto tenga éxito o falle. Controle los errores de forma transparente o deshaga el trabajo completado. Este enfoque agrega resistencia a los sistemas distribuidos mediante la recuperación de excepciones transitorias, errores de mayor duración y errores de proceso que interrumpen los flujos de trabajo de varios pasos organizados en servicios y recursos remotos.
Contexto y problema
Las aplicaciones suelen realizar tareas que abarcan varios pasos y algunos pasos pueden invocar servicios remotos o acceder a recursos remotos en la orquestación de la lógica de la aplicación. La interacción con cualquier cosa fuera del proceso local expone la tarea a un intervalo de modos de error. La lógica de orquestación debe controlar estos modos de error sin perder la integridad de la operación en su conjunto.
Puede gestionar situaciones sencillas, como fallos transitorios que se resuelven por sí solos, mediante enfoques como el patrón de reintento. Cuando los errores son más permanentes o cuando se produce un error en el propio orquestador, el sistema debe restaurar un estado coherente a partir de registros duraderos y garantizar la integridad de la operación general.
Solución
El patrón del supervisor del agente planificador coordina una tarea distribuida de múltiples pasos a través de tres actores lógicos. Estos actores orquestan los pasos que se van a realizar como parte de la tarea general y gestionan tanto las ejecuciones satisfactorias como las fallidas.
Scheduler
Scheduler organiza los pasos que componen la tarea y organiza su ejecución. Scheduler es responsable de combinar los pasos en una canalización o flujo de trabajo y ejecutarlos en el orden correcto. A medida que progresa cada paso, Scheduler registra su estado, como paso aún no iniciado, paso en ejecución o paso completado. El estado también incluye un tiempo complete-by que limita la duración permitida del paso.
Cuando un paso necesita un servicio o recurso remoto, el Scheduler invoca a un agente adecuado y le pasa los detalles del trabajo. El programador suele comunicarse con los agentes mediante mensajes asíncronos de solicitud/respuesta, a menudo implementados a través de colas. En su lugar, puede usar otras tecnologías de mensajería distribuida.
Note
Scheduler realiza una función similar al rol Administrador de procesos en el patrón Administrador de procesos. Un motor de flujo de trabajo que el Programador controla normalmente define e implementa el flujo de trabajo, desacoplando la lógica de flujo de trabajo empresarial del propio Programador.
Agente
Un agente encapsula una llamada a un servicio remoto o acceso a un recurso remoto al que hace referencia un paso de tarea. Cada agente normalmente encapsula las llamadas a un único servicio o recurso e implementa la lógica de manejo de errores y reintento correspondientes dentro del plazo de finalización que impone el planificador. Cuando entra en juego la lógica de reintento, el agente transmite un identificador estable a lo largo de todos los intentos de reintento. Un servicio posterior puede usar esto para la eliminación de duplicados.
Si hay diferentes pasos en el flujo de trabajo que usan distintos servicios o recursos, cada paso puede hacer referencia a otro agente. Esa asignación es un detalle de implementación del patrón. Para obtener instrucciones sobre cómo diseñar estrategias de reintento, consulte Procedimientos recomendados para el control de errores transitorios.
Supervisor
El supervisor supervisa el estado de los pasos que realiza el Programador. El supervisor se ejecuta periódicamente con la frecuencia especificada por la carga de trabajo y examina el estado de los pasos que ha registrado el programador. Si el Supervisor encuentra pasos cuyo tiempo de espera ha expirado o que han fallado, dispone que el Agente adecuado recupere el paso, o activa otra acción correctiva que podría incluir la modificación del estado del paso. El supervisor solo solicita estas acciones de recuperación. El programador y los agentes los implementan.
Interacciones
Scheduler, Agent y Supervisor son componentes lógicos y su implementación física depende de la tecnología que use. Por ejemplo, puede implementar varios agentes lógicos como parte de un único servicio web o como actividades dentro del mismo worker hospedado.
Scheduler mantiene el progreso de la tarea y el estado por paso en un almacén de datos duradero denominado almacén de estado. El supervisor usa esta información para determinar si se produjo un error en un paso. En el diagrama siguiente se muestra la relación entre el Planificador, los Agentes, el Supervisor y el almacén de estado.
En la parte superior izquierda, el Scheduler organiza y ejecuta los pasos. Una línea de doble flecha con la etiqueta "El planificador solicita al agente que acceda a un recurso remoto" se dirige a un agente situado a la derecha, y una línea de doble flecha con la etiqueta "El agente accede a un recurso o servicio remoto" apunta desde el agente hacia un recurso remoto. Debajo de este, las líneas de doble flecha van desde Scheduler hasta otro agente y luego hasta un servicio remoto. Otra línea de flecha doble con la etiqueta "Scheduler mantiene el estado del paso" desciende hasta el almacén de estado. Una línea de flecha doble con la etiqueta "Supervisor supervisa el estado del paso" conecta el almacén de estado y el Supervisor a su derecha. Una flecha etiquetada como "El supervisor solicita reintentar el paso" apunta desde el supervisor hacia arriba y a la izquierda, hasta el planificador.
- Scheduler organiza y ejecuta los pasos que componen la tarea como un flujo de trabajo.
- Un paso del flujo de trabajo puede enviar una solicitud a un agente para acceder a un recurso remoto o invocar un servicio remoto. Las solicitudes y respuestas normalmente se envían de forma asincrónica.
- Un agente accede al recurso o servicio remotos. El agente debe incluir el control de errores y la lógica de reintento.
- El programador mantiene el estado de cada paso en el almacén de estados a medida que se inicia y se completa.
- El Supervisor monitoriza el estado de los pasos en el almacén de estado y puede solicitar la actualización del estado de un paso.
- El supervisor solicita al Programador que vuelva a intentar un paso con errores.
Cuando la aplicación está preparada ejecutar una tarea, envía una solicitud al componente Scheduler. Scheduler registra el estado inicial de la tarea y sus pasos, como el paso que aún no se ha iniciado, en el almacén de estado y, a continuación, comienza a ejecutar las operaciones que define el flujo de trabajo. A medida que el Scheduler inicia cada paso, actualiza el estado de ese paso, como paso en ejecución, en el almacén de estado.
Si un paso hace referencia a un servicio o recurso remoto, el componente Scheduler envía un mensaje al componente Agent adecuado. El mensaje contiene la información que el Agente necesita para invocar el servicio o acceder al recurso, junto con el plazo de finalización y el número de reintentos permitidos para la operación.
Un Agente puede implementar cualquier lógica de reintento adecuada para su tarea, pero si el Agente no completa su trabajo antes del plazo de finalización, el Programador asume que la operación falló y deja de esperar una respuesta. El Agente debe respetar el plazo y no debe iniciar nuevos efectos colaterales una vez vencido este, aunque el trabajo ya en curso puede continuar.
Si el componente Agent completa la operación correctamente, devuelve una respuesta al componente Scheduler. Scheduler actualiza el estado para completar el paso , por ejemplo, y comienza el paso siguiente. Este proceso continúa hasta que la tarea se haya completado.
Scheduler debe omitir cualquier respuesta tardía y el Agente no debe intentar la recuperación del flujo de trabajo por sí mismo. Si el propio Agent falla, el Scheduler tampoco recibe una respuesta. El estado en el almacén de estados no distingue, de forma intencionada, entre un paso que agota el tiempo de espera y uno que falla.
Cuando un paso supera el tiempo de espera o falla, el registro del almacén de estados sigue mostrando el paso como en ejecución, pero con una hora límite de finalización caducada. El Supervisor busca registros en este estado y coordina la recuperación.
El supervisor también debe evitar que el mismo paso vuelva a intentarlo indefinidamente. El supervisor mantiene un recuento de reintentos para cada paso junto con la información de estado en el almacén de estados. Si el número supera un umbral predefinido, se puede configurar el Supervisor para que espere un período prolongado antes de pedir al Planificador que reintente el paso, por si el fallo subyacente se resuelve durante ese intervalo.
Una posible estrategia del Supervisor es ampliar el valor de complete-by y enviar un mensaje al Planificador identificando el paso que excedió el tiempo de espera, para que el Planificador pueda volver a intentarlo. Este diseño requiere que la lógica del paso sea idempotente, ya que el mismo trabajo puede realizarse más de una vez.
Como alternativa, el supervisor puede pedir al Programador que deshaga toda la tarea desencadenando una transacción de compensación. Este enfoque depende de que el Scheduler y los agentes proporcionen suficiente información para implementar operaciones de compensación para cada paso que ya se haya completado correctamente. El registro de compensación necesita ordenación, así como durabilidad, ya que las operaciones de compensación se ejecutan normalmente en el orden inverso de los pasos que se completaron. Una operación de compensación que a su vez falla deja la tarea en un estado en el que no está ni completada ni deshecha limpiamente. El almacén de estado debe ser capaz de representar esta condición para que los operadores puedan localizarlo e investigarlo.
Note
El supervisor no supervisa el programador y los agentes y los reinicia si se produce un error. Ese rol pertenece a la infraestructura de hospedaje. El supervisor tampoco necesita conocer las operaciones de negocio que ejecuta el Scheduler, incluido cómo compensarlas si fallan. Ese conocimiento pertenece a la lógica de flujo de trabajo que ejecuta Scheduler. El supervisor solo es responsable de detectar que un paso ha fallado y de disponer que ese paso se repita o que se deshaga toda la tarea que contiene el paso fallido.
En una implementación real de este patrón, varias instancias del Programador se pueden ejecutar simultáneamente, cada una de las cuales controla un subconjunto de tareas. El sistema también puede ejecutar varias instancias de cada agente o varios supervisores. Cuando hay más de un supervisor activo, los supervisores deben coordinarse para que no compitan para recuperar el mismo paso o tarea con errores. El patrón de elección del líder es una manera de coordinar supervisores.
La principal ventaja de este patrón es que el sistema sigue siendo resistente a errores transitorios e irrecuperables, y puede crearlo para que sea de recuperación automática. Si falla un Agente o el Programador, puede iniciar una nueva instancia, y el Supervisor puede encargarse de que la tarea afectada se reanude. Si falla el propio Supervisor, otra instancia puede retomar la ejecución desde donde la anterior se detuvo. Cuando el supervisor se ejecuta según una programación, se inicia automáticamente una nueva instancia en el siguiente intervalo. También puede replicar el almacén de estado para lograr una mayor resiliencia.
Problemas y consideraciones
Tenga en cuenta los siguientes puntos al decidir cómo implementar este patrón:
Complejidad de la implementación. Este patrón es difícil de implementar y requiere pruebas exhaustivas de cada modo de error que el sistema puede experimentar. Planifica las pruebas de inyección de fallos junto con las pruebas funcionales.
Amplificación de reintentos. Los límites de reintento independientes en el agente, el entorno de ejecución de orquestación, la biblioteca cliente, la mensajería y los niveles supervisor multiplican el número de llamadas a una dependencia con errores. Designa al programador como propietario de un presupuesto de reintentos duradero de extremo a extremo y configura o desactiva los reintentos en las demás capas, de modo que su máximo combinado no pueda superar dicho presupuesto.
Control de admisión. El patrón no limita cuánto trabajo puede estar en curso al mismo tiempo. Dado que el Scheduler está diseñado para no perder nunca el trabajo que acepta, un servicio posterior lento o que falla provoca una acumulación creciente de registros de procesamiento, en lugar de una contrapresión visible para el emisor. La vía de envío necesita su propio control de admisión, como una cola limitada, un límite de tareas concurrentes en ejecución o el rechazo de nuevos envíos cuando la cola de trabajo pendiente supera un umbral. Esta contrapresión ayuda a garantizar que una incidencia aguas abajo no cause de forma silenciosa una acumulación ilimitada en el almacén de estado.
Durabilidad del estado de recuperación. La lógica de recuperación y reintento del Scheduler es compleja y depende del estado almacenado en el almacén de estados. También es posible que tenga que registrar la información necesaria para impulsar una transacción de compensación en un almacén duradero y la propia transacción de compensación puede producir un error. Trate el almacén de estado y cualquier registro de transacciones compensatorias como recursos duraderos de primera clase. Estos activos deben sobrevivir al programador, a los agentes y al supervisor, y deben ser recuperables independientemente de los trabajadores que escriban en ellos.
Importante
El registro de la transacción compensatoria debe heredar la clasificación de los datos que necesita rastrear. Si un paso acepta datos de clientes o de pago, el registro de la transacción compensatoria hereda ese nivel de sensibilidad y las reglas de retención correspondientes.
Problema de escritura doble. El envío de una tarea normalmente implica más de una escritura duradera. Por ejemplo, una tarea podría necesitar escribir tanto un registro de la aplicación en una base de datos corporativa como un registro inicial en el repositorio de estado. Estas operaciones de escritura no comparten la misma transacción, por lo que, si solo se completa una de las operaciones, es posible que un registro de la aplicación no tenga ningún registro del almacén de estado, o que un registro del almacén de estado no tenga ningún registro de la aplicación. El patrón actual no resuelve este problema de escritura dual. Entre las soluciones habituales se incluyen realizar la escritura en una orquestación duradera con un borrado compensatorio en caso de error, aplicar el patrón Transactional Outbox o usar un identificador estable, como el identificador de tarea de la propia aplicación, de modo que cada escritura pueda repetirse de forma segura.
Control de versiones del flujo de trabajo y del estado. Las tareas de larga duración pueden extenderse a lo largo de varios despliegues, por lo que los cambios en la lógica del flujo de trabajo o en el estado persistente pueden impedir el reprocesamiento, la recuperación o la compensación de las operaciones en curso. Versione ambos contratos y conserve el control de estado y el código compatibles hasta que ninguna tarea activa dependa de ellos.
Resultados de compensación. Una transacción de compensación puede completarse, fallar o quedar bloqueada a mitad del proceso. La máquina de estados que mantiene el Scheduler debe representar todos estos estados. Si Error es el único estado terminal, una compensación bloqueada es idéntica a un paso que produjo un error antes de ejecutar la compensación y los operadores pierden la señal que necesitan intervenir. Distinguir la compensación en curso, la compensación completada y la compensación fallida en el esquema del almacén de estados, en lugar de agruparlos en un único estado Error.
Ritmo del supervisor. La frecuencia con la que se ejecuta el supervisor es una decisión deliberada. Debería ejecutarse con la suficiente frecuencia como para que los pasos que fallen o agoten el tiempo de espera no bloqueen el trabajo durante demasiado tiempo, pero no con tanta frecuencia como para que se convierta en una fuente de carga y costes para el almacén de estado. Ajuste el intervalo con respecto a la duración típica del paso y el retraso de detección aceptable para un paso bloqueado y vuelva a revisarlo a medida que crece el volumen de flujo de trabajo.
Idempotencia del paso. Un agente puede ejecutar un paso más de una vez. Por ejemplo, el Supervisor podría ampliar el plazo de finalización y pedir al Scheduler que reintente un paso cuya ejecución original ya produjo un efecto que el Scheduler nunca llegó a ver. Por lo tanto, la lógica que implementa cada paso debe ser idempotente.
Visibilidad operativa. El comportamiento en tiempo de ejecución del patrón reside en las transiciones del almacén de estados, en lugar de en respuestas síncronas. Los operadores únicamente pueden ver lo que emiten el almacén de estado y los procesos de trabajo. Decida qué programadores, agentes y supervisor deben emitir y qué umbrales deben desencadenar alertas.
Reinicio y recuperación del planificador. Si el planificador se reinicia tras un fallo, o el flujo de trabajo que está ejecutando termina inesperadamente, el planificador debe poder determinar el estado de cualquier tarea que estuviera gestionando cuando falló y reanudar la tarea desde ese punto. Los detalles de implementación de esta recuperación suelen ser específicos del sistema. Por ejemplo, un planificador basado en un entorno de ejecución de orquestación con puntos de control puede apoyarse en ese entorno para reproducir el historial de ejecución y reanudar la ejecución, mientras que un planificador personalizado tiene que reconstruir el estado de las operaciones en curso a partir del propio almacén de estado. Si no se puede recuperar una tarea, es posible que sea necesario deshacer el trabajo que ya se ha realizado para esa tarea, lo que puede requerir una transacción de compensación.
Cuándo usar este patrón
Use este patrón cuando:
Un proceso se ejecuta en una carga de trabajo distribuida y debe permanecer resistente a los errores de comunicación y a los errores operativos en los servicios y los recursos que coordina.
Los trabajos en segundo plano orquestan flujos de trabajo de varios pasos cuyas etapas implican servicios o recursos remotos, y esos flujos de trabajo, en su conjunto, deben completarse o revertirse correctamente. Entre los ejemplos comunes se incluyen el procesamiento de pedidos y el aprovisionamiento de recursos. Para obtener más información, consulte Procedimientos recomendados para trabajos en segundo plano.
Este patrón podría no ser adecuado cuando:
- La tarea no invoca servicios remotos ni accede a recursos remotos. No existe ninguna superficie de fallo distribuida que mitigar para los roles Scheduler, Agent y Supervisor. La sobrecarga de coordinación del patrón agrega costos sin ninguna ventaja de resistencia.
Diseño de cargas de trabajo
Evalúa cómo utilizar el patrón Programador-Agente-Supervisor en el diseño de una carga de trabajo para cumplir los objetivos y principios recogidos en los pilares del Marco de arquitectura recomendada de Azure. 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 usa un almacén de estado duradero y un supervisor periódico para detectar los pasos que han agotado el tiempo de espera o han producido errores y para impulsar la recuperación. - RE:05 Redundancia - RE:07 Autopreservación |
| 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. | Este patrón separa la orquestación del trabajo de larga duración y de varios pasos de los agentes que realizan dichos pasos, de modo que estos puedan asignarse a los agentes que dispongan de capacidad. El trabajo de prioridad más alta se puede programar antes del trabajo de prioridad inferior cuando la implementación proporciona una señal de prioridad explícita. - PE:05 Escalado y particionamiento - PE:09 Flujos críticos |
Si este patrón introduce concesiones dentro de un pilar, considérelas en relación con los objetivos de los otros pilares.
Example
En este ejemplo se implementa una aplicación web que implementa un sistema de comercio electrónico en Microsoft Azure. Los usuarios examinan productos y realizan pedidos a través de un front-end web y los trabajadores en segundo plano en la ruta de procesamiento de pedidos llaman a un servicio remoto que es propenso a errores transitorios y duraderos. El procesamiento de pedidos implementa el patrón Scheduler Agent Supervisor mediante el uso de Durable Functions, Azure Service Bus y Azure Cosmos DB.
Una actividad de envío escribe en la base de datos de pedidos y en un almacén de estado de Cosmos DB; un orquestador de Durable Functions reclama los registros de estado pendientes y envía el trabajo a un agente a través de un par de colas de solicitud y respuesta de Service Bus; y un supervisor analiza el almacén de estado en busca de registros caducados CompleteBy veces.
En el diagrama siguiente se muestra una vista general de la solución Azure.
- La aplicación envía una solicitud a una cola para administrar el pedido.
- El proceso de presentación recupera solicitudes, inserta los detalles del pedido en la base de datos de pedidos y genera un registro del pedido en el repositorio de estado.
- El Scheduler busca un pedido con
LockedByestablecido en null en el almacén de estado, y la lógica del flujo de trabajo del Scheduler procesa el pedido. - La lógica de flujo de trabajo envía solicitudes a agentes y recibe respuestas de agentes a través de colas de mensajes.
- Las tareas de flujo de trabajo usan agentes para invocar el servicio remoto.
- El Supervisor busca pedidos cuyo valor
CompleteByha caducado y actualiza este valor para permitir que el Scheduler vuelva a intentar el proceso.
Presentación
Cuando un cliente realiza un pedido, el front-end web publica un mensaje de pedido en una cola de Service Bus. Una función de envío recibe el mensaje en modo PeekLock, inserta los detalles del pedido en la base de datos de pedidos y crea un registro de almacén de estado para el proceso de pedido.
Dado que la base de datos Orders y la base de datos creada con Azure Cosmos DB son recursos diferentes y no comparten una transacción, la función considera cada operación de escritura como una operación idempotente independiente. La función usa el identificador de pedido como clave estable, crea cualquiera de los registros cuando falta y acepta un registro existente solo después de comprobar que sus datos de orden inmutable coinciden con el mensaje. Los datos en conflicto hacen que la función envíe el mensaje a la cola de mensajes fallidos y avise a un operador, en lugar de sobrescribir un registro.
El registro contiene los siguientes campos:
| Campo | Description |
|---|---|
OrderID |
El ID del pedido en la base de datos «orders», que se usa como identificador de documento de Azure Cosmos DB y clave de partición. |
LockedBy |
El ID de instancia específico del intento de la orquestación que administra el pedido. Pueden estar ejecutándose varias orquestaciones del programador, pero una transición de estado condicional permite que solo un intento activo reclame un pedido. |
CompleteBy |
Hora a la que se debe procesar el pedido. |
ProcessState |
Estado actual de la tarea de control del pedido. Los estados posibles son: - Pending: el orden se crea, pero no se ha iniciado el procesamiento. - Processing: el pedido se está procesando actualmente. - Processed: el pedido se procesó correctamente. - Error: error en el procesamiento del pedido. |
FailureCount |
Número de intentos de procesamiento fallidos o que agotaron el tiempo de espera registrados para el pedido. |
Cuando la actividad de envío escribe por primera vez el registro, copia OrderID del nuevo pedido, establece LockedBy y CompleteBy en null, establece ProcessState en Pending y establece FailureCount en 0.
Note
En este ejemplo, la lógica de control de pedidos es intencionadamente sencilla y tiene un solo paso que llama a un servicio remoto. En un escenario de varios pasos más complejo, la actividad de envío crearía un registro de almacén de estado por paso, manteniendo OrderID como clave de partición, pero usando un identificador de elemento único como {OrderID}:{StepID}, por lo que Scheduler y Supervisor pueden razonar sobre el estado de cada paso de forma independiente.
Scheduling
El Scheduler es un orquestador de Durable Functions. Una función de inicio sondea Azure Cosmos DB para los registros donde LockedBy es NULL y ProcessState es Pending. La función crea un identificador de instancia de orquestación específico para el intento a partir de OrderID y del número del siguiente intento. Una actualización condicional asigna ProcessState a Processing y LockedBy a ese ID de instancia antes de que el iniciador programe la orquestación. Esta reclamación evita que dos iniciadores programen el mismo intento.
Cada actualización desde la orquestación también comprueba que LockedBy sigue coincidiendo con su identificador de instancia. Esta comprobación impide que un intento expirado cambie el estado de un intento de reemplazo. El paralelismo entre órdenes proviene de ejecutar muchas instancias de orquestación en paralelo, no del paralelismo dentro de un único pedido. La orquestación define CompleteBy y dirige el flujo de trabajo.
El orquestador recupera los detalles del pedido de la base de datos de pedidos y ejecuta el flujo de trabajo como una secuencia de funciones de actividad. Cuando un paso necesita el servicio remoto, invoca un agente.
Execution
El agente puede ser una función de actividad cuando el trabajo es de corta duración y se ejecuta en la misma aplicación de funciones, o puede ser un proceso de trabajo independiente al que se accede mediante un par de colas de solicitud/respuesta de Service Bus cuando se ejecuta en un entorno de ejecución diferente o al otro lado de un límite de confianza. En ambos casos, el orquestador compara un temporizador duradero con la respuesta del agente para detectar el CompleteByplazo límite.
Cuando se accede al agente a través de Service Bus, una función desencadenada por una cola recibe la respuesta y usa el cliente de Durable Functions para desencadenar un evento externo que incluye el identificador de instancia de la orquestación y un identificador de evento estable. El orquestador desduplica eventos externos habilitando la detección de duplicados y estableciendo un valor estable MessageId en cada solicitud, por lo que Service Bus puede descartar duplicados introducidos por reintentos.
Si el Agente recibe una respuesta del servicio remoto antes de que se active el temporizador duradero, el Agente devuelve el resultado al orquestador. El orquestador completa el paso y actualiza ProcessState a Processed solo si LockedBy sigue identificando la instancia de orquestación actual. Si el temporizador se dispara primero, el orquestador considera que el paso ha fallado, deja de esperar y finaliza sin cambiar el registro del estado.
El Agente detiene de forma cooperativa el inicio de nuevos efectos secundarios después de su propia fecha límite, pero el trabajo ya en curso podría continuar. A continuación, el registro de almacén de estado permanece en el Processing estado con un valor expirado CompleteBy , lo que permite al Supervisor organizar la recuperación. Use idempotency o un token de barrera aplicada a destino para evitar que un intento superpuesto se duplica o entra en conflicto con un efecto secundario.
Si el agente detecta un error irrecuperable y no transitorio al ponerse en contacto con el servicio remoto, devuelve una respuesta de error al orquestador. El orquestador establece ProcessState en Error y genera un evento que avisa a un operador, que puede investigar el fallo y volver a enviar el paso de procesamiento fallido.
Supervisión
El supervisor consulta periódicamente el almacén de estado de Azure Cosmos DB en busca de pedidos en Processing estado con un CompleteBy caducado. Dado que OrderID es la clave de partición, esta consulta alcanza todas las particiones físicas incluso cuando ProcessState y CompleteBy se indexan. El proceso delimita cada exploración mediante una ventana de tiempo CompleteBy, un número máximo de resultados y la paginación mediante tokens de continuación, y supervisa su consumo de unidades de solicitud (RU).
Las cargas de trabajo de mayor tamaño mantienen un índice o una cola de recuperación independientes, divididos según el patrón de acceso del Supervisor. Cuando supervisor encuentra un registro expirado, usa una actualización condicional que comprueba el valor expirado LockedBy antes de incrementar FailureCount. Si FailureCount está por debajo de un umbral configurado, el supervisor se restablece LockedBy a null, se actualiza CompleteBy con una nueva hora de expiración y vuelve ProcessState a Pending, lo que permite al iniciador programar un nuevo intento. Si FailureCount supera el umbral, el Supervisor considera el fallo como no transitorio, establece ProcessState en Error y genera un evento que alerta a un operador.
Note
El Supervisor se ejecuta como una función desencadenada por temporizador cuando el análisis es breve y liviano, o como una tarea programada de Azure Container Apps cuando el análisis requiere una imagen de contenedor personalizada, un tiempo de ejecución más prolongado o sidecars. Ambas opciones se ejecutan en una programación de estilo cron y se adaptan al trabajo periódico y de corta duración que realiza el supervisor. El desencadenador de temporizador usa un bloqueo en el almacenamiento entre instancias escaladas horizontalmente en una aplicación de funciones. Las implementaciones independientes o los trabajos de Container Apps que pueden solaparse usan el mecanismo de reclamación de recuperación condicional descrito anteriormente, o pueden coordinarse mediante el patrón de elección de líder.
Informe de estado
Es posible que el orquestador también tenga que mantener informada a la aplicación que envió la orden sobre el progreso y el estado final, aunque esto no se muestra en el diagrama. La aplicación y el orquestador se desacoplan deliberadamente. La aplicación no sabe qué instancia de orquestación controla el orden y la orquestación no sabe qué instancia de aplicación la publicó. Debido a este desacoplamiento, el orquestador no puede devolver actualizaciones de progreso sincrónicamente.
Para devolver el estado del pedido, cada aplicación remitente proporciona su propia cola de respuesta privada de Service Bus con control de acceso. La solicitud enviada a la actividad de envío incluye el identificador de esa cola, que la actividad de envío registra en el registro del almacén de estado del pedido para que el orquestador pueda enviarlo a la cola correcta en lugar de difundirlo. Luego, el orquestador publica mensajes de estado como solicitud recibida, pedido completado o pedido fallido en esa cola, incluyendo el OrderID, para que la aplicación pueda correlacionar cada mensaje con la solicitud original.
Tecnologías auxiliares
Asigne los roles lógicos del patrón a los servicios que se ajusten a los requisitos operativos y de flujo de trabajo:
Programador de tareas: Use Durable Functions para la orquestación definida mediante código o Azure Logic Apps para flujos de trabajo visuales e integración basada en conectores.
Mensajería del agente: Use colas de Service Bus para la mensajería asincrónica de solicitudes y respuestas.
Almacén de estado: Use Azure Cosmos DB para el estado del documento o Azure SQL Database para las transacciones de estado relacional y de registro cruzado.
Supervisor: Utiliza un desencadenador de temporizador de Functions para escaneos ligeros o un trabajo de Container Apps cuando necesites un Integration Runtime de contenedores.
Registro de compensación: Almacene los registros de compensación junto con el estado de la tarea o en Azure Table Storage o Azure Blob Storage.
Pasos siguientes
- Elija entre Azure Functions y Azure Logic Apps para la orquestación del flujo de trabajo.
- Versión de orquestaciones de Durable Functions para proteger los flujos de trabajo en curso durante las implementaciones.
- Evite la pérdida de mensajes y el procesamiento duplicado en Azure Service Bus mediante la combinación de la confirmación de mensajes, la idempotencia y la gestión de mensajes fallidos.
Recursos relacionados
Los patrones siguientes también le serán pertinentes cuando implemente este patrón:
Patrón de reintento. Un agente puede usar este patrón para reintentar de forma transparente una operación que tenga acceso a un servicio remoto o recurso y que haya producido un error anteriormente. Úselo cuando se espera que la causa del error sea transitoria y se pueda corregir mediante un reintento.
Patrón Circuit Breaker. Un agente que se conecta a un servicio remoto o un recurso puede usar este patrón para controlar los errores que tardan una cantidad variable de tiempo en corregirse, por lo que las llamadas repetidas no se acumulan en una dependencia que es poco probable que responda.
Patrón de Transacción Compensatoria. Si un Programador no puede completar correctamente su flujo de trabajo, es posible que sea necesario deshacer el trabajo que ya se ha realizado. El patrón de transacción de compensación describe cómo deshacer ese trabajo en las operaciones que siguen el modelo de consistencia eventual, que es común en los procesos de negocio de larga duración que coordina un Scheduler.
Patrón de Elección de Líder. Cuando varias instancias de Supervisor se ejecutan simultáneamente, deben coordinarse para que no compitan para recuperar el mismo paso con errores. El patrón de elección de líder describe cómo elegir un único coordinador para ese trabajo.