2012-03-02 10 views
7

Lo que voy a describir es esencialmente un problema de confirmación en dos fases entre dos sistemas dispares y estoy buscando consejos sobre cómo manejarlo. En nuestra aplicación web, descargamos algunas operaciones caras/de terceros, como el envío de correos electrónicos, a procesos fuera de banda de trabajadores en segundo plano (lo llamamos nuestra infraestructura de trabajo).Compromiso de dos fases: ¿cómo utilizar mi cola de forma efectiva?

Para enviar un correo electrónico, por ejemplo, Creamos un trabajo de correo electrónico y objeto de correo electrónico en nuestra base de datos. Luego tenemos que esperar a que nuestro supervisor de trabajo recoja el trabajo de correo electrónico y lo envíe. El supervisor de trabajos funciona básicamente al sondear la base de datos cada pocos segundos cuando está inactiva.

Esto, sin embargo, agrega una demora en el envío de correo electrónico y agrega lo que considero una carga indebida en la base de datos con el sondeo. Sería mucho mejor si pudiéramos poner inmediatamente el trabajo de correo electrónico en la cola tan pronto como se cree el correo electrónico.

Sin embargo, esto actualmente falla por dos razones. En primer lugar, la cola suele ser mucho más rápida que la solicitud web. El correo electrónico se recoge para su procesamiento antes de que la solicitud web haya cometido su transacción de base de datos, por lo que no puede generar correctamente el correo electrónico. En segundo lugar, si la solicitud web falla, revierte su transacción de base de datos lo que significa que debe enviarse el correo electrónico no. Sin embargo, si ya se ha puesto en la cola, ya no está en control de la solicitud.

¿Existe una buena estrategia para crear una confirmación en dos fases entre la cola y la base de datos? Como referencia, estamos usando RabbitMQ y MySQL con tablas InnoDB. Una idea que encabecé fue incluir los trabajos de correo electrónico en la cola después de que se haya confirmado la transacción de la base de datos, pero eso deja la posibilidad de que el correo electrónico nunca se ponga en cola. Todavía tendré que crear un proceso de votación que busque correos electrónicos que deberían haberse enviado y que no.

Respuesta

0

Me doy cuenta de que esto es un par de años más tarde :) pero quería agregar algunas reflexiones sobre esto para los demás que se encuentran con esta pregunta.

Puede enviar el mensaje con retraso para aumentar la posibilidad de que la base de datos esté lista cuando los trabajos la reciban. Nunca utilicé RabbitMQ pero encontré este ejemplo de uso de una cola rabbitMQ como cola retrasada How to create a delayed queue in RabbitMQ?. Su trabajo de correo electrónico aún tendría que tratar con los registros sin comentar, ya que el retraso no es un método determinista para tratar el procesamiento distribuido.

Dicho esto, parece que hay espacio para mejorar su diseño. En general, con las arquitecturas de servicios es una mala idea compartir tablas db entre servicios. Conduce a transacciones distribuidas y problemas de escala. Intentaría asegurarme de que el mensaje RabbitMQ contenga todos los datos que necesita para procesar el correo electrónico independientemente de cualquier otro servicio. O si necesita más datos, debe solicitar esos datos a través de una solicitud ServiceBus en lugar de una consulta DB.

Cuestiones relacionadas