Tengo un sistema donde un cliente (llamémoslo ClientA) puede publicar solicitudes a un tema MQTT particular. El corredor, en caso de que sea importante, es Amazon Web Services. Luego tengo otro cliente (llamémoslo MainSubscriber) que siempre está suscrito al mismo tema para que pueda recibir solicitudes de ClientA y hacer un trabajo que, al final, se convierte en una operación de base de datos. La base de datos, en caso de que sea importante, es DynamoDB.
Dado que MainSubscriber puede no estar siempre accesible / en línea, existe el deseo de tener un suscriptor de conmutación por error para que sea la copia de seguridad de conmutación por error del suscriptor principal. La idea es que si el suscriptor principal no maneja la solicitud de manera oportuna, entonces el suscriptor de conmutación por error se activará y realizará la operación equivalente de trabajo / base de datos. El desafío es que el "trabajo" y la "operación de la base de datos" resultante no deben ser duplicados por los suscriptores principales y de conmutación por error.
Aquí hay un dibujo de arquitectura de sistema lógico para este sistema.
-----> MainSubscriber ----
/ \
ClientA --> Broker ---> Database
\ /
---> FailoverSubscriber --
Claramente, hay algunos desafíos con este sistema:
- ¿Cómo le indica el suscriptor principal al suscriptor de conmutación por error que está trabajando en la solicitud?
- ¿Cómo detecta el suscriptor de conmutación por error que el suscriptor principal no ha recibido la solicitud y necesita comenzar a trabajar en ella?
- ¿Cómo detiene el suscriptor de conmutación por error el suscriptor principal en caso de que de repente vuelva a estar en línea y responda a la solicitud?
- ¿Cómo lidiar con los problemas de sincronía entre los suscriptores principales y de conmutación por error?
Preferiría no tener que reinventar la rueda si ya existe una solución existente para tal esquema. Entonces, mi primera pregunta es si ya hay algo por ahí.
De lo contrario, estaba pensando en usar DynamoDB con lecturas muy consistentes para actuar como mediador entre el suscriptor principal y el de conmutación por error. Entonces, mi segunda pregunta es si hay algún esquema bien establecido para hacer esto.
Respuestas:
De acuerdo con la documentación de AWS SQS (como usted dijo que el corredor es AWS), esto debería ser nativo:
El problema es encontrar el tiempo de espera de visibilidad adecuado de acuerdo con su tiempo de procesamiento máximo.
Todavía tiene una pequeña posibilidad de que ambos suscriptores procesen el mismo mensaje, en este caso su código de suscriptor debe intentar crear una salida idempotente para la base de datos (al menos la misma clave primaria) y debe manejar con gracia un error al intentar insertar el mismo registro.
fuente
Es posible que desee ver el concepto de colas de mensajes no entregados de AWS SQS . De los documentos de AWS:
Por lo tanto, si señala al suscriptor principal para que escuche desde la cola normal y al suscriptor secundario para que escuche desde la cola de mensajes no entregados, se debe resolver el problema de conmutación por error.
Además, con esto, se atienden 1, 2 y 3 de sus problemas. Los suscriptores principales y secundarios no necesitan hablar entre ellos en este caso.
Además, basándose en la respuesta de Tensibai, asegúrese de que su código de suscriptor esté escrito para recibir un mensaje a la vez si varios suscriptores escuchan la misma cola debido a
visibility timeout
Lo malo sería que introduciría un retraso en el procesamiento, los mensajes ingresan en la cola de mensajes no entregados solo después de un tiempo.
Entonces, en caso de que no quieras eso, entonces puedes seguir adelante con la respuesta de Tensibai. Y si puede tolerar eso, en lugar de tener una tabla Dynamo adicional para las comprobaciones de estado, puede usar esto.
fuente