microsoft - ¿Cuál es la forma correcta de abandonar un mensaje de Azure SB para que vuelva a ser visible en el futuro de una manera que pueda controlar?
porta azure (5)
Entonces, el escenario es que estoy usando una cola SB para estrangular las devoluciones de llamadas a otros servicios. Uno de los problemas estándar al volver a llamar a otros servicios es que pueden estar inactivos por un tiempo incontrolable. Suponiendo que detecto que el objetivo está caído / no responde, ¿cuál es el mejor patrón para abandonar ese mensaje para que no vuelva a aparecer en la cola de inmediato?
Aquí hay algunos enfoques que conozco, he intentado o estoy considerando:
Obviamente, si solo uso
BrokeredMessage::Abandon()
el mensaje se desbloqueará y se volverá a poner en la cola. Esto obviamente es indeseable para este escenario y lo que estoy tratando de evitar.Si simplemente ignoro el hecho de que cometí un error y nunca llamo a Abandon, esto evitará que se muestre de inmediato, pero realmente no tengo un control preciso sobre cuánto tiempo hasta que aparezca de nuevo y me gustaría implementar un estrategia de reintento en descomposición.
Pensé que tal vez podría llamar a
BrokeredMessage::Abandon(IDictionary<string, object>)
y de alguna manera actualizar la propiedadScheduledEnqueueTimeUTC
, pero he intentado esto y no parece haber una manera de afectar esa propiedad más allá del envío inicial de mensaje. Tiene sentido, pero vale la pena intentarlo.He considerado simplemente el uso de
BrokeredMessage::Complete()
en esta situación y, en realidad, solo estoy poniendo en cola una nueva copia del mensaje con el conjunto de propiedadesScheduledEqueueTimeUTC
.
La bala final casi parece demasiado dura, pero estoy llegando a la conclusión de que probablemente sea la respuesta correcta dada la naturaleza inherente de las colas. Pensé que podría haber una forma mejor de hacerlo en las colas de Azure SB que me faltan.
En la viñeta n. ° 2 anterior: ¿No puede establecer el intervalo de tiempo TTL en el mensaje cuando llama a Receive(TimeSpan)
lugar de al Receive()
predeterminado? Luego, simplemente puede abandonar el mensaje (sin llamar a Abandon()
), y el mensaje debería volver a aparecer en la cola cuando caduque el TTL. Si bien esto no le da un control de grano fino para decir "Reaparecer después de x segundos", sí le proporciona previsibilidad para cuando reaparezca el mensaje.
Nota: Con las colas basadas en almacenamiento, puede actualizar el tiempo de espera de invisibilidad, por lo que le daría un control preciso para la reaparición del mensaje.
Preferiría el último enfoque porque parece ser la solución más simple que usa las características integradas del bus de servicio de Azure.
El flujo es este:
var newMessage = new BrokeredMessage();
// Copy message body and properties from original message...
var scheduleTimeUtc = DateTimeOffset.UtcNow.Add(...);
await queueClient.ScheduleMessageAsync(newMessage, scheduleTimeUtc);
await originalMessage.CompleteAsync()
Se siente un poco hacky, pero la solución que se me ocurrió es
try
{
...
}
catch (Exception ex)
{
await Task.Delay(30000);
throw;
}
De esta manera esperará 30 segundos antes de permitir que se abandone. Eventualmente será una letra muerta después de la cantidad de veces configurada.
Estoy usando Azure Webjobs para recibir. Aunque estoy usando Task.Delay
lugar de Thread.Sleep
, no parece estar liberando el hilo para procesar otro elemento de la cola mientras espera (de manera predeterminada, Webjobs procesa 16 en paralelo).
Si desea guardar un mensaje por un tiempo y tiene un lugar para anotar el número de secuencia (que podría estar en estado de sesión en una cola de sesión), puede aplazarlo (). Los mensajes diferidos se pueden recuperar utilizando una sobrecarga de recepción especial que proporciona el SequenceNumber; esa es también la única manera de llegar a ellos otra vez que no expiren, así que ten cuidado. Esta función se creó para flujos de trabajo y máquinas de estado para que puedan manejar la llegada de mensajes fuera de orden.
Si fuera usted, consultaría una de las muchas páginas de patrones de integración empresarial que existen en Internet para encontrar una solución. Básicamente, desea tener un reintento que, si falla, envía el mensaje sucesivamente a una cola de mensajes no entregados. Estos mensajes se pueden volver a poner en cola en una fecha posterior. Esto podría ser manual o automatizado dependiendo de los requisitos.
Tenga en cuenta que si bien la página que le envié está relacionada con el camello, por lo tanto, todo lo que se describe en esa página es aplicable .NET y azul. Aquí hay más .NET uno si está interesado en http://www.eaipatterns.com/