Para bien o para mal, hemos migrado toda nuestra aplicación web LAMP de máquinas dedicadas a la nube (máquinas Amazon EC2). Va muy bien hasta ahora, pero la forma en que hacemos crons es sub-óptimo. Tengo una pregunta específica de Amazon sobre cómo administrar mejor los trabajos cron en la nube usando "la forma de Amazon".
El problema : tenemos varios servidores web y necesitamos ejecutar crons para trabajos por lotes, como crear feeds RSS, activar correos electrónicos, muchas cosas diferentes en realidad. PERO los trabajos cron solo deben ejecutarse en una máquina porque a menudo escriben en la base de datos, por lo que duplicarían los resultados si se ejecutaran en varias máquinas.
Hasta ahora, hemos designado a uno de los servidores web como el "servidor web maestro" y tiene algunas tareas "especiales" que los otros servidores web no tienen. La compensación por la computación en la nube es la confiabilidad: no queremos un "servidor web maestro" porque es un único punto de falla. Queremos que todos sean idénticos y que puedan aumentar y reducir la escala sin recordar no sacar el servidor web principal del clúster.
¿Cómo podemos rediseñar nuestra aplicación para convertir trabajos cron de Linux en elementos de trabajo transitorios que no tienen un solo punto de falla?
Mis ideas hasta ahora:
- Tenga una máquina dedicada solo a ejecutar crons. Esto sería un poco más manejable, pero aún sería un punto de falla único y desperdiciaría algo de dinero teniendo una instancia adicional.
- Es posible que algunos trabajos se trasladen de los crons de Linux a MySQL Events; sin embargo, no soy un gran fanático de esta idea, ya que no quiero poner la lógica de la aplicación en la capa de la base de datos.
- Quizás podamos ejecutar todos los crons en todas las máquinas, pero cambiar nuestros scripts cron para que todos comiencen con un poco de lógica que implemente un mecanismo de bloqueo para que solo un servidor realmente actúe y los demás simplemente salten. No soy un fanático de esta idea, ya que suena potencialmente defectuoso y preferiría usar una de las mejores prácticas de Amazon en lugar de lanzar la nuestra.
- Me estoy imaginando una situación en la que los trabajos se programan en algún lugar, se agregan a una cola y luego los servidores web podrían ser cada uno un trabajador, que puede decir "oye, me quedo con este". Amazon Simple Workflow Service suena exactamente a este tipo de cosas, pero actualmente no sé mucho al respecto, por lo que cualquier detalle sería útil. ¿Parece algo pesado para algo tan simple como un cron? ¿Es el servicio adecuado o hay un servicio de Amazon más adecuado?
Actualización: desde que hice la pregunta, vi el seminario web de Amazon Simple Workflow Service en YouTube y me di cuenta de que a las 34:40 ( http://www.youtube.com/watch?v=lBUQiek8Jqk#t=34m40s ) vislumbré un diapositiva que menciona trabajos cron como una aplicación de muestra. En su página de documentación, " Muestras de AWS Flow Framework para Amazon SWF ", Amazon dice que tiene un código de muestra para crons:
... > Trabajos cron En este ejemplo, un flujo de trabajo de larga duración ejecuta periódicamente una actividad. Se demuestra la capacidad de continuar las ejecuciones como nuevas ejecuciones, de modo que una ejecución puede ejecutarse durante períodos de tiempo muy prolongados. ...
Descargué el AWS SDK para Java ( http://aws.amazon.com/sdkforjava/ ) y, efectivamente, enterrado dentro de unas ridículas capas de carpetas, hay algo de código Java ( aws-java-sdk-1.3.6/samples/AwsFlowFramework/src/com/amazonaws/services/simpleworkflow/flow/examples/periodicworkflow
).
El problema es que, si soy honesto, esto realmente no ayuda, ya que no es algo que pueda digerir fácilmente con mis habilidades. Falta la misma muestra en el SDK de PHP y no parece haber un tutorial que recorra el proceso. Básicamente, sigo buscando consejos o sugerencias.
Respuestas:
Me inscribí en el soporte de Amazon Gold para hacerles esta pregunta, esta fue su respuesta:
fuente
Creo que este video responde a su pregunta exacta: cronjobs al estilo aws (escalable y tolerante a fallas):
Uso de Cron en la nube con Amazon Simple Workflow
El video describe el servicio SWF utilizando el caso de uso específico de implementar cronjobs.
La relativa complejidad de la solución puede ser difícil de asimilar si viene directamente de un crontab. Hay un estudio de caso al final que me ayudó a comprender lo que le compra esa complejidad adicional. Sugeriría ver el estudio de caso y considerar sus requisitos de escalabilidad y tolerancia a fallas para decidir si debe migrar desde su solución crontab existente.
fuente
Tenga cuidado con el uso de SQS para cronjobs, ya que no garantizan que solo "una sola máquina vea un trabajo". Garantizan que "al menos uno" recibirá el mensaje.
De: http://aws.amazon.com/sqs/faqs/#How_many_times_will_I_receive_each_message
Hasta ahora, puedo pensar en la solución en la que tiene una instancia con la instancia de Gearman Job Server instalada: http://gearman.org/ . En la misma máquina, configura trabajos cron que están produciendo comandos para ejecutar su tarea cronjob en segundo plano. Entonces uno de sus servidores web (trabajadores) comenzará a ejecutar esta tarea, garantiza que solo uno la tomará. No importa cuántos trabajadores tenga (especialmente cuando usa el escalado automático).
Los problemas con esta solución son:
fuente
Amazon acaba de lanzar nuevas funciones para Elastic Beanstalk. De los documentos :
Ahora puede crear un entorno que contiene un
cron.yaml
archivo que configura las tareas de programación:Me imagino que el seguro de ejecutarlo solo una vez en un entorno de escala automática se utiliza a través de la cola de mensajes (SQS). Cuando el demonio cron desencadena un evento, coloca esa llamada en la cola SQS y el mensaje en la cola solo se evalúa una vez. Los documentos dicen que la ejecución podría retrasarse si SQS tiene muchos mensajes para procesar.
fuente
Me encontré con esta pregunta por tercera vez y pensé en contribuir. Hemos tenido este dilema por un tiempo. Sigo sintiendo realmente que a AWS le falta una función aquí.
En nuestro caso, después de analizar las posibles soluciones, decidimos que teníamos dos opciones:
cloud-init
scripts para ejecutar cronjobs. Por supuesto, esto viene con un tiempo de inactividad, lo que lleva a cronjobs perdidos (cuando se ejecutan ciertas tareas cada minuto, como lo hacemos nosotros).rcron
usa. Por supuesto, la magia no está realmente enrcron
sí misma, está en la lógica que usa para detectar un nodo que falla (usamoskeepalived
aquí) y "actualizar" otro nodo para dominarlo.Decidimos optar por la segunda opción, simplemente porque es increíblemente rápido y ya teníamos experiencia con servidores web que ejecutan estos cronjobs (en nuestra era anterior a AWS).
Por supuesto, esta solución está diseñada específicamente para reemplazar el enfoque tradicional de cronjob de un nodo, donde el tiempo es el factor decisivo (por ejemplo, "Quiero que el trabajo A se ejecute una vez al día a las 5 a. M." , O como en nuestro caso "Quiero el trabajo B que se ejecute una vez por minuto " ). Si usa cronjobs para activar la lógica de procesamiento por lotes, realmente debería echarle un vistazo
SQS
. No existe un dilema activo-pasivo, lo que significa que puede usar un solo servidor o una fuerza laboral completa para procesar su cola. También sugeriría buscarSWF
escalar su fuerza laboral (aunqueauto scaling
podría ser capaz de hacer el truco también en la mayoría de los casos).Depender de otro tercero era algo que queríamos evitar.
fuente
El 12 de febrero de 2016, Amazon publicó un blog sobre la programación de trabajos SSH con AWS Lambda . Creo que esto responde a la pregunta.
fuente
Si ya tiene un servicio de Redis, esta parece una buena solución:
https://github.com/kvz/cronlock
Leer más: http://kvz.io/blog/2012/12/31/lock-your-cronjobs/
fuente
La forma "Amazon" es distribuirse, lo que significa que los crones voluminosos deben dividirse en muchos trabajos más pequeños y entregarse a las máquinas adecuadas.
Usando la cola SQS con el tipo establecido en FIFO, péguelas para asegurarse de que cada trabajo sea ejecutado por una sola máquina. También tolera fallas, ya que las colas se almacenarán en búfer hasta que una máquina vuelva a girar.
Considere también si realmente necesita "agrupar" estas operaciones. ¿Qué sucede si las actualizaciones de una noche son considerablemente más grandes de lo esperado? Incluso con recursos dinámicos, su procesamiento podría retrasarse esperando a que se pongan en marcha suficientes máquinas. En su lugar, almacene sus datos en SDB, notifique a las máquinas sobre actualizaciones a través de SQS y cree su fuente RSS sobre la marcha (con almacenamiento en caché).
Los trabajos por lotes son de una época en que los recursos de procesamiento eran limitados y los servicios "en vivo" tenían prioridad. En la nube, este no es el caso.
fuente
¿Por qué construirías el tuyo propio? ¿Por qué no usar algo como Quartz (con programación agrupada)? Ver documentación.
http://quartz-scheduler.org/documentation/quartz-2.x/configuration/ConfigJDBCJobStoreClustering
fuente
Lo que hacemos es que tenemos un servidor en particular que es parte de nuestro clúster de aplicaciones web detrás de un ELB y también se le asigna un nombre DNS específico para que podamos ejecutar los trabajos en ese servidor específico. Esto también tiene la ventaja de que si ese trabajo hace que el servidor se ralentice, ELB lo eliminará del clúster y luego lo devolverá una vez que finalice el trabajo y vuelva a estar en buen estado.
Funciona como un campeón.
fuente
Un método para verificar que su expresión cron funciona a la manera de Amazon es ejecutarla a través del comando events. Por ejemplo:
aws events put-rule --name "DailyLambdaFunction" --schedule-expression "<your_schedule_expression>
Si su expresión de programación no es válida, esto fallará.
Más recursos: https://docs.aws.amazon.com/cli/latest/reference/events/put-rule.html
fuente
Si está dispuesto a utilizar un servicio que no sea de AWS, puede consultar Microsoft Azure . Azure ofrece un excelente programador de trabajos .
fuente
Dado que nadie ha mencionado el evento CloudWatch , diría que es la forma en que AWS hace trabajos cron. Puede ejecutar muchas acciones, como la función Lambda, la tarea ECS.
fuente