Varias soluciones eficientes para tareas retrasadas
A las tareas que requieren una ejecución retrasada las llamamos tareas retrasadas. Es decir, es un conjunto de acciones que se realizan en un momento específico después o antes de que ocurra un evento.
Algunos escenarios de aplicación donde se pueden utilizar tareas retrasadas son los siguientes:
Algunas características de las tareas retrasadas son las siguientes:
Redis implementa tareas retrasadas utilizando su Estructura de datos ZSET. ZSET puede almacenar puntuaciones y valores, y puede ordenarse según las puntuaciones.
Los pasos de implementación de las tareas retrasadas son los siguientes:
(1) Utilice el tiempo de ejecución de la tarea como puntuación, los datos de la tarea a ejecutar como valor, y use jobId+topicName+groupId+delayTime como clave, y use el comando zadd para almacenar los datos en zset;
p> (2) Usar el proceso para consultar regularmente la puntuación del elemento más pequeño en zset, puede usar la tecla ZRANGEBYSCORE -inf +inf limit 0 1 withscores comando Implementación
(3) Si la puntuación mínima es menor o igual a la marca de tiempo actual, saque la tarea y ejecútela; Y use el comando zrem atom para eliminar los datos. De lo contrario, vuelva a consultar después de dormir por un período de tiempo.
Redis ZSET se implementa a través de una tabla de salto, con una complejidad de O(logN), donde N es el número de elementos almacenados en ZSET. Cuando se implementa mediante redis, puede confiar en el propio redis para lograr persistencia y admitir alta concurrencia y alta disponibilidad a través de clústeres de redis. Por tanto, los costes de desarrollo son muy bajos y se pueden realizar en tiempo real.
Ventajas:
1.Redis zset admite la clasificación de puntuaciones de alto rendimiento.
2.Redis se puede aumentar o disminuir dinámicamente, por lo que cuando hay muchos mensajes, podemos usar clústeres para aumentar la velocidad de procesamiento de mensajes y cumplir con la escalabilidad de la capacidad y el rendimiento.
3. Redis tiene un mecanismo de persistencia. Cuando ocurre una falla, los datos se pueden restaurar a través de AOF y RDB para garantizar la confiabilidad de los datos.
4. Sencillo y práctico, rápido de implementar.
Desventajas:
1. Para evitar el problema de que cuando una CLAVE almacena una gran cantidad de mensajes retrasados, las operaciones de cola y de consulta se ralentizarán (la complejidad temporal de estas dos operaciones son O (logN)), el método mejorado es enrutar la tarea de mensaje retrasado a diferentes claves de Redis a través del algoritmo hash y luego abrir varias claves de Redis. Redis Key y luego abra varios subprocesos de consumo para proporcionar rendimiento.
2.
2. Sin el mecanismo de confirmación, existe la posibilidad de que se pierda el mensaje.
3. Dado que los datos en redis zset se extraen regularmente a través del sondeo, existe un cierto retraso, que se puede reducir acortando el tiempo del sondeo, pero el sondeo frecuente provocará un desperdicio de CPU, lo que puede resolverse esperando/notificar.
4. Necesitamos implementar un mecanismo de reintento automático para intentos fallidos de envío.
Enlaces de referencia:
1. Excelente implementación de código abierto: /queuing_delay/
2. Hermosa implementación de código abierto:
RabbitMQ en sí no proporciona soporte directo para colas de retraso. Confiamos en el TTL y las colas de retraso de RabbitMQ. Las funciones TTL y de cola de mensajes no entregados de RabbitMQ se utilizan para lograr el efecto de cola de retraso.
La cola de mensajes no entregados es en realidad un mecanismo de procesamiento de mensajes de RabbitMQ. Cuando RabbitMQ genera y consume mensajes, los mensajes se convertirán en "letra muerta" si se cumple alguna de las siguientes condiciones:
TTL (Time-To-Live)
TTL es la supervivencia tiempo de RabbitMQ. TTL (Time-to-Live) es una característica avanzada de RabbitMQ que representa el tiempo máximo de supervivencia de un mensaje (en milisegundos).
Si un mensaje no se utiliza dentro del tiempo establecido por el TTL, se convertirá en un mensaje inactivo y entrará en la cola de mensajes inactivos que mencionamos anteriormente.
Hay dos formas diferentes de configurar la propiedad TTL del mensaje. Un método es establecer directamente el tiempo de vencimiento TTL para toda la cola al crear la cola, de modo que todos los mensajes que ingresan a la cola se establezcan en un tiempo de vencimiento unificado. Una vez que el mensaje caduque, se descartará inmediatamente y se ingresará como muerto. cola de mensajes; el otro es Este método está configurado para un solo mensaje, pero debe tenerse en cuenta que el TTL configurado con este método hará que el mensaje esté inactivo. Otro enfoque es configurarlo para un solo mensaje, pero tenga en cuenta que al configurar el TTL de esta manera, es posible que los mensajes no mueran a tiempo porque RabbitMQ solo verifica si el primer mensaje ha caducado. Por ejemplo, si establece un TTL de 20 segundos para el primer mensaje y un TTL de 10 segundos para el segundo mensaje, RabbitMQ espera hasta que caduque el primer mensaje antes de que caduque el segundo. Desde la versión 3.5.8 de RabbitMQ, hemos podido implementar fácilmente el intercambio de mensajes retrasados utilizando el complemento de intercambio de mensajes retrasados de Rabbitmq recomendado oficialmente.
Ventajas:
1. La mensajería confiable, la mensajería confiable y las colas de mensajes inactivos garantizan que los mensajes se consuman al menos una vez y que los mensajes que no se procesen correctamente no se descarten.
2. A través de las características del clúster RabbitMQ, se puede resolver el problema del punto único de falla, evitando así la suspensión de un solo nodo que causa retrasos en la cola e indisponibilidad o pérdida de mensajes.
Desventajas:
1. Necesidad de crear y mantener su propio clúster.
Cuando rocketmq envía un mensaje retrasado, primero enviará el mensaje a la cola especificada de acuerdo con el período de retraso (colocar mensajes con el mismo período de retraso en la misma cola puede garantizar el orden de procesamiento de mensajes, lo que permite La misma cola tiene el mismo tiempo de retraso de mensajes y los mensajes retrasados en todo RocketMQ se ordenarán en orden creciente para garantizar el orden de procesamiento). Los mensajes retrasados de todo RocketMQ se ordenan en orden creciente para garantizar la secuencia de procesamiento de mensajes). Luego, un temporizador pasa por la cola. Luego, el temporizador sondea los mensajes en la cola para determinar si han caducado. La información caducada se enviará a la cola correspondiente para su procesamiento.
Nota: Actualmente, RocketMQ solo admite períodos de tiempo de retraso específicos, 1 segundo, 5 segundos, 10 segundos, .... 2 h, y no puede admitir configuraciones de retraso para ningún período de tiempo.
Ventajas:
1. Distribuido, alto rendimiento, alto rendimiento y alta confiabilidad.
Desventajas:
1. Debe crear, ejecutar y mantener el clúster usted mismo.
2. Solo admite un período de retraso específico.
ActiveMQ admite mensajes retrasados persistentemente en la versión 5.4 y superiores, e incluso admite expresiones Cron. De forma predeterminada, esta función no está habilitada. Para habilitar esta función, debe modificar el archivo de configuración activemq.xml y establecer la propiedad SchedulerSupport en verdadero en el nodo del intermediario.
Ventajas:
1. El soporte para expresiones cron es más flexible.
Desventajas:
1. Debe crear y ejecutar el clúster usted mismo.
Si la cantidad de datos es pequeña, puedes intentar usar quartz, delayQueue, TimeWheel, etc. Sin embargo, para garantizar que no se pierdan datos, debe utilizar un sistema de almacenamiento persistente de terceros, como rocksDB.
Si la cantidad de datos es grande, puedes intentar usar quartz, delayQueue o TimeWheel.