Un nuevo punto de referencia para transacciones distribuidas: una guía completa de análisis y aplicación para RocketMQ

Lograr la consistencia y confiabilidad de las transacciones es un desafío importante en los sistemas distribuidos. Este artículo presentará en detalle cómo usar el mecanismo de semi-mensaje de RocketMQ para implementar transacciones distribuidas y brindar ejemplos de códigos específicos y mejores prácticas.

1. Introducción

En los sistemas distribuidos, el procesamiento de transacciones es una tarea compleja y crítica. Las transacciones ACID tradicionales son difíciles de operar en múltiples servicios y bases de datos. RocketMQ es un middleware de mensajes distribuidos, a través de su mecanismo de semi-mensaje podemos lograr la consistencia y confiabilidad de las transacciones distribuidas.

2. Descripción general del medio mensaje de RocketMQ

2.1 Definición de medio mensaje

La razón por la que el uso de mensajes ordinarios y transacciones de pedidos no puede garantizar la consistencia es esencialmente que los mensajes ordinarios no pueden tener la capacidad de comprometerse, revertirse y coordinarse unificadamente como las transacciones de bases de datos independientes. La función de mensaje de transacción distribuida basada en RocketMQ admite capacidades de compromiso de dos fases sobre la base de mensajes ordinarios. Vincule la confirmación de dos fases con la transacción local para lograr la coherencia de los resultados de la confirmación global.

El envío del mensaje de transacción se divide en dos fases. En la primera etapa, se enviará un mensaje semitransaccional. El mensaje semitransaccional se refiere al mensaje que no puede ser entregado temporalmente. El productor ha enviado con éxito el mensaje al Broker, pero el Broker no ha recibido la segunda confirmación de el mensaje del productor. En este momento, el mensaje se marca como "no se puede entregar temporalmente". Si el mensaje se envía correctamente, se ejecutará la transacción local y se enviará el estado del mensaje de media transacción (confirmar o revertir) al corredor de acuerdo con el éxito de la ejecución de la transacción local. Solo el estado de compromiso del mensaje de la mitad de la transacción se enviará realmente a la entrega descendente. Si se pierde la segunda confirmación de un determinado mensaje de transacción debido a una interrupción de la red, el reinicio de la aplicación del productor, etc., el lado del corredor escaneará y encontrará que un determinado mensaje ha estado en el "mensaje semitransaccional" durante mucho tiempo, y necesita preguntar activamente al productor del mensaje sobre el estado final del mensaje (Commit o Rollback). De esta forma, finalmente se garantiza que la transacción local se ejecuta con éxito y el downstream puede recibir el mensaje, si la transacción local falla, el downstream no puede recibir el mensaje. En general, se garantiza la consistencia de los datos aguas arriba y aguas abajo.

2.2 Cómo funcionan los medios mensajes

Los pasos de envío del mensaje de transacción son los siguientes:

  1. Los productores envían mensajes semitransaccionales a RocketMQ Broker.
  2. Después de que RocketMQ Broker persista con éxito el mensaje, devuelve un Ack al productor para confirmar que el mensaje se ha enviado correctamente. En este momento, el mensaje no se puede entregar temporalmente y es un mensaje semitransaccional.
  3. El productor comienza a ejecutar la lógica de transacción local.
  4. El productor envía el segundo resultado de confirmación (Commit o Rollback) al servidor de acuerdo con el resultado de ejecución de la transacción local. Después de que el servidor recibe el resultado de confirmación, la lógica de procesamiento es la siguiente:
  • El resultado de la segunda confirmación es Commit: el servidor marca el mensaje de media transacción como entregable y lo entrega al consumidor.
  • El resultado de la segunda confirmación es Revertir: el servidor revertirá la transacción y no entregará el mensaje de la mitad de la transacción al consumidor.
  1. En el caso especial de desconexión de la red o reinicio de la aplicación del productor, si el servidor no recibe el segundo resultado de confirmación enviado por el remitente, o el segundo resultado de confirmación recibido por el servidor es Desconocido, después de un período de tiempo fijo, el servicio El terminal iniciará una respuesta de mensaje al productor de mensajes, es decir, cualquier instancia de productor en el clúster de productores.
  2. Cabe señalar que el servidor solo intentará la cantidad especificada de veces de acuerdo con los parámetros, y la transacción se verá obligada a retroceder después de que se exceda la cantidad de veces. Por lo tanto, la puntualidad de la revisión de las transacciones pendientes es muy crítica. , y debe configurarse de acuerdo con el riesgo real del negocio:::

Los pasos de revisión del mensaje de transacción son los siguientes: 7. Después de que el productor recibe la revisión del mensaje, debe verificar el resultado final de la ejecución de la transacción local del mensaje correspondiente. 8. El productor vuelve a enviar la segunda confirmación de acuerdo con el estado final de la transacción local obtenida a través de la inspección, y el servidor todavía procesa el mensaje de la mitad de la transacción de acuerdo con el paso 4.

3. Ejemplo de código y mejores prácticas

3.1 Configuración del productor de transacciones de RocketMQ

Primero, configure los parámetros relevantes del productor de transacciones de RocketMQ, incluida la dirección del servidor de nombres, el grupo de productores, el oyente de transacciones, etc.

TransactionMQProducer producer = new TransactionMQProducer("transaction_producer_group");
producer.setNamesrvAddr("localhost:9876");
producer.setTransactionListener(new TransactionListenerImpl());
producer.start();

3.2 Envío de mensajes de transacción

Al enviar un mensaje de transacción, debe usar el método sendMessageInTransaction de TransactionSendResult y especificar una clase que implemente la interfaz TransactionListener.

Message message = new Message("transaction_topic", "transaction_tag", "Transaction Message".getBytes());
TransactionSendResult sendResult = producer.sendMessageInTransaction(message, null);

3.3 Implementación del escucha de transacciones

En la clase que implementa la interfaz TransactionListener, debe escribir la lógica de transacción local y la lógica de devolución de mensajes.

public class TransactionListenerImpl implements TransactionListener {

    @Override
    public LocalTransactionState executeLocalTransaction(Message msg, Object arg) {
        try {
            // 执行本地事务逻辑
            // 在这里编写执行本地事务的代码,包括数据库操作、服务调用等。

            // 本地事务成功,返回 COMMIT_MESSAGE
            return LocalTransactionState.COMMIT_MESSAGE;
        } catch (Exception e) {
            // 本地事务失败,返回 ROLLBACK_MESSAGE
            return LocalTransactionState.ROLLBACK_MESSAGE;
        }
    }

    @Override
    public LocalTransactionState checkLocalTransaction(MessageExt msg) {
        // 消息回查逻辑
        // 在这里编写消息回查的代码,根据本地事务的状态返回 COMMIT_MESSAGE、ROLLBACK_MESSAGE 或 UNKNOW。
    }
}

3.4 Confirmación del mensaje del consumidor

Por parte del consumidor, después de recibir el mensaje, debe confirmar según el estado de la transacción local.

public class MessageListenerImpl implements MessageListenerConcurrently {

    @Override
    public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
        for (MessageExt msg : msgs) {
            // 处理消息
            // 在这里编写处理消息的代码,包括业务逻辑的执行等。

            // 根据本地事务状态确认消息
            if (transactionState == LocalTransactionState.COMMIT_MESSAGE) {
                return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
            } else if (transactionState == LocalTransactionState.ROLLBACK_MESSAGE) {
                return ConsumeConcurrentlyStatus.RECONSUME_LATER;
            }
        }
        return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
    }
}

4. Precauciones

Cuando utilice el medio mensaje de RocketMQ para implementar transacciones distribuidas, debe prestar atención a los siguientes puntos:

  • Establezca un intervalo y tiempos de respuesta apropiados: de acuerdo con los requisitos comerciales y el rendimiento del sistema, establezca un intervalo y tiempos de respuesta de mensajes razonables para garantizar la eventual consistencia de las transacciones.
  • Manejo de la duplicación de mensajes: debido a la existencia del mecanismo de revisión de mensajes, puede ocurrir la duplicación de mensajes. Del lado del consumidor, es necesario considerar cómo manejar los mensajes duplicados para evitar impactar el negocio.
  • Garantizar la idempotencia del mensaje: durante el procesamiento de mensajes, se debe garantizar la idempotencia del mensaje para evitar el procesamiento repetido de mensajes exitosos.
  • Monitoreo y alarmas: Establecer un mecanismo adecuado de monitoreo y alarmas para detectar y tratar situaciones anormales a tiempo para garantizar la estabilidad y confiabilidad del sistema.

5. Resumen

Este artículo presenta en detalle cómo usar el mecanismo de semi-mensaje de RocketMQ para implementar transacciones distribuidas. El procesamiento confiable y la consistencia de los mensajes se pueden garantizar mediante el envío de mensajes a medias, la ejecución de la lógica de transacción local, la verificación de mensajes y el reconocimiento de mensajes. Al mismo tiempo, se proporcionan ejemplos de códigos específicos y mejores prácticas para ayudar a los lectores a comprender y aplicar mejor el mecanismo de medio mensaje de RocketMQ.

El uso del semimensaje de RocketMQ para implementar transacciones distribuidas puede resolver de manera efectiva los desafíos de las transacciones tradicionales en sistemas distribuidos y mejorar la confiabilidad y consistencia del sistema. En las aplicaciones prácticas, es necesario realizar los ajustes y optimizaciones correspondientes según escenarios específicos para cumplir con los requisitos del sistema.

=================================

Si el artículo es útil para usted, ¡no olvide agregar atención y darle me gusta!

Supongo que te gusta

Origin blog.csdn.net/citywu123/article/details/131411850
Recomendado
Clasificación