7. Springboot 2.x integra RabbitMQ para realizar la confirmación de envío de mensajes y la confirmación de recepción de mensajes para realizar la entrega de mensajes al 100%

Springboot2.x integra RabbitMQ para realizar la confirmación de envío de mensajes y la confirmación de recepción de mensajes para realizar la entrega de mensajes al 100%

Prefacio

  • ¿Cómo garantiza el mensaje el 100% de éxito en la entrega?
  • Explicación detallada del concepto de idempotencia
  • ¿Cómo evitar el problema del consumo repetido de mensajes durante el período comercial pico cuando se generan pedidos masivos?
  • Confirmar mensaje de confirmación, Devolver mensaje de devolución

¿Cómo garantiza el mensaje el 100% de éxito en la entrega?

1.1 ¿Qué es la entrega confiable en el lado de la producción?

  • Garantizar el éxito del mensaje
  • Asegurar la recepción exitosa de los nodos MQ
  • El remitente recibe la respuesta de confirmación del nodo MQ (Broker)
  • Mecanismo completo de compensación de mensajes

Los primeros tres pasos pueden no garantizar el 100% de la entrega del mensaje. Entonces agrega el cuarto paso

Solución del gigante de Internet BAT / TMD:

  • Base de datos de caída de mensajes, marcando el estado del mensaje
    Al enviar un mensaje, necesita mantener el mensaje en la base de datos y establecer un estado (no enviado, enviando, llegando) para el mensaje. Cuando cambia el estado del mensaje, es necesario realizar un cambio en el mensaje. Realice una operación por turnos para los mensajes que no han llegado y vuelva a enviarlos. También hay un límite de 3-5 veces para el número de rotaciones. Asegúrese de que el mensaje se pueda enviar correctamente.

  • Entrega retrasada de mensajes, segunda confirmación, verificación de devolución de llamada

El esquema a adoptar depende de la cantidad de servicios y mensajes simultáneos.

1.2 El primer esquema:

Entrega confiable del lado de la producción

Por ejemplo: envíe un mensaje de pedido de la siguiente manera.

Paso 1: Almacene el mensaje de pedido (cree un pedido), los datos comerciales se almacenan en la base de datos y el mensaje también se almacena en la base de datos. Desventajas: Necesita persistir dos veces. (Estado: 0)
Paso 2: En la premisa de que el Paso 1 es exitoso, envíe un mensaje Paso
3: Después de que el Agente reciba el mensaje, confirme el final de nuestra producción. Confirm Listener monitorea asincrónicamente los mensajes enviados por el Broker.
paso 4: tome el mensaje especificado y actualice (estado = 1), lo que indica que el mensaje se ha entregado correctamente.

Paso 5: La tarea de sincronización distribuida obtiene el estado del mensaje, si es igual a 0, luego toma los datos.
paso 6: reenvíe el mensaje
paso 7: establezca el límite de reintentos 3 veces. Si el mensaje falla después de 3 reintentos, entonces (estado = 2), el mensaje se considera un error.

Preguntar por qué fallaron estos mensajes puede requerir una consulta manual.

Suponga que el paso 2 se ejecuta con éxito y el paso 3 se debe a la memoria flash de la red. Luego confirme que nunca recibirá el mensaje, luego debemos establecer una regla:
Por ejemplo: cuando el mensaje se almacena en la base de datos, establezca un valor crítico de tiempo de espera = 5min, cuando exceda los 5min, los datos serán capturados.
O escriba una tarea cronometrada para obtener el estado = 0 mensajes cada 5 minutos. Puede haber un pequeño problema: el mensaje se envía, la tarea cronometrada acaba de ejecutarse y no se ha recibido la confirmación, la tarea cronometrada se ejecutará, lo que provocará que el mensaje se ejecute dos veces.
Operación más refinada: límite de tolerancia de tiempo de espera de mensajes. Si confirm no recibe el mensaje dentro de 2-3 minutos, será reenviado.

Nota: Frente a las aplicaciones a pequeña escala, se pueden agregar transacciones para garantizar la coherencia de las transacciones. Sin embargo, ante la alta concurrencia en las grandes fábricas, no se agregan transacciones. El empalme de transacciones de desempeño es muy serio, pero se hace una compensación.

Para asegurar MQ, pensamos si el primer tipo de entrega confiable es apropiado en el contexto de alta concurrencia.

El primer esquema tiene dos almacenamiento de datos, uno de datos comerciales y otro de mensajes. Este es un cuello de botella para el almacenamiento de datos.
De hecho, solo necesitamos almacenar el negocio.

Entrega retrasada de mensajes, segunda confirmación, verificación de devolución de llamada

Este método no garantiza necesariamente el 100% de éxito, pero también puede garantizar el 99,99% de los mensajes. Si se encuentra en una situación particularmente extrema, solo puede necesitar compensar manualmente o realizar tareas cronometradas para hacerlo.
El segundo método consiste principalmente en reducir el funcionamiento de la base de datos.

1.2 El segundo esquema:

Paso 1: después de que el mensaje comercial se haya almacenado correctamente en la base de datos, se envía el primer mensaje.
paso 2: De manera similar, después de que el mensaje se haya almacenado correctamente en la base de datos, se envía el segundo mensaje y los dos mensajes se envían al mismo tiempo. El segundo mensaje es la verificación retrasada, que se puede configurar en 2 minutos o 5 minutos para retrasar el envío.
paso 3: el consumidor supervisa la cola especificada.
Paso 4: Una vez que el consumidor ha procesado el mensaje, se genera internamente una nueva confirmación de envío de mensaje. Entrega a MQ Broker.
Paso 5: Servicio de devolución de llamada El servicio de devolución de llamada supervisa el MQ Broker. Si se recibe el mensaje enviado por el servicio Downstream, se puede determinar que el mensaje se envió correctamente y el mensaje de ejecución se almacena en la base de datos MSG.
Paso 6: Verifique Detalles para verificar y monitorear el mensaje de entrega retrasada del paso 2. En este momento, las dos colas de monitoreo no son iguales Después de 5 minutos, el servicio de devolución de llamada recibe el mensaje y verifica la base de datos MSG. Si descubre que el mensaje anterior se ha enviado correctamente, no necesita hacer otras cosas. Si la verificación falla, la devolución de llamada compensa y envía activamente la comunicación RPC. Notifique al productor ascendente que vuelva a enviar el mensaje.

El propósito de hacerlo: Un almacenamiento de base de datos menos. El enfoque no está en el 100% de éxito en la entrega, sino en el rendimiento.

2. El concepto de idempotencia

2.1 ¿Qué es la idempotencia?

Idempotente (idempotente, idempotencia) es un concepto matemático y de ciencias de la computación que se encuentra comúnmente en el álgebra abstracta, a saber, f (f (x)) = f (x). En pocas palabras, el resultado de una operación ejecutada varias veces es consistente con el resultado de una ejecución .

  • Podemos aprender del mecanismo de bloqueo optimista de la base de datos:
  • Por ejemplo, ejecutamos una declaración SQL para actualizar el inventario:
  • ACTUALIZAR T_REPS SET COUNT = COUNT - 1, VERSION = VERSION + 1 DONDE VERSION = 1

Utilice el método de agregar el número de versión para garantizar la idempotencia.

2.2 Garantía de idempotencia final del consumidor

¿Cómo evitar el problema del consumo repetido de mensajes durante el período comercial pico cuando se generan pedidos masivos?

En el caso de una alta simultaneidad, llegará una gran cantidad de mensajes a MQ y el consumidor necesita supervisar una gran cantidad de mensajes. En este caso, inevitablemente se producirán entregas repetidas de mensajes, flashes de red, etc. Si no hace idempotencia, habrá consumo repetido de mensajes.
-La realización de la idempotencia por parte del consumidor significa que nuestros mensajes nunca se consumirán varias veces, incluso si recibimos varios mensajes idénticos, solo se ejecutarán una vez.

Observe las principales operaciones idempotentes de las principales empresas de Internet:
-Mecanismo de identificación única + huella digital, utilizando claves primarias de la base de datos para eliminar duplicados.
-Utilizar la atomicidad de Redis para lograr
-Otras tecnologías para lograr la idempotencia

2.2.1 Mecanismo de identificación única + código de huella digital

  • Mecanismo de identificación única + huella digital, utilizando la clave principal de la base de datos para eliminar duplicados.
    Garantizar la singularidad
  • SELECCIONE COUNT (1) FROM T_ORDER WHERE ID = ID único + código de huella digital
    Si la consulta no existe, agréguela. No es necesario hacer nada y el consumidor no necesita consumir mensajes.
  • Beneficio: simple de implementar
  • Desventajas: cuello de botella en el rendimiento para escrituras de base de datos con alta concurrencia
  • Solución: realice un seguimiento de la ID en la subbase de datos y la subtabla para realizar un enrutamiento algorítmico para
    asignar la presión del tráfico.

2.2.2 Implementación de la característica atómica de Redis

El autoincremento de Redis más fácil de usar.

  • Problemas que deben tenerse en cuenta al usar Redis para la idempotencia.
  • Primero: ¿Necesitamos que los datos se almacenen en la base de datos? Si es así, el problema clave a resolver es cómo lograr la atomicidad en la base de datos y la caché.
    Agregar transacciones no funciona. Redis y las transacciones de la base de datos no son lo mismo, y no hay garantía de éxito y fracaso simultáneos. ¿Tienes un plan mejor?
  • Segundo: ¿Cómo configurar la estrategia de sincronización de tiempo si no se realiza el almacenamiento, entonces todos se almacenan en la caché?
    ¿Cómo lograr la estabilidad de los datos almacenados en caché?

3. Confirmar mensaje de confirmación

Comprenda el mecanismo de confirmación de mensaje Confirmar:

  • La confirmación del mensaje significa que después de que el productor entrega el mensaje, si el corredor recibe el mensaje, nos dará una respuesta al productor.
  • El productor recibe la respuesta para determinar si el mensaje se envía al Broker normalmente ¡Este método es también la garantía principal para la entrega confiable del mensaje!

3.1 Implementar mensaje de confirmación de confirmación

spring:
  application:
    name: zoo-plus-rabbitmq
  rabbitmq:
    virtual-host: /
    host: localhost
    port: 5672
    username: guest
    password: guest
    publisher-confirm-type: correlated #必须配置这个才会确认回调

Productor:

    /**
     * 测试消息确认回调(必须在yml配置publisher-confirm-type: correlated)
     */
    @GetMapping("sendConfirmCallback")
    public Resp sendConfirmCallback() {
    
    
        rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -> {
    
    
            System.out.println("ack:" + ack);
            if (!ack) {
    
    
                //可以进行日志记录、异常处理、补偿处理等
                System.out.println("异常处理");
            }else{
    
    
                //更新数据库,可靠性投递机制
            }
        });
        amqpTemplate.convertAndSend("test-queue", "测试ack确认模式");
        return Resp.success("ok", null);
    }

4. Mecanismo de mensaje de respuesta

  • Return Listener se utiliza para procesar algunos mensajes que no se pueden enrutar.
  • Nuestro productor de mensajes, al especificar una clave de enrutamiento y de intercambio, envía el mensaje a una determinada cola, y luego nuestro consumidor escucha la cola para las operaciones de procesamiento de consumo.
  • Pero en algunos casos, si el intercambio actual no existe o la clave de enrutamiento especificada no se puede enrutar cuando enviamos un mensaje, en este momento, si necesitamos escuchar esos mensajes inalcanzables, ¡debemos usar Return Listener!

Hay un elemento de configuración clave en la API básica:

  • Obligatorio: Si es verdadero, el oyente recibirá el mensaje de que la ruta no es accesible y luego realizará el procesamiento posterior. Si es falso, el agente borrará automáticamente el mensaje.

4.1 Implementar mensaje de confirmación de confirmación

Configuración

spring:
  application:
    name: zoo-plus-rabbitmq
  rabbitmq:
    virtual-host: /
    host: localhost
    port: 5672
    username: guest
    password: guest
    publisher-returns: true #支持发布返回

Código

    /**
     * 启动消息失败返回,比如路由不到队列时触发回调
     * 测试发布回调(必须在yml配置publisher-returns: true)
     */
    @GetMapping("sendReturnCallback")
    public Resp sendReturnCallback() {
        RabbitTemplate.ReturnCallback returnCallback = (message, replyCode, replyText, exchange, routingKey) -> {
            System.out.println("========returnCallback=============");
        };
        rabbitTemplate.setReturnCallback(returnCallback);
        amqpTemplate.convertAndSend("test-", "测试发布回调模式");
        return Resp.success("ok", null);
    }

Dirección de origen: https://gitee.com/zoo-plus/springboot-learn/tree/2.x/springboot-middleware/rabbitmq

Supongo que te gusta

Origin blog.csdn.net/qq_36850813/article/details/104294779
Recomendado
Clasificación