Come usare gli argomenti e le sottoscrizioni del bus di servizio con Python

Questo articolo descrive come usare gli argomenti e le sottoscrizioni del bus di servizio. Gli esempi sono scritti in Python e usano il pacchetto Azure SDK per Python. 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. Per altre informazioni sugli argomenti e sulle sottoscrizioni, vedere la sezione Passaggi successivi.

Cosa sono gli argomenti e le sottoscrizioni del bus di servizio?

Gli argomenti e le sottoscrizioni del bus di servizio supportano un modello di comunicazione con messaggistica di pubblicazione-sottoscrizione . 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.

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. È possibile registrare più sottoscrizioni a un argomento. Quando un messaggio viene inviato a un argomento, viene reso disponibile affinché ogni sottoscrizione possa gestirlo o elaborarlo in modo indipendente.

La sottoscrizione a un argomento è simile a una coda virtuale che riceve copie dei messaggi che sono stati inviati all'argomento. È 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.

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.

Creare uno spazio dei nomi

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. Uno spazio dei nomi fornisce un contenitore di ambito per fare riferimento alle risorse del bus di servizio all'interno dell'applicazione.

Per creare uno spazio dei nomi:

  1. Accedere al portale di Azure.
  2. Nel riquadro di spostamento sinistro del portale fare clic su Nuovo, quindi su Enterprise Integration e infine su Bus di servizio.
  3. Nella finestra di dialogo Crea spazio dei nomi immettere un nome per lo spazio dei nomi. Verrà effettuato immediatamente un controllo sulla disponibilità del nome.
  4. Dopo aver verificato che il nome dello spazio dei nomi sia disponibile, scegliere il piano tariffario, ovvero Basic, Standard o Premium.
  5. Nel campo Sottoscrizione scegliere una sottoscrizione di Azure in cui creare lo spazio dei nomi.
  6. Nel campo Gruppo di risorse scegliere un gruppo di risorse esistente nel quale risiederà lo spazio dei nomi oppure crearne uno nuovo.
  7. In Localitàscegliere il paese o l'area in cui deve essere ospitato lo spazio dei nomi.

    Crea spazio dei nomi

  8. Selezionare il pulsante Create . A questo punto, lo spazio dei nomi verrà creato e abilitato nel sistema. Potrebbero essere necessari alcuni minuti per consentire al sistema di effettuare il provisioning delle risorse per lo spazio dei nomi creato.

Ottenere le credenziali

  1. Nell'elenco degli spazi dei nomi fare clic sul nome dello spazio dei nomi appena creato.
  2. Nel pannello Spazio dei nomi del bus di servizio fare clic su Criteri di accesso condiviso.
  3. Nel pannello Criteri di accesso condivisi fare clic su 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.

    connection-string

Nota

Se è necessario installare Python o il pacchetto Azure per Python, vedere la guida all'installazione di Python.

Creare un argomento

L'oggetto ServiceBusService consente di usare gli argomenti. Aggiungere il seguente codice vicino all'inizio del file Python da cui si desidera accedere al bus di servizio a livello di codice:

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

Il codice seguente consente di creare un oggetto ServiceBusService. Sostituire mynamespace, sharedaccesskeyname e sharedaccesskey con lo spazio dei nomi effettivo e il nome e il valore della chiave di firma di accesso condiviso.

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.

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. L'esempio seguente illustra come impostare la dimensione massima dell'argomento su 5 GB e un valore della durata di 1 minuto:

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 sottoscrizioni

È possibile creare sottoscrizioni ad argomenti anche con l'oggetto ServiceBusService. Le sottoscrizioni sono denominate e possono includere un filtro facoltativo che limita il set di messaggi recapitati alla coda virtuale della sottoscrizione.

Nota

Le sottoscrizioni sono persistenti e continueranno a esistere fintanto che esse o l'argomento che hanno sottoscritto non viene eliminato.

Creare una sottoscrizione con il filtro (MatchAll) predefinito

Il filtro MatchAll è il filtro predefinito e viene usato se non vengono specificati altri filtri durante la creazione di una nuova sottoscrizione. Quando si usa il filtro MatchAll, tutti i messaggi pubblicati nell'argomento vengono inseriti nella coda virtuale della sottoscrizione. L'esempio seguente crea una sottoscrizione denominata AllMessages e usa il filtro MatchAll predefinito.

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

Creare sottoscrizioni con i filtri

È anche possibile definire i filtri che consentono di specificare quali messaggi inviati a un argomento devono essere presenti in una specifica sottoscrizione dell'argomento.

Il tipo di filtro più flessibile tra quelli supportati dalle sottoscrizioni è SqlFilter, che implementa un subset di SQL92. I filtri SQL agiscono sulle proprietà dei messaggi pubblicati nell'argomento. Per altre informazioni sulle espressioni che possono essere usate con un filtro SQL, vedere la sintassi di SqlFilter.SqlExpression.

È possibile aggiungere filtri a una sottoscrizione usando il metodo create_rule dell'oggetto ServiceBusService. Questo metodo consente di aggiungere nuovi filtri a una sottoscrizione esistente.

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. È possibile rimuovere la regola predefinita con il metodo delete_rule dell'oggetto ServiceBusService.

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:

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:

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.

Inviare messaggi a un argomento

Per inviare un messaggio a un argomento del bus di servizio, l'applicazione deve usare il metodo send_topic_message dell'oggetto ServiceBusService.

Il seguente esempio illustra come inviare cinque messaggi di test a mytopic. Si noti che il valore della proprietà messagenumber di ogni messaggio varia nell'iterazione del ciclo, determinando quali sottoscrizioni lo ricevono:

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. Le dimensioni massime dell'intestazione, che include le proprietà standard e personalizzate dell'applicazione, non possono superare 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. Questa dimensione dell'argomento viene definita al momento della creazione, con un limite massimo di 5 GB. Per altre informazioni sulle quote, vedere Quote del bus di servizio.

Ricevere messaggi da una sottoscrizione

I messaggi vengono ricevuti da una sottoscrizione usando il metodo receive_subscription_message nell'oggetto ServiceBusService:

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. È possibile leggere e bloccare il messaggio senza eliminarlo dalla coda impostando il parametro peek_lock su 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. 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. 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.

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. 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. 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. Il metodo delete contrassegna il messaggio come utilizzato e lo rimuove dalla sottoscrizione.

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

msg.delete()

Come gestire arresti anomali e messaggi illeggibili dell'applicazione

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. Se un'applicazione ricevente non riesce a elaborare il messaggio per qualsiasi motivo, può chiamare il metodo unlock nell'oggetto Message. 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.

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.

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. 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. Se lo scenario non tollera la doppia elaborazione, gli sviluppatori dovranno aggiungere logica aggiuntiva all'applicazione per gestire il secondo recapito del messaggio. A tale scopo viene spesso usata la proprietà MessageId del messaggio, che rimane costante in tutti i tentativi di recapito.

Eliminare argomenti e sottoscrizioni

Gli argomenti e le sottoscrizioni sono persistenti e devono essere eliminati in modo esplicito nel portale di Azure oppure a livello di codice. L'esempio seguente illustra come eliminare l'argomento denominato mytopic:

bus_service.delete_topic('mytopic')

Se si elimina un argomento, vengono eliminate anche tutte le sottoscrizioni registrate con l'argomento. Le sottoscrizioni possono essere eliminate anche in modo indipendente. Il codice seguente illustra come eliminare una sottoscrizione denominata HighMessages dall'argomento mytopic:

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

Passaggi successivi

A questo punto, dopo aver appreso le nozioni di base degli argomenti del bus di servizio, usare i seguenti collegamenti per altre informazioni.