Implementaciones de Actualización Continua con IPF SDK
Introducción
Las implementaciones de actualización en línea son una estrategia crucial para mantener la disponibilidad del sistema durante las actualizaciones. Para evitar el tiempo de inactividad y garantizar la disponibilidad continua, un despliegue de actualización en línea actualiza un sistema de manera incremental — instancia por instancia o, en el caso de clústeres más grandes, varias instancias a la vez. Para asegurar rolling upgrades Para que funcione correctamente, todos los componentes de la nueva versión de su servicio de orquestación deben ser compatibles hacia atrás con la versión anterior.
El SDK de IPF utiliza muchas tecnologías, pero crucialmente la clave Marco de Orquestación IPF está construido sobre Akka, un conjunto de herramientas potente para construir aplicaciones impulsadas por mensajes que son altamente concurrentes, distribuidas y resilientes, que proporciona un soporte robusto para rolling upgrades, particularmente al utilizar event-sourced actors for state persistencia, como lo hace el IPF.
Este documento está dirigido a una audiencia técnica y describe el proceso y las consideraciones para implementar despliegues de actualización continua de los servicios de orquestación construidos utilizando el SDK de IPF.
Lectura Requerida
Antes de avanzar más, asegúrese de tener al menos un conocimiento básico de lo siguiente:
Si bien no es necesario para comprender la estrategia, la familiaridad con lo siguiente puede ayudar a entender las razones detrás de algunas de las recomendaciones:
-
doc.akka.io/docs/akka/actual/teclado/conceptos-de-particionamiento-de-cluster.html[Akka Cluster Sharding
-
doc.akka.io/docs/akka/actual/teclado/cluster-sharding.html#recordando-entidades[Recordando Entidades con Akka Cluster Sharding
Estrategia de Despliegue de Actualización Continua
Un servicio de orquestación construido con el SDK de IPF representa una aplicación con estado que se despliega como un único Akka cluster. Como consecuencia, realizar rolling upgrades en un sistema así requiere una estrategia más compleja que la que sería el caso con un típico HTTP microservicio.
Los siguientes pasos describen el proceso para realizar rolling upgrades de los servicios de orquestación de IPF.
Paso 1: Prepare la Nueva Versión
Durante una actualización continua, un reequilibrio de Akka se producirán fragmentos. Combinado con Akka recordando entidades al ser habilitado, esto causará con frecuencia instancias de flujos iniciados en una versión antigua de un nodo de servicio que sean restarted en un nodo de servicio que ejecuta la nueva versión. Además del reequilibrio de Akka fragmentos, ciertos message transport s (como Kafka, Pulsar, AWS Kinesis, etc.) también necesitarán realizar la reasignación de particiones a medida que se detienen los nodos consumidores antiguos y se inician los nuevos.
Todo el trabajo de reequilibrio que se realiza como parte de una actualización continua puede causar que los flujos sensibles al tiempo se agoten, especialmente si la actualización continua se está llevando a cabo mientras el servicio está procesando volúmenes cercanos a su capacidad. Para evitar un gran impacto en el procesamiento, se aconseja programar sus actualizaciones durante los períodos de bajo volumen típicos de su servicio. |
Mantener la compatibilidad hacia atrás requiere lo siguiente:
-
Asegurando que las versiones de flujo existentes no cambien — una vez liberada, una versión de flujo debe considerarse inmutable.
-
Cambiar un flujo sin versioning introduce imprevisibilidad: un flujo en vuelo iniciado en la versión antigua del servicio puede no ser capaz de avanzar al ser rehidratado en la nueva versión del servicio debido a diversas incompatibilidades y, por lo tanto, podría quedar atrapado en un bucle infinito de recuperación-fallo.
-
Si un flujo necesita ser actualizado — cambios en las transiciones, introducción de nuevos estados, etc. — se debe crear una nueva versión del flujo y los cambios deben realizarse en esa versión. Ver Flujos de Versionado en la sección del tutorial para instructions sobre cómo hacer esto.
-
-
Asegurando que no se eliminen versiones de flujo activas de la nueva versión del servicio.
-
Eliminar una versión de flujo presente en la versión anterior del servicio abre la puerta a la orfandad de flujos en curso. IPF utiliza Akka Cluster roles para decidir qué nodos pueden alojar qué flujos. Si para el momento en que la actualización en línea alcance el nodo final aún hay algunos flujos en curso que están ejecutando la versión eliminada, el clúster se encontrará en un state donde ningún nodo podrá alojar la versión antigua del flujo, causando que el flujo en curso quede huérfano y atrapado para siempre en un estado incompleto state.
-
Si la versión anterior de su servicio tenía la capacidad de iniciar un número de flujos de una cierta versión, esos flujos no deben ser eliminados en la nueva versión.
-
Elimine los flujos solo cuando no haya instancias en curso de los mismos y la versión anterior no tenga forma de iniciarlos.
-
Para determinar si se puede iniciar un determinado flujo, debe inspeccionar sus reglas de enrutamiento de flujo (cubiertas en el siguiente punto).
-
-
Proporcionando reglas de enrutamiento para los nuevos flujos y actualizando las reglas para los antiguos.
-
Selección de Versión de Flujo Basada en el Contexto le permite crear reglas de enrutamiento basadas en la configuración que dependen de los encabezados de los mensajes para realizar el enrutamiento a diferentes versiones de un flujo.
-
Alternativamente, como se indica en Flujos de Versionado, usted tiene control programático directo sobre qué versión de un flujo iniciar, por lo que crear reglas de enrutamiento arbitrarias también es una posibilidad.
-
Por defecto, si no se especifica una versión, se utiliza la más reciente.
-
Dependiendo del nivel de confianza en la corrección de sus nuevas versiones de flujo, puede decidir seguir iniciando las versiones antiguas hasta que se cumplan ciertas condiciones — un customer con una característica flag inicia el flujo, el mensaje de iniciación contiene un encabezado específico, se aplica un predicado de configuración estática, etc. La selección de versiones basada en el contexto mencionada anteriormente también puede ser utilizada para realizar pruebas canarias y permitirle migrar lentamente a una nueva versión de un flujo. Ver Selección de Versión de Flujo Basada en Contexto para Pruebas Canary para más detalles.
-
-
Manteniendo la compatibilidad con los existentes event esquemas.
-
Los esquemas son definidos por el business data elementos listados para el event en el DSL.
-
Rompiendo un event el esquema significará que sus flujos en vuelo no podrán ser recuperados en un rebalanceo, dejándolos huérfanos y sin poder completarse sin una implementación de hotfix.
-
Incluso si un flujo no cambia un event’s business data elementos, un cambio no intencionado a un tipo utilizado en algún lugar del gráfico de objetos podría ocurrir, por ejemplo, al actualizar una versión de una biblioteca común.
-
Para asegurar event los esquemas no están rotos, usted debe crear un conjunto de pruebas que verifique sus esquemas en el tiempo de construcción.
-
Si por alguna razón poco probable no puede evitar romper un event esquema, usted puede usar el IPF domain event schema evolution support como último recurso.
-
-
Asegurando que los consumidores de respuesta de dominio externo sean compatibles hacia atrás.
-
Los consumidores que procesan respuestas de su external domains debe ser capaz de enviar las entradas adecuadas tanto a las versiones antiguas como a las nuevas de sus flujos.
-
No apoyar las versiones antiguas además de las nuevas causará que los flujos de la versión antigua en curso se agoten o queden huérfanos en un estado inconsistente.state.
-
-
Evitando cambios disruptivos en lo expuesto APIs— si su servicio define una API que otros componentes integran con, la API debe seguir siendo compatible hacia atrás.
Paso 2: Actualizar Configuración
Actualice la configuración de implementación para soportar rolling upgrades:
-
Asegúrese Akka la configuración ha cambiado de maneras compatibles.
-
Bastantes Akka Las opciones de configuración — particularmente relacionadas con el agrupamiento, por ejemplo, las estrategias del Resolutor de Cerebros Divididos, el número de fragmentos, etc. — requieren que todos los nodos en el clúster estén configurados con el mismo valor para poder formar un clúster con éxito.
-
Si necesita cambiar un Akka El valor de configuración que requiere consistencia en todo el clúster, deberá apagar todo su clúster.
-
-
Asegúrese de que la configuración de IPF haya cambiado de maneras compatibles.
-
Configuración relacionada con los reintentos de acción y timeouts es sensible a los cambios de versión del flujo, consulte Flujos de Versionado para más detalles.
-
Debe aplicar una consideración cuidadosa al actualizar ciertos journal processor configuraciones ya que pueden romper la compatibilidad de actualización continua:
-
Aumentando el número de event particiones (consulte Particionamiento Events para más detalles) puede causar retrasos en el procesamiento, especialmente si el journal processor se despliega como una aplicación separada. En esos escenarios, usted debe asegurarse de que la journal processor la configuración se actualiza y se despliega antes de que usted comience a desplegar su servicio de orquestación.
-
Usando
EVENT_STREAM_PER_TAGcomo suevent-streaming-typeen combinación con la iniciación de nuevas versiones de flujo antes de que la actualización en curso esté completa causará errores de deserialización y — dependiendo de la configuración de manejo de errores de su journal processor— puede incluso resultar en la pérdida permanente de datos.Si está utilizando pruebas de canario de flujo a través de la selección de versiones, usted puede configurar la selección de versiones de tal manera que asegure que las nuevas versiones de flujo solo se inicien con su aprobación, mitigando así el riesgo de errores y pérdida de datos.
-
-
Paso 3: Despliegue de la Nueva Versión de Manera Incremental
Despliegue la nueva versión en un subconjunto de nodos, asegurándose de que el sistema permanezca operativo:
-
Comience actualizando un pequeño número de nodos (por ejemplo, el 10% del clúster).
-
Aumente gradualmente el porcentaje de nodos actualizados hasta que todo el clúster esté ejecutando la nueva versión.
-
Monitoree el servicio para detectar cualquier problema en el procesamiento.
-
El SDK de IPF viene con un conjunto predefinido de herramientas de monitoreo y soporte para trazado distribuido. Integrarlos en su ecosistema de observabilidad sería beneficioso al solucionar problemas.
-
-
Dependiendo de las reglas de enrutamiento, genere tráfico que inicie las nuevas versiones del flujo para asegurar que están funcionando correctamente.
-
Incluso si su pipeline de CD implica un entorno de pre-producción que refleja de cerca la producción, y ha realizado pruebas exhaustivas de sus nuevas versiones de flujo en pre-producción, puede ser recomendable aumentar lentamente la iniciación de nuevas versiones de flujo justo después del despliegue, especialmente si los flujos están llamando a nuevos endpoints de servicios externos.
-
Puede confiar en el métricas de la aplicación existente para rastrear qué versiones de qué flujos están siendo iniciadas y completadas.
-
Paso 4a: Complete la Actualización
Una vez que todos los nodos hayan sido actualizados y validados:
-
Siga monitoreando el sistema para cualquier problema posterior a la actualización.
-
En este momento, cualquier problema que se encuentre probablemente será resuelto por sus procedimientos habituales de corrección de errores.
-
-
Siéntase libre de eliminar cualquier código y configuraciones obsoletas relacionadas con la versión anterior.
-
Esto incluye versiones de flujo que ya no están activas en su servicio; con todas las instancias en curso de los flujos antiguos completadas en producción y las reglas de enrutamiento que impiden que se inicien nuevamente, ya no serán necesarias en la próxima versión de su servicio.
-
Por otro lado, si no le preocupa el tamaño de sus archivos JAR, no hay ningún inconveniente en mantener los flujos antiguos, especialmente si desea permitirse la capacidad de construir.journal processor s que trabajan contra todos los datos históricos en el diario.
-
-
Documente el proceso de actualización y las lecciones aprendidas para referencia futura.
Paso 4b: Revertir
En el improbable escenario de que se descubra un problema con una de las nuevas versiones del flujo solo cuando usted ha desplegado en producción, puede considerar revertir a la versión anterior.
Aquí hay algunas cosas que debe considerar antes de revertir:
-
Todas las instancias en vuelo de las nuevas versiones del flujo quedarán huérfanas y atascadas una vez que realice la reversión.
-
Incluso con Akka Recuerde que, con las entidades habilitadas, no hay nada que se pueda hacer para permitir la reactivación de esos flujos en la versión antigua del servicio de orquestación, ya que el código necesario para ejecutarlos ya no existe.
-
-
Si las versiones antiguas de sus flujos están funcionando correctamente — es decir, el error está presente solo en las nuevas versiones de los flujos — entonces simplemente revertir sus reglas de enrutamiento para evitar la iniciación de los nuevos flujos podría ser suficiente.
-
Dependiendo de cómo configure sus reglas de enrutamiento, esto puede o no requerir un restart de todos los nodos en el clúster.
-
Revertir las reglas de enrutamiento no dejará huérfanas ninguna de las flujos, pero el problema subyacente puede seguir dejando los flujos atascados y puede ser necesaria alguna intervención manual.
-
A diferencia de realizar un retroceso completo de la versión del servicio, revertir las reglas de enrutamiento le permitiría crear utilidades ad-hoc que programáticamente abortar cualquiera de los flujos que están atascados, o al menos pasivar ellos. Usando el Transaction Operations API también es una opción para crear scripts de recuperación ad-hoc.
-
Tiempo de inactividad requerido
Si bien el despliegue de actualización en línea ofrece varias ventajas, como una interrupción mínima y disponibilidad continua, hay escenarios en los que no puede utilizarse de manera efectiva y es necesario un tiempo de inactividad.
A continuación se presentan algunas circunstancias que pueden impedir el uso de rolling upgrades.
Cambios de base de datos incompatibles
Cuando una nueva versión de una aplicación requiere cambios en la base de datos que no son compatibles hacia atrás,rolling upgrades puede ser problemático o incluso inalcanzable.
Mientras que el SDK de IPF promete mantener los esquemas de la base de datos compatibles hacia atrás, algunos cambios pueden estar fuera del control del SDK de IPF (por ejemplo,Akka cambiando sus representaciones internas) y algunos cambios pueden resultar necesarios para cumplir con objetivos no funcionales (por ejemplo, particionar o estructurar colecciones de manera diferente para hacer que ciertas consultas sean más eficientes).
Actualizaciones de Dependencias
Si la nueva versión del servicio depende de una actualización a una dependencia crítica que no es compatible hacia atrás,rolling upgrades puede no ser factible.
Ejemplos incluyen:
-
Actualización a una nueva versión de una base de datos o cola de mensajes que requiere una actualización simultánea de todos los servicios de cliente.
-
Actualización a una nueva versión del SDK de IPF. En este momento, el SDK de IPF no admite implementaciones heterogéneas; todas las instancias deben utilizar la misma versión del SDK.
-
Introduciendo una nueva versión de un marco o biblioteca con la que la versión anterior de la aplicación no puede integrarse — p. ej. Akka actualización de versión que rompe la compatibilidad binaria con la versión anterior del servicio, impidiendo efectivamente que las instancias de la nueva versión formen un clúster con la anterior.
Vulnerabilidades de Seguridad
Si la nueva versión aborda vulnerabilidades de seguridad críticas que deben ser corregidas de inmediato, una actualización continua puede no ser lo suficientemente rápida para mitigar el riesgo. En tales casos, puede ser necesario un despliegue completo para garantizar que todas las instancias se actualicen simultáneamente, ya que las actualizaciones retrasadas pueden exponer el sistema a amenazas de seguridad.
Conclusión
Las implementaciones de actualización continua con el SDK de IPF proporcionan una estrategia robusta y eficiente para mantener la disponibilidad del sistema durante las actualizaciones. Al aprovechar el Akka Las capacidades del toolkit para gestionar aplicaciones concurrentes, distribuidas y resilientes, el Marco de Orquestación IPF garantiza transiciones fluidas entre versiones de servicio.
Consideraciones clave para el éxito rolling upgrades incluya:
-
Compatibilidad hacia atrás: Asegúrese de que todos los componentes en la nueva versión del servicio sean compatibles hacia atrás para evitar interrupciones en la ejecución del flujo.
-
Actualizaciones de Configuración: Actualizar Akka y configuraciones de IPF cuidadosamente para mantener la compatibilidad en todo el clúster.
-
Despliegue Incremental: Despliegue la nueva versión de manera incremental para monitorear y abordar cualquier problema que surja sin afectar la disponibilidad general del servicio.
-
Monitoreo y Validación: Utilice las herramientas de monitoreo proporcionadas y el rastreo distribuido para validar el nuevo despliegue y solucionar cualquier problema.
-
Manejo de Actualizaciones y Reversiones: Prepárese tanto para la finalización de actualizaciones como para posibles reversiones comprendiendo las implicaciones para los flujos en curso y manteniendo flexibilidad en las reglas de enrutamiento.
Al seguir estas directrices, usted puede gestionar eficazmente rolling upgrades, asegurando una interrupción mínima y manteniendo la disponibilidad continua del servicio. Documentar el proceso y las lecciones aprendidas ayudará a refinar futuras implementaciones, contribuyendo a la resiliencia y robustez de sus servicios de orquestación construidos con el SDK de IPF.