Cuando un productor envía un mensaje al broker de ApsaraMQ for RocketMQ, la solicitud puede fallar debido a problemas de red, reinicios del broker o límites de capacidad. El SDK del cliente gestiona estos fallos mediante dos mecanismos integrados:
Reintento de envío: reenvía automáticamente los mensajes con errores hasta que se entregan correctamente o se alcanza el límite de reintentos.
Limitación de tasa: protege al broker contra sobrecargas al rechazar solicitudes cuando la capacidad es insuficiente.
Ambos mecanismos funcionan en conjunto: cuando la limitación de tasa provoca un rechazo, el mecanismo de reintento utiliza un retroceso exponencial para reenviar el mensaje sin saturar aún más al broker.
Reintento de envío
Proceso de reintento
El SDK del cliente incluye una lógica de reintento integrada. Cuando falla una solicitud de envío, el SDK reenvía el mensaje automáticamente, por lo que no se requiere código de reintento a nivel de aplicación.
Establezca el número máximo de reintentos al inicializar el productor. Si una solicitud falla, el SDK la reintenta hasta que el mensaje se entrega o se alcanza el límite de reintentos. Si falla el último reintento, el SDK devuelve un error a su aplicación.
El comportamiento de reintento varía según el modo de envío:
|
Modo de envío |
Comportamiento del hilo |
En caso de fallo final |
|
Sincrónico |
El hilo que realiza la llamada se bloquea durante toda la secuencia de reintentos |
El SDK lanza una excepción |
|
Asincrónico |
El hilo que realiza la llamada no se bloquea |
El SDK entrega un evento de callback de fallo |
Activadores de reintento
Los reintentos se activan por dos categorías de fallos:
Fallos del lado del cliente
Una excepción de red provoca un fallo de conexión o un tiempo de espera agotado en la solicitud.
El broker se está reiniciando o desimplementando, lo que causa fallos de conexión.
El broker presenta lentitud, lo que provoca que se agote el tiempo de espera de las solicitudes.
Errores del lado del broker
Error de lógica del sistema: un error de procesamiento interno en el broker.
Error de limitación de tasa del sistema: el broker rechaza la solicitud porque se ha excedido la capacidad. Consulte Limitación de tasa.
Los mensajes transaccionales solo admiten reintentos transparentes. El SDK no reintenta mensajes transaccionales ante excepciones de red o tiempos de espera agotados.
Intervalo de reintento
El intervalo de reintento depende del tipo de error:
|
Tipo de error |
Intervalo de reintento |
|
Todos los errores excepto limitación de tasa |
Inmediato (sin retraso) |
|
Error de limitación de tasa del sistema |
Retroceso exponencial con variación aleatoria |
Para errores de limitación de tasa, el SDK utiliza un retroceso exponencial con los siguientes parámetros:
|
Parámetro |
Descripción |
Valor predeterminado |
|
|
Retraso antes del primer reintento |
1 segundo |
|
|
Factor por el cual aumenta el retraso después de cada reintento |
1.6 |
|
|
Factor de aleatoriedad aplicado a cada retraso |
0.2 |
|
|
Retraso máximo entre reintentos |
120 segundos |
|
|
Tiempo de espera mínimo de conexión |
20 segundos |
El algoritmo de retroceso funciona de la siguiente manera:
ConnectWithBackoff()
current_backoff = INITIAL_BACKOFF
current_deadline = now() + INITIAL_BACKOFF
while (TryConnect(Max(current_deadline, now() + MIN_CONNECT_TIMEOUT)) != SUCCESS)
SleepUntil(current_deadline)
current_backoff = Min(current_backoff * MULTIPLIER, MAX_BACKOFF)
current_deadline = now() + current_backoff +
UniformRandom(-JITTER * current_backoff, JITTER * current_backoff)
Para consultar la especificación completa, revise retroceso de conexión gRPC.
Comprensión del presupuesto total de tiempo de reintento
El SDK expone solo un control de reintento: el número máximo de reintentos. En modo sincrónico, el hilo que realiza la llamada se bloquea durante toda la secuencia de reintentos, por lo que el tiempo total de bloqueo depende de la relación entre el tiempo de espera por solicitud y el recuento máximo de reintentos:
Total blocking time (worst case) = max_retries x per_request_timeout + sum_of_backoff_delays
Para errores que no son de limitación de tasa (reintento inmediato), el retraso por retroceso es cero:
Total blocking time = max_retries x per_request_timeout
En errores de limitación de tasa, los retrasos por retroceso se acumulan exponencialmente. Por ejemplo, con los parámetros predeterminados y 5 reintentos:
|
Reintento |
Retraso por retroceso (aproximado) |
Retraso acumulado |
|
1 |
1 s |
1 s |
|
2 |
1.6 s |
2.6 s |
|
3 |
2.56 s |
5.16 s |
|
4 |
4.1 s |
9.26 s |
|
5 |
6.55 s |
15.81 s |
Evalúe conjuntamente el tiempo de espera por solicitud y el máximo de reintentos para evitar que el hilo que realiza la llamada se bloquee durante demasiado tiempo en modo sincrónico.
Gestión de mensajes con errores tras agotar los reintentos
Los reintentos integrados no garantizan la entrega. Si todos los reintentos fallan, el SDK devuelve un error. Capture este error en su aplicación e implemente una estrategia alternativa:
Escriba el mensaje con errores en un registro local o en un almacén de mensajes muertos para reprocesarlo posteriormente.
Alerte a su sistema de monitoreo para poder investigar la causa raíz.
Gestión de mensajes duplicados por reintentos
Cuando se agota el tiempo de espera de una solicitud de envío, el SDK no puede determinar si el broker ya recibió y almacenó el mensaje. Un reintento puede generar un duplicado en el broker. Esta es una compensación fundamental en los sistemas de entrega "al menos una vez".
Para gestionar duplicados, diseñe sus consumidores para un procesamiento idempotente:
Asigne a cada mensaje una clave de negocio única (como un ID de pedido o un ID de transacción).
Antes de procesar, compruebe si la clave ya se procesó.
Utilice restricciones de base de datos o cachés de deduplicación para garantizar la unicidad.
Limitación de tasa
La limitación de tasa es un mecanismo operativo normal en los sistemas de mensajería en la nube. Cuando la capacidad del sistema es insuficiente o el uso supera un umbral predefinido, el broker de ApsaraMQ for RocketMQ rechaza inmediatamente la solicitud y devuelve un error de limitación de tasa del sistema. La lógica de reintento integrada del SDK gestiona entonces la solicitud rechazada mediante un retroceso exponencial.
Activadores de limitación de tasa
La limitación de tasa se activa en los siguientes escenarios:
Pico de presión de almacenamiento: un grupo de consumidores comienza a consumir desde el desplazamiento máximo de una cola. En escenarios como lanzamientos de negocios donde un grupo de consumidores debe comenzar a consumir en un momento específico, la presión de almacenamiento en la cola se dispara. Para obtener más información, consulte Consumer progress management.
Acumulación de mensajes: cuando los consumidores no pueden seguir el ritmo de llegada de mensajes, los mensajes no consumidos se acumulan en la cola. Si la acumulación supera el umbral, el broker activa la limitación de tasa para reducir la presión sobre el sistema posterior.
Códigos de error y comportamiento de reintento por tipo de cliente
Cuando se activa la limitación de tasa, el código de error y el comportamiento de reintento dependen del protocolo de su cliente.
Clientes gRPC
|
Elemento |
Valor |
|
Código de error |
|
|
Palabra clave del mensaje de error |
|
|
Comportamiento de reintento |
Reintento automático con retroceso exponencial |
Clientes Remoting
|
Elemento |
Valor |
|
Código de error |
|
|
Palabra clave del mensaje de error |
|
El comportamiento de reintento para clientes Remoting varía según la versión del SDK:
|
SDK |
Comportamiento de reintento ante limitación de tasa |
|
ApsaraMQ for RocketMQ TCP client SDK for Java < 1.9.0.Final |
Sin reintento |
|
ApsaraMQ for RocketMQ TCP client SDK for Java >= 1.9.0.Final |
Reintento automático con retroceso exponencial |
|
Open-source Apache RocketMQ SDK (productor) |
Sin reintento |
|
Open-source Apache RocketMQ SDK (consumidor) |
Reintento automático con retroceso exponencial |
Si su versión del SDK no reintenta automáticamente ante errores de limitación de tasa, implemente una lógica de reintento con retroceso exponencial en el código de su aplicación.
Para consultar las versiones de cliente compatibles, revise SDK compatibility.
Prevención y gestión de la limitación de tasa
Monitoree la capacidad antes de picos de tráfico
Utilice las funciones de observability de ApsaraMQ for RocketMQ para supervisar el uso y la capacidad del sistema. Antes de lanzamientos de negocios o picos de tráfico anticipados:
Compruebe que su instancia cuenta con recursos suficientes para el tráfico esperado.
Revise el retraso del grupo de consumidores para identificar riesgos de acumulación.
Escale su instancia u optimice el rendimiento del consumidor si es necesario.
Gestión de limitaciones de tasa inesperadas en tiempo de ejecución
Si ocurre una limitación de tasa inesperadamente y los reintentos integrados del SDK no logran recuperarse:
Redirija las solicitudes a un sistema alternativo hasta que se resuelva la condición de limitación.
Registre los eventos de limitación de tasa (busque el código de error
530/TOO_MANY_REQUESTSpara gRPC o215/messages flow controlpara Remoting) para ayudar a diagnosticar la causa raíz.