Come usare gli argomenti e le sottoscrizioni del bus di servizio

Questa guida descrive come usare gli argomenti e le sottoscrizioni del bus di servizio da applicazioni Node.js. 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 su argomenti e 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

Creare un'applicazione Node.js

Creare un'applicazione Node.js vuota. Per istruzioni sulla creazione di un'applicazione Node.js, vedere Creare un'app Web Node.js nel servizio app di Azure oppure Creazione e distribuzione di un'applicazione Node.js a un servizio cloud di Azure con Windows PowerShell o Sito Web con WebMatrix.

Configurare l'applicazione per l'uso del bus di servizio

Per usare il bus di servizio, scaricare il pacchetto Azure Node.js, che include un set di librerie di riferimento che comunicano con i servizi REST del bus di servizio.

Usare Node Package Manager (NPM) per ottenere il pacchetto

  1. Usare un'interfaccia della riga di comando come PowerShell (Windows,) Terminal (Mac,) o Bash (Unix) e spostarsi nella cartella in cui è stata creata l'applicazione di esempio.
  2. Digitare npm install azure nella finestra di comando, che dovrebbe restituire l'output seguente:

        azure@0.7.5 node_modules\azure
    ├── dateformat@1.0.2-1.2.3
    ├── xmlbuilder@0.4.2
    ├── node-uuid@1.2.0
    ├── mime@1.2.9
    ├── underscore@1.4.4
    ├── validator@1.1.1
    ├── tunnel@0.0.2
    ├── wns@0.5.3
    ├── xml2js@0.2.7 (sax@0.5.2)
    └── request@2.21.0 (json-stringify-safe@4.0.0, forever-agent@0.5.0, aws-sign@0.3.0, tunnel-agent@0.3.0, oauth-sign@0.3.0, qs@0.6.5, cookie-jar@0.3.0, node-uuid@1.4.0, http-signature@0.9.11, form-data@0.0.8, hawk@0.13.1)
    
  3. È possibile eseguire manualmente il comando ls per verificare che sia stata creata una cartella node_modules. In tale cartella trovare il pacchetto azure, che contiene le librerie necessarie per accedere agli argomenti del bus di servizio.

Importare il modulo

Usando il Blocco note o un altro editor di testo, aggiungere quanto segue alla parte superiore del file server.js dell'applicazione:

var azure = require('azure');

Configurare una stringa di connessione per il bus di servizio

Il modulo di Azure legge le variabili di ambiente AZURE_SERVICEBUS_NAMESPACE and AZURE_SERVICEBUS_ACCESS_KEY per informazioni necessarie per la connessione al bus di servizio. Se queste variabili di ambiente non sono impostate, è necessario specificare le informazioni relative all'account quando si chiama createServiceBusService.

Per un esempio di impostazione delle variabili di ambiente per un servizio cloud di Azure, vedere Servizio cloud Node.js con Archiviazione.

Per un esempio di impostazione delle variabili di ambiente per un sito Web di Azure, vedere Creazione di un'applicazione Web Node.js con Archiviazione.

Creare un argomento

L'oggetto ServiceBusService consente di usare gli argomenti. Il codice seguente consente di creare un oggetto ServiceBusService. Aggiungerlo nella parte superiore del file server.js dopo l'istruzione per l'importazione del modulo azure:

var serviceBusService = azure.createServiceBusService();

Quando si esegue la chiamata di createTopicIfNotExists nell'oggetto ServiceBusService, viene restituito l'argomento specificato, se esiste, o viene creato un nuovo argomento con il nome specificato. Il codice seguente usa createTopicIfNotExists per creare o connettersi all'argomento denominato 'MyTopic':

serviceBusService.createTopicIfNotExists('MyTopic',function(error){
    if(!error){
        // Topic was created or exists
        console.log('topic created or exists.');
    }
});

createServiceBusService supporta anche opzioni aggiuntive che consentono di eseguire l'override delle impostazioni degli argomenti predefinite, ad esempio la durata dei messaggi o la dimensione massima dell'argomento. L'esempio seguente illustra come impostare la dimensione massima dell'argomento su 5 GB con una durata di 1 minuto:

var topicOptions = {
        MaxSizeInMegabytes: '5120',
        DefaultMessageTimeToLive: 'PT1M'
    };

serviceBusService.createTopicIfNotExists('MyTopic', topicOptions, function(error){
    if(!error){
        // topic was created or exists
    }
});

Filtri

Le operazioni di filtro facoltative possono essere applicate alle operazioni eseguite usando ServiceBusService. Le operazioni di filtro possono includere la registrazione, la ripetizione automatica dei tentativi e così via. I filtri sono oggetti che implementano un metodo con la firma:

function handle (requestOptions, next)

Dopo aver eseguito la pre-elaborazione sulle opzioni della richiesta, il metodo chiama next passando un callback con la firma seguente:

function (returnObject, finalCallback, next)

In questo callback, e dopo l'elaborazione di returnObject, ossia la risposta della richiesta al server, il callback deve richiamare "next", se questo esiste, per continuare a elaborare altri filtri oppure semplicemente richiamare finalCallback per concludere la chiamata al servizio.

In Azure SDK per Node.js sono inclusi due filtri che implementano la logica di ripetizione dei tentativi. Sono ExponentialRetryPolicyFilter e LinearRetryPolicyFilter. Il codice seguente consente di creare un oggetto ServiceBusService che usa ExponentialRetryPolicyFilter:

var retryOperations = new azure.ExponentialRetryPolicyFilter();
var serviceBusService = azure.createServiceBusService().withFilter(retryOperations);

Creare sottoscrizioni

È possibile creare le sottoscrizioni di un argomento 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 a cui sono associate, non vengono eliminate. Se l'applicazione contiene la logica per la creazione di una sottoscrizione, è prima necessario verificare se la sottoscrizione esiste già usando il metodo getSubscription.

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. Nell'esempio seguente viene creata una sottoscrizione denominata "AllMessages" e viene usato il filtro predefinito MatchAll.

serviceBusService.createSubscription('MyTopic','AllMessages',function(error){
    if(!error){
        // subscription created
    }
});

Creare sottoscrizioni con i filtri

È anche possibile creare filtri che consentono di definire l'ambito dei messaggi inviati a un argomento che devono essere visualizzati 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 altri dettagli sulle espressioni che è possibile usare con un filtro SQL, esaminare la sintassi di SqlFilter.SqlExpression.

È possibile aggiungere filtri a una sottoscrizione usando il metodo createRule 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 tramite il metodo deleteRule dell'oggetto ServiceBusService.

L'esempio seguente crea una sottoscrizione denominata HighMessages con un filtro SqlFilter che seleziona solo i messaggi in cui il valore della proprietà personalizzata messagenumber è maggiore di 3:

serviceBusService.createSubscription('MyTopic', 'HighMessages', function (error){
    if(!error){
        // subscription created
        rule.create();
    }
});
var rule={
    deleteDefault: function(){
        serviceBusService.deleteRule('MyTopic',
            'HighMessages',
            azure.Constants.ServiceBusConstants.DEFAULT_RULE_NAME,
            rule.handleError);
    },
    create: function(){
        var ruleOptions = {
            sqlExpressionFilter: 'messagenumber > 3'
        };
        rule.deleteDefault();
        serviceBusService.createRule('MyTopic',
            'HighMessages',
            'HighMessageFilter',
            ruleOptions,
            rule.handleError);
    },
    handleError: function(error){
        if(error){
            console.log(error)
        }
    }
}

Analogamente, l'esempio seguente crea una sottoscrizione denominata LowMessages con un filtro SqlFilter che seleziona solo i messaggi in cui il valore della proprietà messagenumber è minore o uguale a 3:

serviceBusService.createSubscription('MyTopic', 'LowMessages', function (error){
    if(!error){
        // subscription created
        rule.create();
    }
});
var rule={
    deleteDefault: function(){
        serviceBusService.deleteRule('MyTopic',
            'LowMessages',
            azure.Constants.ServiceBusConstants.DEFAULT_RULE_NAME,
            rule.handleError);
    },
    create: function(){
        var ruleOptions = {
            sqlExpressionFilter: 'messagenumber <= 3'
        };
        rule.deleteDefault();
        serviceBusService.createRule('MyTopic',
            'LowMessages',
            'LowMessageFilter',
            ruleOptions,
            rule.handleError);
    },
    handleError: function(error){
        if(error){
            console.log(error)
        }
    }
}

Un messaggio inviato a MyTopic verrà sempre recapitato ai ricevitori con sottoscrizione all'argomento AllMessages e recapitato selettivamente ai ricevitori con sottoscrizioni agli argomenti HighMessages e LowMessages (a seconda del contenuto del messaggio).

Come inviare messaggi a un argomento

Per inviare un messaggio a un argomento del bus di servizio, l'applicazione deve usare il metodo sendTopicMessage dell'oggetto ServiceBusService. I messaggi inviati ad argomenti del bus di servizio sono oggetti BrokeredMessage. Gli oggetti BrokeredMessage includono un insieme di proprietà standard, ad esempio Label e TimeToLive, un dizionario usato per contenere le proprietà personalizzate specifiche dell'applicazione e un corpo di dati di tipo stringa. Un'applicazione può impostare il corpo del messaggio passando un valore stringa a sendTopicMessage in modo da popolare le proprietà standard necessarie con valori predefiniti.

Nell'esempio seguente viene illustrato come impostare cinque messaggi di test su 'MyTopic'. Si noti come il valore della proprietà messagenumber di ogni messaggio varia nell'iterazione del ciclo, determinando le sottoscrizioni che lo riceveranno:

var message = {
    body: '',
    customProperties: {
        messagenumber: 0
    }
}

for (i = 0;i < 5;i++) {
    message.customProperties.messagenumber=i;
    message.body='This is Message #'+i;
    serviceBusService.sendTopicMessage(topic, message, function(error) {
      if (error) {
        console.log(error);
      }
    });
}

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.

Ricevere messaggi da una sottoscrizione

I messaggi vengono ricevuti da una sottoscrizione usando il metodo receiveSubscriptionMessage per l'oggetto ServiceBusService. Per impostazione predefinita, i messaggi vengono eliminati dalla sottoscrizione non appena vengono letti. È tuttavia possibile leggere (visualizzarne l'anteprima) e bloccare il messaggio senza eliminarlo dalla sottoscrizione, impostando il parametro facoltativo isPeekLock su true.

Il comportamento predefinito 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 isPeekLock è 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 deleteMessage e specificando il messaggio da eliminare come parametro. Il metodo deleteMessage contrassegna il messaggio come usato e lo rimuove dalla sottoscrizione.

L'esempio seguente illustra come ricevere ed elaborare messaggi usando receiveSubscriptionMessage. L'esempio prima riceve ed elimina un messaggio dalla sottoscrizione "LowMessages" e può riceve un messaggio dalla sottoscrizione "HighMessages" con isPeekLock impostato su true. Il messaggio viene quindi eliminato usando il metodo deleteMessage:

serviceBusService.receiveSubscriptionMessage('MyTopic', 'LowMessages', function(error, receivedMessage){
    if(!error){
        // Message received and deleted
        console.log(receivedMessage);
    }
});
serviceBusService.receiveSubscriptionMessage('MyTopic', 'HighMessages', { isPeekLock: true }, function(error, lockedMessage){
    if(!error){
        // Message received and locked
        console.log(lockedMessage);
        serviceBusService.deleteMessage(lockedMessage, function (deleteError){
            if(!deleteError){
                // Message deleted
                console.log('message has been deleted.');
            }
        }
    }
});

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 ricevitore non riesce a elaborare il messaggio per un qualsiasi motivo, può chiamare il metodo unlockMessage nell'oggetto ServiceBusService. 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 deleteMessage, 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:

serviceBusService.deleteTopic('MyTopic', function (error) {
    if (error) {
        console.log(error);
    }
});

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

serviceBusService.deleteSubscription('MyTopic', 'HighMessages', function (error) {
    if(error) {
        console.log(error);
    }
});

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.