Panoramica delle code dei messaggi non recapitabili del bus di servizioOverview of Service Bus dead-letter queues

Le code del bus di servizio e le sottoscrizioni dell'argomento includono una coda secondaria chiamata coda di messaggi non recapitabili (DLQ, Dead-Letter Queue).Service Bus queues and topic subscriptions provide a secondary sub-queue, called a dead-letter queue (DLQ). Non è necessario creare in modo esplicito la coda dei messaggi non recapitabili, che, tra l'altro, non può essere eliminata né altrimenti gestita indipendentemente dall'entità principale.The dead-letter queue does not need to be explicitly created and cannot be deleted or otherwise managed independent of the main entity.

Questo articolo descrive le code dei messaggi non recapitabili nel bus di servizio di Azure.This article discusses dead-letter queues in Azure Service Bus. Questo argomento viene in gran parte illustrato nell'esempio relativo alle code di messaggi non recapitabili su GitHub.Much of the discussion is illustrated by the Dead-Letter queues sample on GitHub.

Coda di messaggi non recapitabiliThe dead-letter queue

Lo scopo della coda dei messaggi non recapitabili è conservare i messaggi che non possono essere recapitati ai ricevitori o che non possono essere elaborati.The purpose of the dead-letter queue is to hold messages that cannot be delivered to any receiver, or messages that could not be processed. I messaggi possono essere rimossi dalla coda e verificati.Messages can then be removed from the DLQ and inspected. Con l'aiuto di un operatore, un'applicazione potrebbe correggere i problemi e inviare nuovamente il messaggio, registrare la notizia che si è verificato un errore e intraprendere azioni correttive.An application might, with help of an operator, correct issues and resubmit the message, log the fact that there was an error, and take corrective action.

Dal punto di vista di API e protocolli, la coda DLQ è molto simile a qualsiasi altra coda, ad eccezione del fatto che i messaggi possono essere inviati ad essa solo tramite il movimento messaggi non recapitabili dell'entità padre.From an API and protocol perspective, the DLQ is mostly similar to any other queue, except that messages can only be submitted via the dead-letter gesture of the parent entity. Inoltre, il parametro time-to-live non viene rispettato e non è possibile impostare come non recapitabile un messaggio di una coda DLQ.In addition, time-to-live is not observed, and you can't dead-letter a message from a DLQ. La coda dei messaggi non recapitabili supporta completamente il recapito con blocco di visualizzazione e le operazioni transazionali.The dead-letter queue fully supports peek-lock delivery and transactional operations.

Si noti che non è prevista alcuna pulizia automatica della coda.Note that there is no automatic cleanup of the DLQ. I messaggi rimangono nella coda fino a quando non vengono esplicitamente recuperati e non si chiama il metodo Complete() sul messaggio non recapitabile.Messages remain in the DLQ until you explicitly retrieve them from the DLQ and call Complete() on the dead-letter message.

Spostare messaggi nella coda DLQMoving messages to the DLQ

Nel bus di servizio sono presenti diverse attività che comportano l'inserimento di messaggi nella coda DLQ dall'interno del motore di messaggistica stesso.There are several activities in Service Bus that cause messages to get pushed to the DLQ from within the messaging engine itself. Un'applicazione può anche spostare in modo esplicito i messaggi nella coda dei messaggi non recapitabili.An application can also explicitly move messages to the DLQ.

Quando un messaggio viene spostato dal broker, vengono aggiunte al messaggio due proprietà, DeadLetterReason e DeadLetterErrorDescription, nel momento in cui il broker chiama la sua versione interna del metodo DeadLetter sul messaggio.As the message gets moved by the broker, two properties are added to the message as the broker calls its internal version of the DeadLetter method on the message: DeadLetterReason and DeadLetterErrorDescription.

Le applicazioni possono definire i propri codici per la proprietà DeadLetterReason, ma il sistema imposta i valori seguenti.Applications can define their own codes for the DeadLetterReason property, but the system sets the following values.

CondizioneCondition DeadLetterReasonDeadLetterReason DeadLetterErrorDescriptionDeadLetterErrorDescription
SempreAlways HeaderSizeExceededHeaderSizeExceeded È stata superata la dimensione del flusso.The size quota for this stream has been exceeded.
!TopicDescription.!TopicDescription.
EnableFilteringMessagesBeforePublishing e SubscriptionDescription.EnableFilteringMessagesBeforePublishing and SubscriptionDescription.
EnableDeadLetteringOnFilterEvaluationExceptionsEnableDeadLetteringOnFilterEvaluationExceptions
exception.GetType().Nameexception.GetType().Name exception.Messageexception.Message
EnableDeadLetteringOnMessageExpirationEnableDeadLetteringOnMessageExpiration TTLExpiredExceptionTTLExpiredException Il messaggio è scaduto ed è stato configurato come non recapitabile.The message expired and was dead lettered.
SubscriptionDescription.RequiresSessionSubscriptionDescription.RequiresSession L'ID sessione ha valore null.Session id is null. L'entità attivata dalla sessione non consente il recapito di un messaggio il cui identificatore di sessione è null.Session enabled entity doesn't allow a message whose session identifier is null.
!dead letter queue!dead letter queue MaxTransferHopCountExceededMaxTransferHopCountExceeded NullNull
Configurazione esplicita di messaggio non recapitabile da parte dell'applicazione Application explicit dead lettering Specificato dall'applicazioneSpecified by application Specificato dall'applicazioneSpecified by application

Superamento di MaxDeliveryCountExceeding MaxDeliveryCount

Le code e le sottoscrizioni hanno ognuna una proprietà QueueDescription.MaxDeliveryCount e SubscriptionDescription.MaxDeliveryCount. Il valore predefinito è 10.Queues and subscriptions each have a QueueDescription.MaxDeliveryCount and SubscriptionDescription.MaxDeliveryCount property respectively; the default value is 10. Ogni volta che un messaggio viene recapitato in un blocco (ReceiveMode.PeekLock) ma viene abbandonato in modo esplicito oppure il blocco è scaduto, il valore BrokeredMessage.DeliveryCount del messaggio viene incrementato.Whenever a message has been delivered under a lock (ReceiveMode.PeekLock), but has been either explicitly abandoned or the lock has expired, the message's BrokeredMessage.DeliveryCount is incremented. Quando il valore DeliveryCount supera MaxDeliveryCount, il messaggio viene spostato nella coda DLQ con il codice motivo MaxDeliveryCountExceeded.When DeliveryCount exceeds MaxDeliveryCount, the message is moved to the DLQ, specifying the MaxDeliveryCountExceeded reason code.

Non è possibile disattivare questo comportamento, ma è possibile impostare MaxDeliveryCount su un numero molto elevato.This behavior cannot be disabled, but you can set MaxDeliveryCount to a very large number.

Superamento di TimeToLiveExceeding TimeToLive

Quando la proprietà QueueDescription.EnableDeadLetteringOnMessageExpiration o SubscriptionDescription.EnableDeadLetteringOnMessageExpiration viene impostata su true (il valore predefinito è false), tutti i messaggi in scadenza vengono spostati nella coda DLQ con il codice motivo TTLExpiredException.When the QueueDescription.EnableDeadLetteringOnMessageExpiration or SubscriptionDescription.EnableDeadLetteringOnMessageExpiration property is set to true (the default is false), all expiring messages are moved to the DLQ, specifying the TTLExpiredException reason code.

Si noti che i messaggi scaduti vengono ripuliti e quindi spostati nella coda di messaggi non recapitabili solo quando esiste almeno un ricevitore attivo che effettua il pull della sottoscrizione o della coda principale. Tale comportamento è predefinito.Note that expired messages are only purged and therefore moved to the DLQ when there is at least one active receiver pulling on the main queue or subscription; that behavior is by design.

Errori durante l'elaborazione di regole di sottoscrizioneErrors while processing subscription rules

Quando la proprietà SubscriptionDescription.EnableDeadLetteringOnFilterEvaluationExceptions di una sottoscrizione è abilitata, qualsiasi errore si verifichi durante l'esecuzione di una regola di filtro SQL di una sottoscrizione viene acquisito nella coda DLQ con il messaggio che indica l'errore.When the SubscriptionDescription.EnableDeadLetteringOnFilterEvaluationExceptions property is enabled for a subscription, any errors that occur while a subscription's SQL filter rule executes are captured in the DLQ along with the offending message.

Definizione di messaggi non recapitabili a livello di applicazioneApplication-level dead-lettering

Oltre alle funzionalità di definizione dei messaggi non recapitabili del sistema, le applicazioni possono usare la coda DLQ per rifiutare esplicitamente i messaggi inaccettabili.In addition to the system-provided dead-lettering features, applications can use the DLQ to explicitly reject unacceptable messages. Ciò può riguardare i messaggi che non possono essere elaborati correttamente a causa diversi problemi del sistema, i messaggi contenenti payload in formato non valido o che non superino il processo di autenticazione quando viene utilizzato un schema di sicurezza a livello di messaggio.This may include messages that cannot be properly processed due to any sort of system issue, messages that hold malformed payloads, or messages that fail authentication when some message-level security scheme is used.

Messaggi non recapitabili negli scenari ForwardTo o SendViaDead-lettering in ForwardTo or SendVia scenarios

I messaggi verranno inviati nella coda dei messaggi non recapitabili di trasferimento nelle condizioni seguenti:Messages will be sent to the transfer dead-letter queue under the following conditions:

  • Un messaggio passa attraverso più di 3 code o argomenti che sono concatenati.A message passes through more than 3 queues or topics that are chained together.
  • L'argomento o la coda di destinazione è disattivato o eliminato.The destination queue or topic is disabled or deleted.
  • L'argomento o la coda di destinazione supera le dimensioni massime dell'entità.The destination queue or topic exceeds the maximum entity size.

Per recuperare questi messaggi non recapitabili, è possibile creare un destinatario usando il metodo di utilità FormatTransferDeadletterPath.To retrieve these dead-lettered messages, you can create a receiver using the FormatTransferDeadletterPath utility method.

EsempioExample

Il frammento di codice seguente crea un ricevitore del messaggio.The following code snippet creates a message receiver. Nel ciclo di ricezione della coda principale, il codice recupera il messaggio con Receive(TimeSpan.Zero), che richiede al broker di restituire immediatamente i messaggi disponibili o di restituire nessun risultato.In the receive loop for the main queue, the code retrieves the message with Receive(TimeSpan.Zero), which asks the broker to instantly return any message readily available, or to return with no result. Se riceve un messaggio, il codice lo abbandona immediatamente, incrementando DeliveryCount.If the code receives a message, it immediately abandons it, which increments the DeliveryCount. Dopo che il sistema ha spostato il messaggio alla coda DLQ, la coda principale rimane vuota e il ciclo viene interrotto, perché ReceiveAsync restituisce null.Once the system moves the message to the DLQ, the main queue is empty and the loop exits, as ReceiveAsync returns null.

var receiver = await receiverFactory.CreateMessageReceiverAsync(queueName, ReceiveMode.PeekLock);
while(true)
{
    var msg = await receiver.ReceiveAsync(TimeSpan.Zero);
    if (msg != null)
    {
        Console.WriteLine("Picked up message; DeliveryCount {0}", msg.DeliveryCount);
        await msg.AbandonAsync();
    }
    else
    {
        break;
    }
}

Passaggi successiviNext steps

Per altre informazioni sulle code del bus di servizio, vedere gli articoli seguenti:See the following articles for more information about Service Bus queues: