2012-01-15 7 views
12

¿Puede alguien guiarme en cómo Gearman reintenta cuando se lanzan excepciones o cuando se producen errores?¿Condiciones de error y reintentos en Gearman?

Uso el cliente de engranaje de python en una aplicación de Django y mis trabajadores son iniciados como un comando de Django. Leí de blog post que reintenta de las condiciones de error no son directas y que requiere sys.exit desde el lado del trabajador.

¿Ha sido arreglado para volver a intentar quizás con sendFail o sendException? También hace reintentos de soporte gearman con el algoritmo de exponentials - digamos si falla una falla de SMTP después de 2,4,8,16 segundos, etc.?

+0

sys.exit() es una mala idea con Gearman: por lo general, volverá a intentarlo para siempre (a menos que tenga reintentos de trabajo configurados en el inicio del daemon). Simplemente haga un 'return stringvar' con cualquier estado/resultado del trabajo (por ejemplo, clave en una fila DB o caché con la información real). – RichVel

Respuesta

25

A mi entender, Gearman emplea un enfoque muy "no es mi negocio", por ejemplo, no interviene con los trabajos realizados, a menos que los trabajadores se cuelguen. Se supone que los mensajes de éxito/falla deben ser manejados por el cliente, no por el propio servidor de Gearman.

En puestos de trabajo de primer plano, esto implica que todos los sendFail()/sendException() y otra send*() están dirigidos al cliente y le toca al cliente a decidir si para volver a intentar el trabajo o no. Esto tiene sentido ya que a veces puede que no sea necesario volver a intentarlo.

En trabajos en segundo plano, todas las funciones de send*() pierden su significado, ya que no hay ningún cliente que escuche las devoluciones de llamada. Como resultado, los mensajes enviados serán ignorados por Gearman. La única condición en la que se reintentará el trabajo es cuando el trabajador se cuelga (lo cual puede ser emulado con un comando exit(XX), donde XX es un valor distinto de cero). Esto, por supuesto, no es algo que desee hacer, porque se supone que los trabajadores suelen ser procesos de larga ejecución, no los que deben reiniciarse después de cada trabajo fallido.

Personalmente, he resuelto este problema extendiendo la clase predeterminada de GearmanJob, donde intercepto las llamadas a las funciones send*() y luego implementé el mecanismo de reintento. Básicamente, paso todos los datos relacionados con el reintento (número máximo de intentos, tiempos ya reintentos) junto con una carga de trabajo y luego manejo todo por mi cuenta. Es un poco engorroso, pero entiendo por qué Gearman funciona de esta manera: solo le permite manejar toda la lógica de la aplicación.

Finalmente, con respecto a la capacidad de reintentar trabajos con tiempo de espera exponencial (o cualquier tiempo de espera para ese asunto). Gearman tiene una función para agregar trabajos retrasados ​​(busque SUBMIT_JOB_EPOCH en el protocol documentation), pero no estoy seguro de su estado: la extensión PHP y, creo, el módulo Python no lo admiten y los documentos dicen que se puede eliminar en el futuro. Pero entiendo que funciona en este momento, solo tiene que enviar solicitudes de socket raw a Gearman para que suceda (y la parte exponencial también debería implementarse de su lado).

Sin embargo, this blog post argumenta que la implementación de SUBMIT_JOB_EPOCH no se escala correctamente. Utiliza node.js y setTimeout() para hacerlo funcionar, he visto a otros utilizar la utilidad de Unix at para hacer lo mismo. En cualquier caso, Gearman no lo hará por ti. Se enfocará en la confiabilidad, pero le permitirá enfocarse en toda la lógica.

+5

Sé que es una respuesta a una pregunta anterior, pero he visto a mucha gente luchando con el mismo problema y creo que vale la pena proporcionar la imagen completa de una vez por todas. – Aurimas

Cuestiones relacionadas