Cómo guardar el mensaje en la base de datos y enviar la respuesta al tema eventualmente consistentes?

gstackoverflow:

Tengo el siguiente consumidor RabbitMQ:

Consumer consumer = new DefaultConsumer(channel) {
    @Override
     public void handleDelivery(String consumerTag, Envelope envelope, MQP.BasicProperties properties, byte[] body) throws IOException {
            String message = new String(body, "UTF-8");
            sendNotificationIntoTopic(message);
            saveIntoDatabase(message);
     }
};

Siguiente situación puede ocurrir:

  1. Mensaje se envía al tema con éxito
  2. La conexión a la base de datos se perdió por lo inserto de base de datos ha fallado.

Como resultado tenemos inconsistencia de datos.

Resultado esperado ya sea tanto la acción se ejecutó con éxito o ambos no fueron ejecutados en absoluto.

Cualquier solución ¿cómo puedo lograrlo?

PD

Actualmente he siguiente idea (comentario, a)

Podemos suponer que corredor no perder ningún mensaje.

Tenemos que estar suscrito el tema que queremos enviar.

  1. Guardar entrada en la base de datos y el campo de juego statuscon el valor de 'pendiente'
  2. Intentará enviar los datos al tema. Si envío fue exitosa - actualización de campo statuscon el valor de 'éxito'
  3. Tenemos que tener un trabajo sheduled que tienen para comprobar filas con estado pendiente. En el momento en 2 casos:
    3.1 La notificación no se envía en absoluto
    3.2 Notificación fue enviado pero guarda en la base de datos ha fallado (la probabilidad es muy baja, pero es posible)

    Así que tenemos que distinquish que los 2 casos de alguna manera: podemos almacenar mensajes de tema en la recopilación y el trabajo podemos comprobar si el mensaje ha sido aceptado o no. Así que si se colocó un mensaje que corresponde la fila de base de datos tenemos que actualizar el estado de "éxito". De lo contrario, hay que quitar la entrada de la base de datos.

Creo que mi idea tiene algunos puntos débiles (por ejemplo, si tenemos la aplicación de varios nodos tenemos que guardan los mensajes en Hazelcast (o análogos) pero es punto adicional de falla hipotética)

Alexandar Petrov:

Aquí está un ejemplo de Try Cancelar Confirmar patrón https://servicecomb.apache.org/docs/distributed_saga_3/ que debería ser capaz de hacer frente a su problema. Usted debe tolerar alguna posibilidad de la doble presentación de los datos a través de la cola. Aquí hay un ejemplo:

  1. Definir la abstracción Operación y asignar ID de la operación, más una marca de tiempo.
  2. A la espera de estado de escritura a la base de datos (se puede hacer esto en el mismo paso que 1)
  3. Escribir un oyente que las encuestas de la base de datos de todas las operaciones con estado pendiente y mayores de "tiempo de espera"
  4. Para cada operación pendiente enviar los datos a través de la cola con el ID asignado.
  5. El lado receptor debe ser consciente de la ID y si el ID ha sido procesado nada debe suceder.

6A . Si tiene que ser del 100% de que la operación se ha completado necesita una segunda cola en el lado receptor publicará un ID de mensaje - HECHO. Si tal consistencia no es necesario omitir este paso. Alternativamente, se puede publicar ID -Failed razón para el fracaso.

6B . El lado tampoco espera la presentación de un mensaje de 6A de completa la operación escribiendo estado DONE a la base de datos.

  • Una vez que un tiempo de espera sertine ha pasado o determinado límite de reintentos ha pasado. Se escribe el estado de funcionamiento a prueba.
  • Puede enviar un mensaje a potentialy programar la cirugía lado del receptor con la reversión de identificación.

Tenga en cuenta que todos estos pasos no implican una técnica transacciones. Usted puede hacer esto con una base de datos no transaccionales.

Lo que he escrito es una variación de la función Try Cancelar Confirmar patrón en el que cada destinatario del mensaje debe ser consciente de cómo gestionar sus propios datos.

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=226604&siteId=1
Recomendado
Clasificación