Come usare gli argomenti e le sottoscrizioni del bus di servizio con PythonHow to use Service Bus topics and subscriptions with Python

Questo articolo descrive come usare gli argomenti e le sottoscrizioni del bus di servizio.This article describes how to use Service Bus topics and subscriptions. Gli esempi sono scritti in Python e usano il pacchetto Azure SDK per Python.The samples are written in Python and use the Azure Python SDK package. Gli scenari presentati includono la creazione di argomenti e sottoscrizioni, la creazione di filtri per le sottoscrizioni, l’invio di messaggi a un argomento, la ricezione di messaggi da una sottoscrizione e l’eliminazione di argomenti e sottoscrizioni.The scenarios covered include creating topics and subscriptions, creating subscription filters, sending messages to a topic, receiving messages from a subscription, and deleting topics and subscriptions. Per altre informazioni sugli argomenti e sulle sottoscrizioni, vedere la sezione Passaggi successivi.For more information about topics and subscriptions, see the Next Steps section.

Cosa sono gli argomenti e le sottoscrizioni del bus di servizio?What are Service Bus topics and subscriptions?

Gli argomenti e le sottoscrizioni del bus di servizio supportano un modello di comunicazione con messaggistica di pubblicazione-sottoscrizione .Service Bus topics and subscriptions support a publish/subscribe messaging communication model. Quando si usano gli argomenti e le sottoscrizioni, i componenti di un'applicazione distribuita non comunicano direttamente l'uno con l'altro, ma scambiano messaggi tramite un argomento, che agisce da intermediario.When using topics and subscriptions, components of a distributed application do not communicate directly with each other; instead they exchange messages via a topic, which acts as an intermediary.

Concetti relativi agli argomenti

Diversamente dalle code del bus di servizio, in cui ogni messaggio viene elaborato da un unico consumer, gli argomenti e le sottoscrizioni offrono una forma di comunicazione "uno a molti" tramite un modello di pubblicazione-sottoscrizione.In contrast with Service Bus queues, in which each message is processed by a single consumer, topics and subscriptions provide a "one-to-many" form of communication, using a publish/subscribe pattern. È possibile registrare più sottoscrizioni a un argomento.It is possible to register multiple subscriptions to a topic. Quando un messaggio viene inviato a un argomento, viene reso disponibile affinché ogni sottoscrizione possa gestirlo o elaborarlo in modo indipendente.When a message is sent to a topic, it is then made available to each subscription to handle/process independently.

La sottoscrizione a un argomento è simile a una coda virtuale che riceve copie dei messaggi che sono stati inviati all'argomento.A subscription to a topic resembles a virtual queue that receives copies of the messages that were sent to the topic. È possibile registrare regole di filtro per un argomento in base alla sottoscrizione, per poter filtrare o limitare quali messaggi relativi a un argomento vengono ricevuti dalle diverse sottoscrizioni dell'argomento.You can optionally register filter rules for a topic on a per-subscription basis, which enables you to filter or restrict which messages to a topic are received by which topic subscriptions.

Gli argomenti e le sottoscrizioni del bus di servizio consentono la scalabilità e l'elaborazione di grandi quantità di messaggi tra un numero elevato di utenti e applicazioni.Service Bus topics and subscriptions enable you to scale and process a very large number of messages across many users and applications.

Creare uno spazio dei nomiCreate a namespace

Per iniziare a usare gli argomenti e le sottoscrizioni del bus di servizio in Azure, è necessario creare prima di tutto uno spazio dei nomi del servizio.To begin using Service Bus topics and subscriptions in Azure, you must first create a service namespace. Uno spazio dei nomi fornisce un contenitore di ambito per fare riferimento alle risorse del bus di servizio all'interno dell'applicazione.A namespace provides a scoping container for addressing Service Bus resources within your application.

Per creare uno spazio dei nomi:To create a namespace:

  1. Accedere al portale di Azure.Log on to the Azure portal.
  2. Nel riquadro di spostamento sinistro del portale fare clic su Nuovo, quindi su Enterprise Integration e infine su Bus di servizio.In the left navigation pane of the portal, click New, then click Enterprise Integration, and then click Service Bus.
  3. Nella finestra di dialogo Crea spazio dei nomi immettere un nome per lo spazio dei nomi.In the Create namespace dialog, enter a namespace name. Verrà effettuato immediatamente un controllo sulla disponibilità del nome.The system immediately checks to see if the name is available.
  4. Dopo aver verificato che il nome dello spazio dei nomi sia disponibile, scegliere il piano tariffario, ovvero Basic, Standard o Premium.After making sure the namespace name is available, choose the pricing tier (Basic, Standard, or Premium).
  5. Nel campo Sottoscrizione scegliere una sottoscrizione di Azure in cui creare lo spazio dei nomi.In the Subscription field, choose an Azure subscription in which to create the namespace.
  6. Nel campo Gruppo di risorse scegliere un gruppo di risorse esistente nel quale risiederà lo spazio dei nomi oppure crearne uno nuovo.In the Resource group field, choose an existing resource group in which the namespace will live, or create a new one.
  7. In Localitàscegliere il paese o l'area in cui deve essere ospitato lo spazio dei nomi.In Location, choose the country or region in which your namespace should be hosted.

    Crea spazio dei nomi

  8. Selezionare il pulsante Create .Click the Create button. A questo punto, lo spazio dei nomi verrà creato e abilitato nel sistema.The system now creates your namespace and enables it. Potrebbero essere necessari alcuni minuti per consentire al sistema di effettuare il provisioning delle risorse per lo spazio dei nomi creato.You might have to wait several minutes as the system provisions resources for your account.

Ottenere le credenzialiObtain the credentials

  1. Nell'elenco degli spazi dei nomi fare clic sul nome dello spazio dei nomi appena creato.In the list of namespaces, click the newly created namespace name.
  2. Nel pannello Spazio dei nomi del bus di servizio fare clic su Criteri di accesso condiviso.In the Service Bus namespace blade, click Shared access policies.
  3. Nel pannello Criteri di accesso condivisi fare clic su RootManageSharedAccessKey.In the Shared access policies blade, click RootManageSharedAccessKey.

    connection-info

  4. Nel pannello Criteri: RootManageSharedAccessKey fare clic sul pulsante Copia accanto a Stringa di connessione - chiave primaria per copiare la stringa di connessione negli Appunti e usarla in un secondo momento.In the Policy: RootManageSharedAccessKey blade, click the copy button next to Connection string–primary key, to copy the connection string to your clipboard for later use.

    connection-string

Nota

Se è necessario installare Python o il pacchetto Azure per Python, vedere la guida all'installazione di Python.If you need to install Python or the Azure Python package, see the Python Installation Guide.

Creare un argomentoCreate a topic

L'oggetto ServiceBusService consente di usare gli argomenti.The ServiceBusService object enables you to work with topics. Aggiungere il seguente codice vicino all'inizio del file Python da cui si desidera accedere al bus di servizio a livello di codice:Add the following near the top of any Python file in which you wish to programmatically access Service Bus:

from azure.servicebus import ServiceBusService, Message, Topic, Rule, DEFAULT_RULE_NAME

Il codice seguente consente di creare un oggetto ServiceBusService.The following code creates a ServiceBusService object. Sostituire mynamespace, sharedaccesskeyname e sharedaccesskey con lo spazio dei nomi effettivo e il nome e il valore della chiave di firma di accesso condiviso.Replace mynamespace, sharedaccesskeyname, and sharedaccesskey with your actual namespace, Shared Access Signature (SAS) key name, and key value.

bus_service = ServiceBusService(
    service_namespace='mynamespace',
    shared_access_key_name='sharedaccesskeyname',
    shared_access_key_value='sharedaccesskey')

È possibile ottenere i valori per il nome e il valore della chiave di firma di accesso condiviso nel portale di Azure.You can obtain the values for the SAS key name and value from the Azure portal.

bus_service.create_topic('mytopic')

Il metodo create_topic supporta anche opzioni aggiuntive che consentono di eseguire l'override delle impostazioni predefinite degli argomenti, come la durata (TTL) dei messaggi o le dimensioni massime dell'argomento.The create_topic method also supports additional options, which enable you to override default topic settings such as message time to live or maximum topic size. L'esempio seguente illustra come impostare la dimensione massima dell'argomento su 5 GB e un valore della durata di 1 minuto:The following example sets the maximum topic size to 5 GB, and a time to live (TTL) value of 1 minute:

topic_options = Topic()
topic_options.max_size_in_megabytes = '5120'
topic_options.default_message_time_to_live = 'PT1M'

bus_service.create_topic('mytopic', topic_options)

Creare sottoscrizioniCreate subscriptions

È possibile creare sottoscrizioni ad argomenti anche con l'oggetto ServiceBusService.Subscriptions to topics are also created with the ServiceBusService object. Le sottoscrizioni sono denominate e possono includere un filtro facoltativo che limita il set di messaggi recapitati alla coda virtuale della sottoscrizione.Subscriptions are named and can have an optional filter that restricts the set of messages delivered to the subscription's virtual queue.

Nota

Le sottoscrizioni sono persistenti e continueranno a esistere fintanto che esse o l'argomento che hanno sottoscritto non viene eliminato.Subscriptions are persistent and will continue to exist until either they, or the topic to which they are subscribed, are deleted.

Creare una sottoscrizione con il filtro (MatchAll) predefinitoCreate a subscription with the default (MatchAll) filter

Il filtro MatchAll è il filtro predefinito e viene usato se non vengono specificati altri filtri durante la creazione di una nuova sottoscrizione.The MatchAll filter is the default filter that is used if no filter is specified when a new subscription is created. Quando si usa il filtro MatchAll, tutti i messaggi pubblicati nell'argomento vengono inseriti nella coda virtuale della sottoscrizione.When the MatchAll filter is used, all messages published to the topic are placed in the subscription's virtual queue. L'esempio seguente crea una sottoscrizione denominata AllMessages e usa il filtro MatchAll predefinito.The following example creates a subscription named AllMessages and uses the default MatchAll filter.

bus_service.create_subscription('mytopic', 'AllMessages')

Creare sottoscrizioni con i filtriCreate subscriptions with filters

È anche possibile definire i filtri che consentono di specificare quali messaggi inviati a un argomento devono essere presenti in una specifica sottoscrizione dell'argomento.You can also define filters that enable you to specify which messages sent to a topic should show up within a specific topic subscription.

Il tipo di filtro più flessibile tra quelli supportati dalle sottoscrizioni è SqlFilter, che implementa un subset di SQL92.The most flexible type of filter supported by subscriptions is a SqlFilter, which implements a subset of SQL92. I filtri SQL agiscono sulle proprietà dei messaggi pubblicati nell'argomento.SQL filters operate on the properties of the messages that are published to the topic. Per altre informazioni sulle espressioni che possono essere usate con un filtro SQL, vedere la sintassi di SqlFilter.SqlExpression.For more information about the expressions that can be used with a SQL filter, see the SqlFilter.SqlExpression syntax.

È possibile aggiungere filtri a una sottoscrizione usando il metodo create_rule dell'oggetto ServiceBusService.You can add filters to a subscription by using the create_rule method of the ServiceBusService object. Questo metodo consente di aggiungere nuovi filtri a una sottoscrizione esistente.This method allows you to add new filters to an existing subscription.

Nota

Poiché il filtro predefinito viene applicato automaticamente a tutte le nuove sottoscrizioni, è necessario prima di tutto rimuovere il filtro predefinito, altrimenti MatchAll eseguirà l'override di qualsiasi altro filtro specificato.Because the default filter is applied automatically to all new subscriptions, you must first remove the default filter or the MatchAll will override any other filters you may specify. È possibile rimuovere la regola predefinita con il metodo delete_rule dell'oggetto ServiceBusService.You can remove the default rule by using the delete_rule method of the ServiceBusService object.

L'esempio seguente crea una sottoscrizione denominata HighMessages con un filtro SqlFilter che seleziona solo i messaggi che hanno una proprietà messagenumber personalizzata con valore maggiore di 3:The following example creates a subscription named HighMessages with a SqlFilter that only selects messages that have a custom messagenumber property greater than 3:

bus_service.create_subscription('mytopic', 'HighMessages')

rule = Rule()
rule.filter_type = 'SqlFilter'
rule.filter_expression = 'messagenumber > 3'

bus_service.create_rule('mytopic', 'HighMessages', 'HighMessageFilter', rule)
bus_service.delete_rule('mytopic', 'HighMessages', DEFAULT_RULE_NAME)

Analogamente, l'esempio seguente crea una sottoscrizione denominata LowMessages con un filtro SqlFilter che seleziona solo i messaggi che hanno una proprietà messagenumber con valore minore o uguale a 3:Similarly, the following example creates a subscription named LowMessages with a SqlFilter that only selects messages that have a messagenumber property less than or equal to 3:

bus_service.create_subscription('mytopic', 'LowMessages')

rule = Rule()
rule.filter_type = 'SqlFilter'
rule.filter_expression = 'messagenumber <= 3'

bus_service.create_rule('mytopic', 'LowMessages', 'LowMessageFilter', rule)
bus_service.delete_rule('mytopic', 'LowMessages', DEFAULT_RULE_NAME)

Di conseguenza, quando un messaggio viene inviato a mytopic, viene sempre recapitato ai ricevitori aderenti alla sottoscrizione dell'argomento AllMessages e viene recapitato selettivamente ai ricevitori aderenti alle sottoscrizioni dell'argomento HighMessages e LowMessages, a seconda del contenuto del messaggio.Now, when a message is sent to mytopic it is always delivered to receivers subscribed to the AllMessages topic subscription, and selectively delivered to receivers subscribed to the HighMessages and LowMessages topic subscriptions (depending on the message content).

Inviare messaggi a un argomentoSend messages to a topic

Per inviare un messaggio a un argomento del bus di servizio, l'applicazione deve usare il metodo send_topic_message dell'oggetto ServiceBusService.To send a message to a Service Bus topic, your application must use the send_topic_message method of the ServiceBusService object.

Il seguente esempio illustra come inviare cinque messaggi di test a mytopic.The following example demonstrates how to send five test messages to mytopic. Si noti che il valore della proprietà messagenumber di ogni messaggio varia nell'iterazione del ciclo, determinando quali sottoscrizioni lo ricevono:Note that the messagenumber property value of each message varies on the iteration of the loop (this determines which subscriptions receive it):

for i in range(5):
    msg = Message('Msg {0}'.format(i).encode('utf-8'), custom_properties={'messagenumber':i})
    bus_service.send_topic_message('mytopic', msg)

Gli argomenti del bus di servizio supportano messaggi di dimensioni massime fino a 256 KB nel livello Standard e fino a 1 MB nel livello Premium.Service Bus topics support a maximum message size of 256 KB in the Standard tier and 1 MB in the Premium tier. Le dimensioni massime dell'intestazione, che include le proprietà standard e personalizzate dell'applicazione, non possono superare 64 KB.The header, which includes the standard and custom application properties, can have a maximum size of 64 KB. Non esiste alcun limite al numero di messaggi mantenuti in un argomento, mentre è prevista una limitazione alla dimensione totale dei messaggi di un argomento.There is no limit on the number of messages held in a topic but there is a cap on the total size of the messages held by a topic. Questa dimensione dell'argomento viene definita al momento della creazione, con un limite massimo di 5 GB.This topic size is defined at creation time, with an upper limit of 5 GB. Per altre informazioni sulle quote, vedere Quote del bus di servizio.For more information about quotas, see Service Bus quotas.

Ricevere messaggi da una sottoscrizioneReceive messages from a subscription

I messaggi vengono ricevuti da una sottoscrizione usando il metodo receive_subscription_message nell'oggetto ServiceBusService:Messages are received from a subscription using the receive_subscription_message method on the ServiceBusService object:

msg = bus_service.receive_subscription_message('mytopic', 'LowMessages', peek_lock=False)
print(msg.body)

I messaggi vengono eliminati dalla sottoscrizione non appena vengono letti quando il parametro peek_lock è impostato su False.Messages are deleted from the subscription as they are read when the parameter peek_lock is set to False. È possibile leggere e bloccare il messaggio senza eliminarlo dalla coda impostando il parametro peek_lock su True.You can read (peek) and lock the message without deleting it from the queue by setting the parameter peek_lock to True.

Il comportamento di lettura ed eliminazione del messaggio nell'ambito dell'operazione di ricezione costituisce il modello più semplice ed è adatto per scenari in cui un'applicazione può tollerare la mancata elaborazione di un messaggio in caso di errore.The behavior of reading and deleting the message as part of the receive operation is the simplest model, and works best for scenarios in which an application can tolerate not processing a message in the event of a failure. Per comprendere meglio questo meccanismo, si consideri uno scenario in cui il consumer invia la richiesta di ricezione e viene arrestato in modo anomalo prima dell'elaborazione.To understand this, consider a scenario in which the consumer issues the receive request and then crashes before processing it. Poiché il bus di servizio contrassegna il messaggio come utilizzato, quando l'applicazione viene riavviata e inizia a utilizzare nuovamente i messaggi, il messaggio utilizzato prima dell'arresto anomalo risulterà perso.Because Service Bus will have marked the message as being consumed, then when the application restarts and begins consuming messages again, it will have missed the message that was consumed prior to the crash.

Se il parametro peek_lock è impostato su True, l'operazione di ricezione viene suddivisa in due fasi, in modo da consentire il supporto di applicazioni che non possono tollerare messaggi mancanti.If the peek_lock parameter is set to True, the receive becomes a two stage operation, which makes it possible to support applications that cannot tolerate missing messages. Quando il bus di servizio riceve una richiesta, individua il messaggio successivo da usare, lo blocca per impedirne la ricezione da parte di altri consumer e quindi lo restituisce all'applicazione.When Service Bus receives a request, it finds the next message to be consumed, locks it to prevent other consumers receiving it, and then returns it to the application. Dopo aver elaborato il messaggio o averlo archiviato in modo affidabile per una successiva elaborazione, l'applicazione esegue la seconda fase del processo di ricezione chiamando il metodo delete nell'oggetto Message.After the application finishes processing the message (or stores it reliably for future processing), it completes the second stage of the receive process by calling delete method on the Message object. Il metodo delete contrassegna il messaggio come utilizzato e lo rimuove dalla sottoscrizione.The delete method marks the message as being consumed and removes it from the subscription.

msg = bus_service.receive_subscription_message('mytopic', 'LowMessages', peek_lock=True)
print(msg.body)

msg.delete()

Come gestire arresti anomali e messaggi illeggibili dell'applicazioneHow to handle application crashes and unreadable messages

Il bus di servizio fornisce funzionalità per il ripristino gestito automaticamente in caso di errori nell'applicazione o di problemi di elaborazione di un messaggio.Service Bus provides functionality to help you gracefully recover from errors in your application or difficulties processing a message. Se un'applicazione ricevente non riesce a elaborare il messaggio per qualsiasi motivo, può chiamare il metodo unlock nell'oggetto Message.If a receiver application is unable to process the message for some reason, then it can call the unlock method on the Message object. In questo modo, il bus di servizio sbloccherà il messaggio nella sottoscrizione rendendolo nuovamente disponibile per la ricezione da parte della stessa applicazione consumer o da un'altra.This will cause Service Bus to unlock the message within the subscription and make it available to be received again, either by the same consuming application or by another consuming application.

Al messaggio bloccato nella sottoscrizione è anche associato un timeout. Se l'applicazione non riesce a elaborare il messaggio prima della scadenza del timeout, ad esempio a causa di un arresto anomalo, il bus di servizio sbloccherà automaticamente il messaggio rendendolo nuovamente disponibile per la ricezione.There is also a timeout associated with a message locked within the subscription, and if the application fails to process the message before the lock timeout expires (for example, if the application crashes), then Service Bus unlocks the message automatically and makes it available to be received again.

In caso di arresto anomalo dell'applicazione dopo l'elaborazione del messaggio ma prima della chiamata del metodo delete, il messaggio verrà nuovamente recapitato all'applicazione al riavvio.In the event that the application crashes after processing the message but before the delete method is called, then the message will be redelivered to the application when it restarts. Questo processo di elaborazione viene spesso definito di tipo At-Least-Once, per indicare che ogni messaggio verrà elaborato almeno una volta ma che in determinate situazioni potrà essere recapitato una seconda volta.This is often called At Least Once Processing, that is, each message will be processed at least once but in certain situations the same message may be redelivered. Se lo scenario non tollera la doppia elaborazione, gli sviluppatori dovranno aggiungere logica aggiuntiva all'applicazione per gestire il secondo recapito del messaggio.If the scenario cannot tolerate duplicate processing, then application developers should add additional logic to their application to handle duplicate message delivery. A tale scopo viene spesso usata la proprietà MessageId del messaggio, che rimane costante in tutti i tentativi di recapito.This is often achieved using the MessageId property of the message, which will remain constant across delivery attempts.

Eliminare argomenti e sottoscrizioniDelete topics and subscriptions

Gli argomenti e le sottoscrizioni sono persistenti e devono essere eliminati in modo esplicito nel portale di Azure oppure a livello di codice.Topics and subscriptions are persistent, and must be explicitly deleted either through the Azure portal or programmatically. L'esempio seguente illustra come eliminare l'argomento denominato mytopic:The following example shows how to delete the topic named mytopic:

bus_service.delete_topic('mytopic')

Se si elimina un argomento, vengono eliminate anche tutte le sottoscrizioni registrate con l'argomento.Deleting a topic also deletes any subscriptions that are registered with the topic. Le sottoscrizioni possono essere eliminate anche in modo indipendente.Subscriptions can also be deleted independently. Il codice seguente illustra come eliminare una sottoscrizione denominata HighMessages dall'argomento mytopic:The following code shows how to delete a subscription named HighMessages from the mytopic topic:

bus_service.delete_subscription('mytopic', 'HighMessages')

Passaggi successiviNext steps

A questo punto, dopo aver appreso le nozioni di base degli argomenti del bus di servizio, usare i seguenti collegamenti per altre informazioni.Now that you've learned the basics of Service Bus topics, follow these links to learn more.