Condividi tramite


libreria client bus di servizio di Azure per .NET - versione 7.13.1

bus di servizio di Azure consente di creare applicazioni che sfruttano i modelli di messaggistica asincrona usando un servizio altamente affidabile per gestire i messaggi tra producer e consumer. bus di servizio di Azure offre messaggistica flessibile e negoziata tra client e server, insieme alla messaggistica FIFO (First-In, First-Out) strutturata e alle funzionalità di pubblicazione/sottoscrizione con routing complesso. Per altre informazioni su bus di servizio di Azure, è possibile consultare: Che cos'è bus di servizio di Azure?

Usare la libreria client per bus di servizio di Azure per:

  • Trasferire i dati aziendali: sfruttare la messaggistica per lo scambio durevole di informazioni, ad esempio ordini di vendita o acquisti, giornali di registrazione o spostamenti di inventario.

  • Separare le applicazioni: migliorare l'affidabilità e la scalabilità di applicazioni e servizi, alleviare i mittenti e i ricevitori della necessità di essere online contemporaneamente.

  • Controllare la modalità di elaborazione dei messaggi: supportare i consumer tradizionali concorrenti per i messaggi usando le code o consentire a ogni consumer la propria istanza di un messaggio usando argomenti e sottoscrizioni.

  • Implementare flussi di lavoro complessi: le sessioni di messaggio supportano scenari che richiedono l'ordinamento dei messaggi o il rinvio dei messaggi.

Codice | sorgente Pacchetto (NuGet) | Documentazione | di riferimento sulle APIDocumentazione | del prodotto Guida | alla migrazione Guida alla risoluzione dei problemi

Introduzione

Prerequisiti

  • Sottoscrizione di Microsoft Azure: Per usare i servizi di Azure, inclusi i bus di servizio di Azure, è necessaria una sottoscrizione. Se non si ha un account Azure esistente, è possibile iscriversi per ottenere una versione di valutazione gratuita o usare i vantaggi del sottoscrittore MSDN quando si crea un account.

  • Spazio dei nomi del bus di servizio: Per interagire con bus di servizio di Azure, è necessario avere anche uno spazio dei nomi disponibile. Se non si ha familiarità con la creazione di risorse di Azure, è possibile seguire la guida dettagliata per la creazione di uno spazio dei nomi del bus di servizio usando il portale di Azure. È anche possibile trovare istruzioni dettagliate per l'uso dell'interfaccia della riga di comando di Azure, dei Azure PowerShell o dei modelli di Azure Resource Manager (ARM) per creare un'entità del bus di servizio.

  • C# 8.0: La libreria client bus di servizio di Azure usa nuove funzionalità introdotte in C# 8.0. Per sfruttare i vantaggi della sintassi C# 8.0, è consigliabile compilare usando .NET Core SDK 3.0 o versione successiva con una versione del linguaggio di latest.

    Gli utenti di Visual Studio che desiderano sfruttare appieno la sintassi C# 8.0 dovranno usare Visual Studio 2019 o versione successiva. Visual Studio 2019, inclusa l'edizione Community gratuita, può essere scaricato qui. Gli utenti di Visual Studio 2017 possono sfruttare la sintassi C# 8 usando il pacchetto NuGet Microsoft.Net.Compilers e impostando la versione del linguaggio, anche se l'esperienza di modifica potrebbe non essere ideale.

    È comunque possibile usare la libreria con le versioni precedenti del linguaggio C#, ma sarà necessario gestire manualmente membri enumerabili asincroni e asincroni eliminabili anziché trarre vantaggio dalla nuova sintassi. È comunque possibile usare qualsiasi versione del framework supportata da .NET Core SDK, incluse le versioni precedenti di .NET Core o .NET Framework. Per altre informazioni, vedere: come specificare i framework di destinazione.

    Nota importante: Per compilare o eseguire gli esempi e gli esempi senza modifiche, l'uso di C# 8.0 è obbligatorio. È comunque possibile eseguire gli esempi se si decide di modificarli per altre versioni del linguaggio.

Per creare rapidamente le risorse del bus di servizio necessarie in Azure e ricevere una stringa di connessione, è possibile distribuire il modello di esempio facendo clic su:

Distribuisci in Azure

Installare il pacchetto

Installare la libreria client bus di servizio di Azure per .NET con NuGet:

dotnet add package Azure.Messaging.ServiceBus

Autenticare il client

Affinché la libreria client del bus di servizio interagisca con una coda o un argomento, è necessario comprendere come connettersi e autorizzarla. Il modo più semplice per farlo consiste nell'usare una stringa di connessione, che viene creata automaticamente durante la creazione di uno spazio dei nomi del bus di servizio. Se non si ha familiarità con i criteri di accesso condiviso in Azure, è possibile seguire la guida dettagliata per ottenere una stringa di connessione del bus di servizio.

Dopo aver creato una stringa di connessione, è possibile autenticare il client con esso.

// Create a ServiceBusClient that will authenticate using a connection string
string connectionString = "<connection_string>";
await using var client = new ServiceBusClient(connectionString);

Per informazioni su come eseguire l'autenticazione con Azure.Identity, vedere questo esempio.

Per informazioni su come avviare la connessione con un endpoint personalizzato, vedere questo esempio.

ASP.NET Core

Per inserire ServiceBusClient come dipendenza in un'app ASP.NET Core, installare l'integrazione della libreria client di Azure per ASP.NET Core pacchetto.

dotnet add package Microsoft.Extensions.Azure

Registrare quindi il client nel Startup.ConfigureServices metodo :

public void ConfigureServices(IServiceCollection services)
{
    services.AddAzureClients(builder =>
    {
        builder.AddServiceBusClient(Configuration.GetConnectionString("ServiceBus"));
    });
  
    services.AddControllers();
}

Per usare il codice precedente, aggiungerlo alla configurazione:

{
  "ConnectionStrings": {
    "ServiceBus": "<connection_string>"
  }
}

Per altre informazioni, vedere Inserimento di dipendenze con Azure SDK per .NET.

Concetti chiave

Dopo aver inizializzato un ServiceBusClientoggetto , è possibile interagire con i tipi di risorse primari all'interno di uno spazio dei nomi del bus di servizio, di cui possono esistere più e su cui avviene la trasmissione effettiva dei messaggi, lo spazio dei nomi viene spesso usato come contenitore dell'applicazione:

  • Coda: consente l'invio e la ricezione di messaggi. Spesso usato per la comunicazione da punto a punto.

  • Argomento: a differenza delle code, gli argomenti sono più adatti per gli scenari di pubblicazione/sottoscrizione. Un argomento può essere inviato a , ma richiede una sottoscrizione, di cui possono essere presenti più in parallelo, da utilizzare.

  • Sottoscrizione: meccanismo da utilizzare da un argomento. Ogni sottoscrizione è indipendente e riceve una copia di ogni messaggio inviato all'argomento. Le regole e i filtri possono essere usati per personalizzare i messaggi ricevuti da una sottoscrizione specifica.

Per altre informazioni su queste risorse, vedere Che cos'è bus di servizio di Azure?.

Per interagire con queste risorse, è necessario avere familiarità con i concetti dell'SDK seguenti:

  • Un client del bus di servizio è l'interfaccia principale per gli sviluppatori che interagiscono con la libreria client del bus di servizio. Funge da gateway da cui si verificherà tutta l'interazione con la libreria.

  • Un mittente del bus di servizio ha come ambito una coda o un argomento specifico e viene creato usando il client del bus di servizio. Il mittente consente di inviare messaggi a una coda o a un argomento. Consente inoltre di pianificare i messaggi per il recapito in una data specificata.

  • Un ricevitore del bus di servizio ha come ambito una coda o una sottoscrizione specifica e viene creato usando il client del bus di servizio. Il ricevitore consente di ricevere messaggi da una coda o da una sottoscrizione. Consente inoltre di risolvere i messaggi dopo averli ricevuti. Esistono quattro modi per risolvere i messaggi:

    • Completamento: determina l'eliminazione del messaggio dalla coda o dall'argomento.
    • Abbandono: rilascia il blocco del ricevitore sul messaggio, consentendo la ricezione del messaggio da parte di altri ricevitori.
    • Rinvia: impedisce la ricezione del messaggio tramite mezzi normali. Per ricevere messaggi posticipati, è necessario conservare il numero di sequenza del messaggio.
    • DeadLetter: sposta il messaggio nella coda Dei messaggi non recapitabili. In questo modo si impedisce la ricezione del messaggio. Per ricevere messaggi dalla coda dei messaggi non recapitabili, è necessario un ricevitore con ambito nella coda Dei messaggi non recapitabili.
  • Un ricevitore di sessione del bus di servizio ha come ambito una coda o una sottoscrizione specifica abilitata per la sessione e viene creata usando il client del bus di servizio. Il ricevitore di sessione è quasi identico al ricevitore standard, con la differenza che le operazioni di gestione delle sessioni vengono esposte che si applicano solo alle entità abilitate per la sessione. Queste operazioni includono il recupero e l'impostazione dello stato della sessione, nonché il rinnovo dei blocchi di sessione.

  • Un processore del bus di servizio ha come ambito una coda o una sottoscrizione specifica e viene creato usando il client del bus di servizio. Può ServiceBusProcessor essere considerato come un'astrazione intorno a un set di ricevitori. Usa un modello di callback per consentire l'impostazione del codice quando viene ricevuto un messaggio e quando si verifica un'eccezione. Offre il completamento automatico dei messaggi elaborati, il rinnovo automatico del blocco dei messaggi e l'esecuzione simultanea dei gestori eventi specificati dall'utente. A causa del set di funzionalità, deve essere lo strumento vai a per scrivere applicazioni che ricevono dalle entità del bus di servizio. ServiceBusReceiver è consigliato per scenari più complessi in cui il processore non è in grado di fornire il controllo granulare previsto quando si usa direttamente ServiceBusReceiver.

  • Un processore di sessione del bus di servizio ha come ambito una coda o una sottoscrizione specifica abilitata per la sessione e viene creata usando il client del bus di servizio. Il processore di sessione è quasi identico al processore standard, con la differenza che le operazioni di gestione delle sessioni vengono esposte che si applicano solo alle entità abilitate per la sessione.

Per altri concetti e approfondimenti, vedere: Funzionalità avanzate del bus di servizio.

Durata del client

I ServiceBusClientmittenti, i ricevitori e i processori sono sicuri per memorizzare nella cache e usare come singleton per la durata dell'applicazione, procedura consigliata quando i messaggi vengono inviati o ricevuti regolarmente. Sono responsabili della gestione efficiente della rete, della CPU e dell'uso della memoria, lavorando per mantenere basso l'utilizzo durante i periodi di inattività.

Questi tipi sono eliminabili e chiamano DisposeAsync o CloseAsync è necessario per garantire che le risorse di rete e altri oggetti non gestiti siano puliti correttamente. È importante notare che, quando un'istanza ServiceBusClient viene eliminata, chiude automaticamente e pulisce tutti i mittenti, i ricevitori e i processori creati con esso.

Thread safety

Microsoft garantisce che tutti i metodi di istanza client siano thread-safe e indipendenti l'uno dall'altro (linee guida). Ciò garantisce che la raccomandazione di riutilizzare le istanze client sia sempre sicura, anche tra thread.

Concetti aggiuntivi

Opzioni | client Diagnostica | Beffardo

Esempio

Inviare e ricevere un messaggio

L'invio di messaggi viene eseguito usando .ServiceBusSender La ricezione viene eseguita usando .ServiceBusReceiver

string connectionString = "<connection_string>";
string queueName = "<queue_name>";
// since ServiceBusClient implements IAsyncDisposable we create it with "await using"
await using var client = new ServiceBusClient(connectionString);

// create the sender
ServiceBusSender sender = client.CreateSender(queueName);

// create a message that we can send. UTF-8 encoding is used when providing a string.
ServiceBusMessage message = new ServiceBusMessage("Hello world!");

// send the message
await sender.SendMessageAsync(message);

// create a receiver that we can use to receive the message
ServiceBusReceiver receiver = client.CreateReceiver(queueName);

// the received message is a different type as it contains some service set properties
ServiceBusReceivedMessage receivedMessage = await receiver.ReceiveMessageAsync();

// get the message body as a string
string body = receivedMessage.Body.ToString();
Console.WriteLine(body);

Invio di un batch di messaggi

Esistono due modi per inviare diversi messaggi contemporaneamente. Il primo modo per eseguire questa operazione usa il batch sicuro. Con il batch sicuro è possibile creare un ServiceBusMessageBatch oggetto, che consente di tentare di aggiungere messaggi uno alla volta al batch usando il TryAdd metodo . Se il messaggio non può adattarsi al batch, TryAdd restituirà false.

// add the messages that we plan to send to a local queue
Queue<ServiceBusMessage> messages = new Queue<ServiceBusMessage>();
messages.Enqueue(new ServiceBusMessage("First message"));
messages.Enqueue(new ServiceBusMessage("Second message"));
messages.Enqueue(new ServiceBusMessage("Third message"));

// create a message batch that we can send
// total number of messages to be sent to the Service Bus queue
int messageCount = messages.Count;

// while all messages are not sent to the Service Bus queue
while (messages.Count > 0)
{
    // start a new batch
    using ServiceBusMessageBatch messageBatch = await sender.CreateMessageBatchAsync();

    // add the first message to the batch
    if (messageBatch.TryAddMessage(messages.Peek()))
    {
        // dequeue the message from the .NET queue once the message is added to the batch
        messages.Dequeue();
    }
    else
    {
        // if the first message can't fit, then it is too large for the batch
        throw new Exception($"Message {messageCount - messages.Count} is too large and cannot be sent.");
    }

    // add as many messages as possible to the current batch
    while (messages.Count > 0 && messageBatch.TryAddMessage(messages.Peek()))
    {
        // dequeue the message from the .NET queue as it has been added to the batch
        messages.Dequeue();
    }

    // now, send the batch
    await sender.SendMessagesAsync(messageBatch);

    // if there are any remaining messages in the .NET queue, the while loop repeats
}

Il secondo modo usa l'overload SendMessagesAsync che accetta un oggetto IEnumerable di ServiceBusMessage. Con questo metodo si tenterà di adattare tutti i messaggi forniti in un singolo batch di messaggi che verrà inviato al servizio. Se i messaggi sono troppo grandi da adattare in un singolo batch, l'operazione genererà un'eccezione.

IList<ServiceBusMessage> messages = new List<ServiceBusMessage>();
messages.Add(new ServiceBusMessage("First"));
messages.Add(new ServiceBusMessage("Second"));
// send the messages
await sender.SendMessagesAsync(messages);

Ricezione di un batch di messaggi

// create a receiver that we can use to receive the messages
ServiceBusReceiver receiver = client.CreateReceiver(queueName);

// the received message is a different type as it contains some service set properties
// a batch of messages (maximum of 2 in this case) are received
IReadOnlyList<ServiceBusReceivedMessage> receivedMessages = await receiver.ReceiveMessagesAsync(maxMessages: 2);

// go through each of the messages received
foreach (ServiceBusReceivedMessage receivedMessage in receivedMessages)
{
    // get the message body as a string
    string body = receivedMessage.Body.ToString();
}

Completare un messaggio

Per rimuovere un messaggio da una coda o una sottoscrizione, è possibile chiamare il CompleteAsync metodo .

string connectionString = "<connection_string>";
string queueName = "<queue_name>";
// since ServiceBusClient implements IAsyncDisposable we create it with "await using"
await using var client = new ServiceBusClient(connectionString);

// create the sender
ServiceBusSender sender = client.CreateSender(queueName);

// create a message that we can send
ServiceBusMessage message = new ServiceBusMessage("Hello world!");

// send the message
await sender.SendMessageAsync(message);

// create a receiver that we can use to receive and settle the message
ServiceBusReceiver receiver = client.CreateReceiver(queueName);

// the received message is a different type as it contains some service set properties
ServiceBusReceivedMessage receivedMessage = await receiver.ReceiveMessageAsync();

// complete the message, thereby deleting it from the service
await receiver.CompleteMessageAsync(receivedMessage);

Abbandonare un messaggio

L'abbandono di un messaggio rilascia il blocco del ricevitore, che consente di ricevere il messaggio da questo o da altri ricevitori.

ServiceBusReceivedMessage receivedMessage = await receiver.ReceiveMessageAsync();

// abandon the message, thereby releasing the lock and allowing it to be received again by this or other receivers
await receiver.AbandonMessageAsync(receivedMessage);

Rinviare un messaggio

Rinviare un messaggio impedirà la ricezione di nuovo usando i ReceiveMessageAsync metodi o ReceiveMessagesAsync . Esistono invece metodi ReceiveDeferredMessageAsync separati e ReceiveDeferredMessagesAsync per la ricezione di messaggi posticipati.

ServiceBusReceivedMessage receivedMessage = await receiver.ReceiveMessageAsync();

// defer the message, thereby preventing the message from being received again without using
// the received deferred message API.
await receiver.DeferMessageAsync(receivedMessage);

// receive the deferred message by specifying the service set sequence number of the original
// received message
ServiceBusReceivedMessage deferredMessage = await receiver.ReceiveDeferredMessageAsync(receivedMessage.SequenceNumber);

Lettera non recapitata un messaggio

La lettera non recapitabile di un messaggio è simile a quella di rinviare con una differenza principale, ovvero che i messaggi verranno automaticamente recapitati dal servizio dopo che sono stati ricevuti un certo numero di volte. Le applicazioni possono scegliere di inviare messaggi di lettera non recapitabili manualmente in base ai propri requisiti. Quando viene inviato un messaggio non recapitato viene effettivamente spostato in una sottoqueue della coda originale. Si noti che viene ServiceBusReceiver usato per ricevere messaggi dalla sottoqueue della lettera non recapitata indipendentemente dal fatto che la coda principale sia abilitata per la sessione.

ServiceBusReceivedMessage receivedMessage = await receiver.ReceiveMessageAsync();

// Dead-letter the message, thereby preventing the message from being received again without receiving from the dead letter queue.
// We can optionally pass a dead letter reason and dead letter description to further describe the reason for dead-lettering the message.
await receiver.DeadLetterMessageAsync(receivedMessage, "sample reason", "sample description");

// receive the dead lettered message with receiver scoped to the dead letter queue.
ServiceBusReceiver dlqReceiver = client.CreateReceiver(queueName, new ServiceBusReceiverOptions
{
    SubQueue = SubQueue.DeadLetter
});
ServiceBusReceivedMessage dlqMessage = await dlqReceiver.ReceiveMessageAsync();

// The reason and the description that we specified when dead-lettering the message will be available in the received dead letter message.
string reason = dlqMessage.DeadLetterReason;
string description = dlqMessage.DeadLetterErrorDescription;

Per altre informazioni, vedere la panoramica delle code di lettere non recapitabili di ServiceBus.

Uso del processore

Il ServiceBusProcessor può essere considerato come un'astrazione intorno a un set di ricevitori. Usa un modello di callback per consentire l'impostazione del codice quando viene ricevuto un messaggio e quando si verifica un'eccezione. Offre il completamento automatico dei messaggi elaborati, il rinnovo automatico del blocco dei messaggi e l'esecuzione simultanea dei gestori eventi specificati dall'utente. A causa del set di funzionalità, deve essere lo strumento per la scrittura di applicazioni che ricevono da entità del bus di servizio. ServiceBusReceiver è consigliato per scenari più complessi in cui il processore non è in grado di fornire direttamente il controllo con granularità fine previsto quando si usa ServiceBusReceiver.

string connectionString = "<connection_string>";
string queueName = "<queue_name>";
// since ServiceBusClient implements IAsyncDisposable we create it with "await using"
await using var client = new ServiceBusClient(connectionString);

// create the sender
ServiceBusSender sender = client.CreateSender(queueName);

// create a set of messages that we can send
ServiceBusMessage[] messages = new ServiceBusMessage[]
{
    new ServiceBusMessage("First"),
    new ServiceBusMessage("Second")
};

// send the message batch
await sender.SendMessagesAsync(messages);

// create the options to use for configuring the processor
var options = new ServiceBusProcessorOptions
{
    // By default or when AutoCompleteMessages is set to true, the processor will complete the message after executing the message handler
    // Set AutoCompleteMessages to false to [settle messages](/azure/service-bus-messaging/message-transfers-locks-settlement#peeklock) on your own.
    // In both cases, if the message handler throws an exception without settling the message, the processor will abandon the message.
    AutoCompleteMessages = false,

    // I can also allow for multi-threading
    MaxConcurrentCalls = 2
};

// create a processor that we can use to process the messages
await using ServiceBusProcessor processor = client.CreateProcessor(queueName, options);

// configure the message and error handler to use
processor.ProcessMessageAsync += MessageHandler;
processor.ProcessErrorAsync += ErrorHandler;

async Task MessageHandler(ProcessMessageEventArgs args)
{
    string body = args.Message.Body.ToString();
    Console.WriteLine(body);

    // we can evaluate application logic and use that to determine how to settle the message.
    await args.CompleteMessageAsync(args.Message);
}

Task ErrorHandler(ProcessErrorEventArgs args)
{
    // the error source tells me at what point in the processing an error occurred
    Console.WriteLine(args.ErrorSource);
    // the fully qualified namespace is available
    Console.WriteLine(args.FullyQualifiedNamespace);
    // as well as the entity path
    Console.WriteLine(args.EntityPath);
    Console.WriteLine(args.Exception.ToString());
    return Task.CompletedTask;
}

// start processing
await processor.StartProcessingAsync();

// since the processing happens in the background, we add a Console.ReadKey to allow the processing to continue until a key is pressed.
Console.ReadKey();

Autenticazione con Azure.Identity

La libreria di identità di Azure offre un supporto semplice di Azure Active Directory per l'autenticazione.

// Create a ServiceBusClient that will authenticate through Active Directory
string fullyQualifiedNamespace = "yournamespace.servicebus.windows.net";
await using var client = new ServiceBusClient(fullyQualifiedNamespace, new DefaultAzureCredential());

Uso delle sessioni

Le sessioni forniscono un meccanismo per raggruppare i messaggi correlati. Per usare le sessioni, è necessario usare un'entità abilitata per la sessione.

Risoluzione dei problemi

Vedere la Guida alla risoluzione dei problemi del bus di servizio.

Passaggi successivi

Oltre agli scenari introduttivi illustrati, la libreria client bus di servizio di Azure offre supporto per scenari aggiuntivi per sfruttare il set completo di funzionalità del servizio bus di servizio di Azure. Per esplorare alcuni di questi scenari, la libreria client del bus di servizio offre un progetto di esempi da usare come illustrazione per scenari comuni. Per informazioni dettagliate, vedere gli esempi README .

Contributo

In questo progetto sono benvenuti i contributi e i suggerimenti. Per la maggior parte dei contenuti è necessario sottoscrivere un contratto di licenza di collaborazione (CLA, Contributor License Agreement) che stabilisce che l'utente ha il diritto di concedere, e di fatto concede a Microsoft i diritti d'uso del suo contributo. Per informazioni dettagliate, vedere https://cla.microsoft.com.

Quando si invia una richiesta pull, un bot CLA determina automaticamente se è necessario specificare un contratto CLA e completare la richiesta pull in modo appropriato (ad esempio con un'etichetta e un commento). Seguire le istruzioni specificate dal bot. È sufficiente eseguire questa operazione una sola volta per tutti i repository che usano il contratto CLA Microsoft.

Questo progetto ha adottato il Codice di comportamento di Microsoft per l'open source. Per altre informazioni, vedere Code of Conduct FAQ (Domande frequenti sul Codice di comportamento Open Source di Microsoft) oppure contattare opencode@microsoft.com per eventuali altre domande o commenti.

Per altre informazioni, vedere la guida ai contributi .

Impression