Todos sabemos que con el auge del desarrollo y las arquitecturas nativas de la nube, hemos visto plataformas basadas en Kubernetes como el nuevo estándar, todas enfocándose en nuevos desarrollos siguiendo los nuevos paradigmas y mejores prácticas: Microservicios, Arquitecturas impulsadas por eventos, nuevos protocolos brillantes como GraphQL o gRPC, y así sucesivamente.
Pero debemos ser conscientes de que la mayoría de las empresas que hoy están adoptando estas tecnologías no son oportunidades de campo verde. Tienen muchos sistemas ya en funcionamiento con los que todos los nuevos desarrollos en las nuevas arquitecturas nativas de la nube necesitan interactuar, por lo que las reglas se vuelven más complejas y hay muchas tonalidades de gris cuando estamos creando nuestra aplicación en Kubernetes.
Y basado en mi experiencia, cuando estamos hablando con el cliente sobre la nueva arquitectura en la nube, la mayoría de ellos traen aquí el patrón por lotes. Saben que esto ya no es una mejor práctica, que no pueden seguir construyendo sus sistemas de manera por lotes tratando de hacer por la noche lo que deberíamos estar haciendo en tiempo real. Pero, la mayoría de las veces necesitan coexistir con los sistemas que ya tienen y podría ser necesario este tipo de procedimiento. Así que necesitamos encontrar una manera de proporcionar Procesamiento por Lotes en Kubernetes.
También para los clientes que ya tienen sus aplicaciones existentes usando ese patrón y quieren moverse al nuevo mundo, es mejor para ellos que puedan hacerlo sin necesidad de re-arquitectar su aplicación existente. Algo que probablemente terminarán haciendo pero a su propio ritmo.
Los patrones de procesamiento por lotes en el desarrollo de TIBCO son un patrón bastante utilizado y tenemos clientes en todo el mundo con este tipo de desarrollo usado en producción durante muchos años. Ya sabes, este tipo de proceso que se ejecuta en un momento específico (semanalmente los lunes, cada día a las 3 PM… o simplemente cada hora para hacer algún trabajo regular).
Es un patrón sencillo aquí. Simplemente agrega un temporizador que puedes configurar cuándo se lanzará y agrega tu lógica. Eso es todo. Tan simple como eso:
Pero, ¿cómo se puede traducir esto a un enfoque de Kubernetes? ¿Cómo podemos crear aplicaciones que funcionen con este patrón y aún así ser gestionadas por nuestra plataforma? Afortunadamente, esto es algo que se puede hacer, y también tienes diferentes maneras de hacerlo dependiendo de lo que quieras lograr.
Principalmente hoy vamos a describir dos maneras de poder hacer eso y tratar de explicar las principales diferencias entre una y otra para que puedas saber cuál deberías usar dependiendo de tu caso de uso. A esos dos métodos los voy a llamar de esta manera: Lote gestionado por TIBCO Kubernetes y enfoque de API de Cron Job
Lote Gestionado por TIBCO
Este es el más simple. Es exactamente el mismo enfoque que tienes en tu aplicación BusinessWorks existente en las instalaciones, solo que desplegado en el clúster de Kubernetes.
Así que, no necesitas cambiar nada en tu lógica, solo tendrás una aplicación que es iniciada por un Temporizador con su configuración respecto a la programación dentro del alcance de la aplicación BusinessWorks y eso es todo.
Solo necesitas proporcionar los artefactos necesarios para desplegar tu aplicación en Kubernetes como cualquier otra aplicación de TIBCO BusinessWorks y eso es todo. Eso significa que estás creando un Despliegue para lanzar este componente y siempre tendrás un pod en ejecución evaluando cuándo la condición es verdadera para lanzar el proceso como lo tienes en tu enfoque en las instalaciones.
API de Cron-Job de Kubernetes
El patrón de procesamiento por lotes es algo que ya está cubierto de manera predeterminada por la API de Kubernetes y por eso tenemos el concepto de Cron-Job. Probablemente recuerdes los Cron Jobs que tenemos en nuestras máquinas Linux. Si eres un desarrollador o un administrador de sistemas, estoy seguro de que has jugado con estos cronjobs para programar tareas o comandos para que se ejecuten en un momento determinado. Si eres una persona basada en Windows, este es el equivalente en Linux de tus Trabajos del Programador de Tareas de Windows. Mismo enfoque.
Y esto es muy simple, solo necesitas crear un nuevo artefacto usando esta API de Cron Job que principalmente dice el trabajo a ejecutar y la programación de ese trabajo similar a lo que hemos hecho en el pasado con el cronjob en nuestra máquina Linux:
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: hello
spec:
schedule: "*/1 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: hello
image: busybox
args:
- /bin/sh
- -c
- date; echo Hola desde el clúster de Kubernetes
restartPolicy: OnFailure Los trabajos que podemos usar aquí deben cumplir con una regla única que también se aplica en los trabajos cron de Unix: El comando debe terminar cuando el trabajo esté hecho.
Y esto es algo que es crítico, lo que significa que nuestro contenedor debe salir cuando el trabajo esté hecho para poder ser usado dentro de este enfoque. Eso significa que no podemos usar un “enfoque de servidor” como estamos haciendo en el enfoque anterior porque en ese caso, el pod nunca termina. ¿Significa eso que no puedo usar una aplicación de TIBCO BusinessWorks como parte de un Cron Job de Kubernetes? ¡Absolutamente no! Veamos cómo puedes hacerlo.
Así que, deberíamos centrarnos en dos cosas, la lógica de negocio debería poder ejecutarse tan pronto como el proceso comience y el contenedor debería terminar tan pronto como el trabajo esté hecho. Comencemos con la primera.
La primera es fácil. Usemos nuestro ejemplo anterior: Enfoque por lotes simple que escribe una traza de registro cada minuto. Necesitamos hacer que comience tan pronto como el proceso haya comenzado, pero esto es bastante de serie (OOTB) con TIBCO BusinessWorks, solo necesitamos configurar ese temporizador para que se ejecute solo una vez y eso comenzará tan pronto como la aplicación esté en ejecución:
Así que, ya tenemos el primer requisito solucionado, veamos con el otro.
Deberíamos poder terminar el contenedor completamente cuando el proceso termine y eso es un desafío porque la aplicación BusinessWorks no se comporta de esa manera. Se supone que deben estar siempre en ejecución. Pero esto también se puede resolver.
Lo único que necesitamos es hacer uso de un comando al final del flujo. Es como un comando de salida en nuestro script de shell o código Java para terminar el proceso y el contenedor. Para hacer eso, deberíamos agregar una Actividad de “Ejecutar Comando Externo” y simplemente configurarla para enviar una señal al proceso BusinessWorks que se ejecuta dentro del contenedor.
La señal que vamos a enviar es SIGINT, que es similar a la que enviamos cuando presionamos CTRL+C en un Terminal para requerir que el proceso se detenga. Vamos a hacer lo mismo. Para hacer eso, vamos a usar el comando kill que se incluye en todas las máquinas Unix y en la mayoría de las imágenes base de docker también. Y el comando kill requiere dos argumentos:
kill -s <SIGNAL_NAME> <PID>
- SIGNAL_NAME: Ya cubrimos esa parte y vamos a usar la señal llamada SIGINT.
- PID: En cuanto al PID, necesitamos proporcionar el PID del proceso BusinessWorks que se ejecuta dentro del contenedor.
La parte de encontrar el PID para ese proceso que ejecuta BusinessWorks dentro del contenedor puede ser difícil de localizar, pero si ves los procesos en ejecución dentro de un contenedor de BusinessWorks, puedes ver que no es tan complicado de encontrar:
Si entramos dentro de un contenedor en ejecución de una aplicación BusinessWorks, verificaremos que este PID siempre es el número 1. Así que ya tenemos todo listo para configurar la actividad como se muestra a continuación:
Y eso es todo, con estos dos cambios podemos desplegar esto usando la API de CronJob y usarlo como parte de tu conjunto de herramientas de patrones de aplicación.
Pros y Contras de cada enfoque
Como puedes imaginar, no hay una solución única sobre cuándo usar uno u otro porque va a depender de tu caso de uso y tus requisitos. Así que intentaré enumerar aquí las principales diferencias entre ambos enfoques para que puedas elegir mejor cuando esté en tus manos:
- El enfoque gestionado por TIBCO es más rápido porque el pod ya está en ejecución y tan pronto como se cumple la condición, la lógica comienza. Usar la API de Cron Job requiere un período de calentamiento porque el pod comienza cuando se cumple la condición, por lo que se puede aplicar algún retraso aquí.
- El enfoque gestionado por TIBCO requiere que el pod esté en ejecución todo el tiempo, por lo que utiliza más recursos cuando la condición no se alcanza. Así que en caso de que estés ejecutando contenedores sin estado como AWS Fargate o similar, la API de Cron JOB es una mejor opción.
- La API de CronJob es una API estándar de Kubernetes, lo que significa que se integra completamente con el ecosistema, mientras que el enfoque gestionado por TIBCO es gestionado por TIBCO usando configuraciones de aplicación.
- El enfoque gestionado por TIBCO no es consciente de otras instancias de la misma aplicación en ejecución, por lo que gestionas mantener una sola instancia en ejecución para evitar ejecutar la misma lógica muchas veces. En el caso de la API de Cron Job, esto es gestionado por la propia plataforma de Kubernetes.