Actualmente, tengo una aplicación ejecutándose en un servidor. Hay un crontab configurado, de acuerdo con reglas específicas, hay tareas que se ejecutan en ciertos momentos.
Ahora, estoy pensando en migrar mi aplicación a un contenedor docker para poder ejecutar varias instancias de mi aplicación de forma independiente. Lo que me pregunto cómo hacer es cómo programar tareas en varios contenedores acoplables .
Digamos que tengo un comando php que cada hora obtiene nuevos datos de una aplicación de terceros a través de la API. Actualmente, usaría un cron para programarlo así: 0 */1 * * * php /some/path/index.php mycommand . Puede haber múltiples comandos similares lanzados a diferentes frecuencias.
No puedo simplemente empaquetar crontab en la imagen de mi ventana acoplable, ya que el comando se ejecutaría 5 veces cuando hay 5 contenedores en ejecución. Quiero lanzarlo solo una vez de forma independiente en el conteo de contenedores en ejecución.
¿Cuál sería la solución ideal para lograr esto?
Podría usar un mecanismo de bloqueo, usando algo como redis. Básicamente funcionaría así.
el script se despierta, lo primero que hace es intentar obtener el bloqueo. Si obtiene el bloqueo, entonces avanza, si algo más tiene el bloqueo, entonces sale. Haga lo que hace el script y luego suelte el bloqueo.
Dado que solo un script puede obtener el bloqueo a la vez, solo permitirá que el script se ejecute una vez.
Es importante eliminar el bloqueo cuando finalice el script y también agregar un TTL al bloqueo para que, si el script muere antes de liberar el bloqueo, el bloqueo se abra automáticamente después de que caduque el TTL.
Aquí hay algunos documentos sobre cómo usar Redis como un bloqueo distribuido. https://redis.io/topics/distlock
Una estrategia simple en su caso sería usar contenedores con roles separados. Por ejemplo, en lugar de usar 5 contenedores que respondan a las solicitudes HTTP Y ejecuten cron, podría tener 4 contenedores que ejecuten solo su aplicación y uno exclusivamente para trabajos cron.
Si alguna vez necesita escalar sus trabajos cron agregando más nodos, entonces necesitará una solución de bloqueo/cola distribuida como lo describió @Ken Cochrane.