Applicazione .NET multilivello che usa code del bus di servizio

Introduzione

Microsoft Azure consente di sviluppare applicazioni con la stessa semplicità offerta da Visual Studio e Azure SDK gratuito per .NET. Questa esercitazione illustra i passaggi per creare un'applicazione che usa più risorse di Azure in esecuzione nell'ambiente locale.

Verranno illustrate le operazioni seguenti:

  • Abilitare il computer in uso per lo sviluppo per Azure tramite un singolo download e una singola installazione.
  • Utilizzare Visual Studio per lo sviluppo per Azure.
  • Creare un'applicazione multilivello in Azure utilizzando ruoli Web e ruoli di lavoro.
  • Consentire le comunicazioni tra i livelli usando le code del bus di servizio.

Nota

Per completare l'esercitazione, è necessario un account Azure. È possibile attivare i benefici della sottoscrizione MSDN o iscriversi per un account gratuito.

In questa esercitazione verrà creata ed eseguita un'applicazione multilivello in un servizio cloud di Azure. Il front-end è un ruolo Web ASP.NET MVC e il back-end è un ruolo di lavoro che usa una coda del bus di servizio. È possibile creare la stessa applicazione multilivello con il front-end come progetto Web distribuito in un sito Web di Azure invece che in un servizio cloud. È anche possibile vedere l'esercitazione sull'applicazione .NET ibrida locale/sul cloud.

Nella schermata seguente è illustrata l'applicazione completata.

Informazioni generali sullo scenario: comunicazione tra ruoli

Per inviare un ordine per l'elaborazione, è necessario che il componente dell'interfaccia utente front-end, in esecuzione nel ruolo Web, interagisca con la logica di livello intermedio in esecuzione nel ruolo di lavoro. Questo esempio usa la messaggistica del bus di servizio per la comunicazione tra i livelli.

L'uso della messaggistica del bus di servizio tra il livello Web e il livello intermedio consente di disaccoppiare i due componenti. Invece di usare la messaggistica diretta, ovvero TCP o HTTP, il livello Web non si connette direttamente al livello intermedio, ma inserisce unità di lavoro, ad esempio messaggi, nel bus di servizio, che li conserva in modo affidabile fino a quando il livello intermedio non sarà pronto per usarli ed elaborarli.

Il bus di servizio offre due entità per il supporto della messaggistica negoziata, ovvero le code e gli argomenti. Se si usano le code, ogni messaggio inviato alla coda viene usato da un ricevitore singolo. Gli argomenti supportano il modello pubblicazione/sottoscrizione, in cui ogni messaggio pubblicato viene reso disponibile a una sottoscrizione registrata per l'argomento. Ogni sottoscrizione mantiene in modo logico la propria coda di messaggi. È anche possibile configurare le sottoscrizioni specificando regole di filtro per limitare i set di messaggi passati alla coda della sottoscrizione ai soli messaggi corrispondenti al filtro. Nel seguente esempio vengono usate le code del bus di servizio.

Questo meccanismo di comunicazione presenta alcuni vantaggi rispetto alla messaggistica diretta:

  • Disaccoppiamento temporaneo. Grazie al modello di messaggistica asincrono, non è necessario che produttori e consumer siano online nello stesso momento. I messaggi vengono archiviati in modo affidabile nel bus di servizio fino a quando il consumer non sarà pronto per riceverli. Questo consente la disconnessione volontaria (ad esempio, per attività di manutenzione) o involontaria (a seguito di un guasto) dei componenti dell'applicazione distribuita senza ripercussioni sull'intero sistema. È inoltre possibile che l'applicazione consumer debba essere online solo in determinati orari.
  • Livellamento del carico. In molte applicazioni il carico del sistema varia in base al momento, mentre il tempo di elaborazione richiesto per ogni unità di lavoro è in genere costante. L'interposizione di una coda tra producer e consumer di messaggi implica che è necessario solo eseguire il provisioning dell'applicazione consumer (il ruolo di lavoro) per consentire a quest'ultima di gestire un carico medio anziché il carico massimo. In base alla variazione del carico in ingresso, si verificherà un incremento o una riduzione della profondità della coda, con un risparmio diretto in termini economici rispetto alle risorse infrastrutturali richieste per gestire il carico dell'applicazione.
  • Bilanciamento del carico. Con l'aumento del carico, è possibile aggiungere altri processi di lavoro per la lettura della coda. Ciascun messaggio viene elaborato da un solo processo di lavoro. Inoltre, il bilanciamento del carico di tipo pull consente un uso ottimale delle macchine di lavoro anche quando queste presentano una potenza di elaborazione diversa. Ogni macchina effettuerà infatti il pull dei messaggi alla propria velocità massima. Questo modello viene spesso definito modello del consumer concorrente.

Il codice che consente di implementare questa architettura viene illustrato nelle sezioni seguenti.

Configurare l'ambiente di sviluppo

Prima di iniziare a sviluppare applicazioni Azure, è necessario ottenere gli strumenti e configurare l'ambiente di sviluppo.

  1. Installare Azure SDK per .NET dalla pagina di download di SDK.
  2. Nella colonna .NET fare clic sulla versione di Visual Studio in uso. I passaggi di questa esercitazione usano Visual Studio 2015, ma funzionano anche con Visual Studio 2017.
  3. Quando viene richiesto se eseguire o salvare il file di installazione, fare clic su Esegui.
  4. Nell'Installazione guidata piattaforma Web fare clic su Installa e procedere con l'installazione.
  5. Al termine dell'installazione, saranno disponibili tutti gli strumenti necessari per avviare lo sviluppo dell’app. Nell'SDK sono disponibili gli strumenti che consentono di sviluppare con facilità applicazioni per Azure in Visual Studio.

Creare uno spazio dei nomi

Il passaggio successivo consiste nel creare uno spazio dei nomi del servizio e nell'ottenere una chiave di firma di accesso condiviso. Uno spazio dei nomi fornisce un limite per ogni applicazione esposta tramite il bus di servizio. Una chiave di firma di accesso condiviso viene generata dal sistema quando viene creato uno spazio dei nomi. La combinazione di spazio dei nomi e chiave di firma di accesso condiviso fornisce le credenziali che consentono al bus di servizio di autenticare l'accesso a un'applicazione.

Per iniziare a usare le entità di messaggistica del bus di servizio in Azure, prima di tutto è necessario creare uno spazio dei nomi con un nome univoco in Azure. 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. Fare clic su Crea. 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 di gestione

Con la creazione di un nuovo spazio dei nomi verrà generata automaticamente una regola di firma di accesso condiviso iniziale con una coppia di chiavi primaria e secondaria associata che concede il controllo completo di tutti gli aspetti dello spazio dei nomi. Vedere Autenticazione e autorizzazione del bus di servizio per informazioni su come creare altre regole con diritti più limitati per mittenti e destinatari normali. Per copiare la regola iniziale seguire questa procedura:

  1. Nell'elenco degli spazi dei nomi fare clic sul nome dello spazio dei nomi appena creato.
  2. Nel pannello dello spazio dei nomi fare clic su Criteri di accesso condivisi.
  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. Incollare questo valore nel Blocco note o in un'altra posizione temporanea.

    connection-string

  5. Ripetere il passaggio precedente e copiare e incollare il valore della chiave primaria in un percorso temporaneo per usarlo in seguito.

Creare un ruolo web

Creare in questa sezione il front-end dell'applicazione. Creare prima di tutto le pagine visualizzate dall'applicazione. Aggiungere quindi il codice per inviare elementi a una coda del bus di servizio e visualizzare informazioni relative allo stato della coda.

Creare il progetto

  1. Avviare Visual Studio con privilegi di amministratore: fare clic con il pulsante destro del mouse sull'icona del programma Visual Studio e quindi scegliere Esegui come amministratore. Per l'emulatore di calcolo di Azure, illustrato più avanti in questo articolo, è necessario che Visual Studio sia avviato con privilegi di amministratore.

    In Visual Studio scegliere Nuovo dal menu File, quindi fare clic su Progetto.

  2. Da Modelli installati in Visual C# fare clic su Cloud e quindi su Servizio cloud di Azure. Assegnare al progetto il nome MultiTierApp. Fare quindi clic su OK.

  3. Dai ruoli .NET Framework 4.5 fare doppio clic su Ruolo Web ASP.NET.

  4. Passare il puntatore su WebRole1 in Soluzione servizio cloud di Microsoft Azure, quindi fare clic sull'icona a forma di matita e rinominare il ruolo Web in FrontendWebRole. Fare quindi clic su OK. Assicurarsi di immettere "Frontend" con una 'e' minuscola, non "FrontEnd".

  5. Nella finestra di dialogo Nuovo progetto ASP.NET fare clic su MVC in Seleziona modello.

  6. Sempre nella finestra di dialogo Nuovo progetto ASP.NET fare clic sul pulsante Modifica autenticazione. Nella finestra di dialogo Modifica autenticazione fare clic su Nessuna autenticazione, quindi fare clic su OK. Per questa esercitazione si distribuisce un'applicazione che non richiede l'accesso utente.

  7. Nella finestra di dialogo Nuovo progetto ASP.NET fare clic su OK per creare il progetto.
  8. In Esplora soluzioni fare clic con il pulsante destro del mouse su Riferimenti nel progetto FrontendWebRole e quindi scegliere Gestisci pacchetti NuGet.
  9. Fare clic sulla scheda Sfoglia e quindi cercare Microsoft Azure Service Bus. Selezionare il pacchetto WindowsAzure.ServiceBus, fare clic su Installa e quindi accettare le condizioni per l'utilizzo.

    Sono ora disponibili riferimenti agli assembly client necessari e sono stati aggiunti nuovi file di codice.

  10. In Esplora soluzioni fare clic con il pulsante destro del mouse su Modelli, quindi scegliere Aggiungi e infine Classe. Nella casella Nome digitare il nome OnlineOrder.cs. Fare quindi clic su Aggiungi.

Scrivere il codice per il ruolo Web

Creare prima di tutto in questa sezione le diverse pagine visualizzate dall'applicazione.

  1. In Visual Studio, nel file OnlineOrder.cs sostituire la definizione dello spazio dei nomi esistente con il codice seguente:

    namespace FrontendWebRole.Models
    {
        public class OnlineOrder
        {
            public string Customer { get; set; }
            public string Product { get; set; }
        }
    }
    
  2. In Esplora soluzioni fare doppio clic su Controllers\HomeController.cs. Aggiungere le istruzioni using seguenti nella parte iniziale del file per includere gli spazi dei nomi per il modello appena creato, oltre al bus di servizio.

    using FrontendWebRole.Models;
    using Microsoft.ServiceBus.Messaging;
    using Microsoft.ServiceBus;
    
  3. Anche nel file HomeController.cs sostituire la definizione dello spazio dei nomi esistente con il seguente codice. Tale codice include metodi per la gestione dell'invio di elementi alla coda.

    namespace FrontendWebRole.Controllers
    {
        public class HomeController : Controller
        {
            public ActionResult Index()
            {
                // Simply redirect to Submit, since Submit will serve as the
                // front page of this application.
                return RedirectToAction("Submit");
            }
    
            public ActionResult About()
            {
                return View();
            }
    
            // GET: /Home/Submit.
            // Controller method for a view you will create for the submission
            // form.
            public ActionResult Submit()
            {
                // Will put code for displaying queue message count here.
    
                return View();
            }
    
            // POST: /Home/Submit.
            // Controller method for handling submissions from the submission
            // form.
            [HttpPost]
            // Attribute to help prevent cross-site scripting attacks and
            // cross-site request forgery.  
            [ValidateAntiForgeryToken]
            public ActionResult Submit(OnlineOrder order)
            {
                if (ModelState.IsValid)
                {
                    // Will put code for submitting to queue here.
    
                    return RedirectToAction("Submit");
                }
                else
                {
                    return View(order);
                }
            }
        }
    }
    
  4. Scegliere Compila soluzione dal menu Compila per verificare la correttezza del lavoro svolto finora.
  5. Creare quindi la visualizzazione per il metodo Submit() creato in precedenza. Fare clic con il pulsante destro del mouse all'interno del metodo Submit(), ovvero l'overload del metodo Submit() che non accetta parametri, e quindi scegliere Aggiungi visualizzazione.

  6. Viene visualizzata una finestra di dialogo per la creazione della visualizzazione. Nell'elenco Modello scegliere Crea. Nell'elenco Classe modello scegliere la classe OnlineOrder.

  7. Fare clic su Aggiungi.
  8. Modificare ora il nome visualizzato dell'applicazione. In Esplora soluzioni fare doppio clic sul file Views\Shared\_Layout.cshtml per aprirlo nell'editor di Visual Studio.
  9. Sostituire tutte le occorrenze di My ASP.NET Application con LITWARE'S Products.
  10. Rimuovere i collegamenti Home, About e Contact. Eliminare il codice evidenziato:

  11. Modificare infine la pagina di invio in modo da includere informazioni sulla coda. In Esplora soluzioni fare doppio clic sul file Views\Home\Submit.cshtml per aprirlo nell'editor di Visual Studio. Aggiungere la riga seguente dopo <h2>Submit</h2>. Per ora ViewBag.MessageCount non contiene valori. Il valore verrà inserito successivamente.

    <p>Current number of orders in queue waiting to be processed: @ViewBag.MessageCount</p>
    
  12. L'interfaccia utente è stata implementata. È possibile premere F5 per eseguire l'applicazione e confermare che abbia l'aspetto previsto.

Scrivere codice per l'invio di elementi a una coda del bus di servizio

Aggiungere quindi il codice per l'invio di elementi a una coda. Creare prima di tutto una classe contenente le informazioni di connessione della coda del bus di servizio. Inizializzare quindi la connessione da Global.aspx.cs. Aggiornare infine il codice di invio creato in precedenza in HomeController.cs in modo da inviare effettivamente elementi alla coda del bus di servizio.

  1. In Esplora soluzioni fare clic con il pulsante destro del mouse su FrontendWebRole. È necessario fare clic con il pulsante destro del mouse sul progetto, non sul ruolo. Fare clic su Aggiungi, quindi su Classe.
  2. Assegnare alla classe il nome QueueConnector.cs. Fare clic su Aggiungi per creare la classe.
  3. Aggiungere ora codice che incapsula le informazioni di connessione e inizializza la connessione a una coda del bus di servizio. Sostituire l'intero contenuto di QueueConnector.cs con il codice seguente e immettere i valori per your Service Bus namespace, ovvero il nome dello spazio dei nomi, e yourKey, ovvero la chiave primaria ottenuta in precedenza dal portale di Azure.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using Microsoft.ServiceBus.Messaging;
    using Microsoft.ServiceBus;
    
    namespace FrontendWebRole
    {
        public static class QueueConnector
        {
            // Thread-safe. Recommended that you cache rather than recreating it
            // on every request.
            public static QueueClient OrdersQueueClient;
    
            // Obtain these values from the portal.
            public const string Namespace = "your Service Bus namespace";
    
            // The name of your queue.
            public const string QueueName = "OrdersQueue";
    
            public static NamespaceManager CreateNamespaceManager()
            {
                // Create the namespace manager which gives you access to
                // management operations.
                var uri = ServiceBusEnvironment.CreateServiceUri(
                    "sb", Namespace, String.Empty);
                var tP = TokenProvider.CreateSharedAccessSignatureTokenProvider(
                    "RootManageSharedAccessKey", "yourKey");
                return new NamespaceManager(uri, tP);
            }
    
            public static void Initialize()
            {
                // Using Http to be friendly with outbound firewalls.
                ServiceBusEnvironment.SystemConnectivity.Mode =
                    ConnectivityMode.Http;
    
                // Create the namespace manager which gives you access to
                // management operations.
                var namespaceManager = CreateNamespaceManager();
    
                // Create the queue if it does not exist already.
                if (!namespaceManager.QueueExists(QueueName))
                {
                    namespaceManager.CreateQueue(QueueName);
                }
    
                // Get a client to the queue.
                var messagingFactory = MessagingFactory.Create(
                    namespaceManager.Address,
                    namespaceManager.Settings.TokenProvider);
                OrdersQueueClient = messagingFactory.CreateQueueClient(
                    "OrdersQueue");
            }
        }
    }
    
  4. Assicurarsi che venga chiamato il metodo Initialize. In Esplora soluzioni fare doppio clic su Global.asax\Global.asax.cs.
  5. Aggiungere la riga di codice seguente alla fine del metodo Application_Start.

    FrontendWebRole.QueueConnector.Initialize();
    
  6. Verrà infine aggiornato il codice Web creato in precedenza, in modo da inviare elementi alla coda. In Esplora soluzioni fare doppio clic su Controllers\HomeController.cs.
  7. Aggiornare il metodo Submit(), ovvero l'overload che non accetta parametri, come indicato di seguito per ottenere il numero di messaggi per la coda.

    public ActionResult Submit()
    {
        // Get a NamespaceManager which allows you to perform management and
        // diagnostic operations on your Service Bus queues.
        var namespaceManager = QueueConnector.CreateNamespaceManager();
    
        // Get the queue, and obtain the message count.
        var queue = namespaceManager.GetQueue(QueueConnector.QueueName);
        ViewBag.MessageCount = queue.MessageCount;
    
        return View();
    }
    
  8. Aggiornare il metodo Submit(OnlineOrder order), ovvero l'overload che accetta un parametro, come indicato di seguito per inviare alla coda le informazioni relative all'ordine.

    public ActionResult Submit(OnlineOrder order)
    {
        if (ModelState.IsValid)
        {
            // Create a message from the order.
            var message = new BrokeredMessage(order);
    
            // Submit the order.
            QueueConnector.OrdersQueueClient.Send(message);
            return RedirectToAction("Submit");
        }
        else
        {
            return View(order);
        }
    }
    
  9. È ora possibile eseguire di nuovo l'applicazione. Ogni volta che si invia un ordine, il conteggio dei messaggi aumenta.

Creare il ruolo di lavoro

Verrà ora creato il ruolo di lavoro che elabora l'invio dell'ordine. In questo esempio viene usato il modello di progetto Worker Role with Service Bus Queue di Visual Studio. Le credenziali necessarie sono già state ottenute dal portale.

  1. Assicurarsi che Visual Studio sia connesso all'account Azure.
  2. In Esplora soluzioni in Visual Studio fare clic con il pulsante destro del mouse sulla cartella Roles nel progetto MultiTierApp.
  3. Fare clic su Aggiungi, quindi su Nuovo progetto di ruolo di lavoro. Viene visualizzata la finestra di dialogo Aggiungi nuovo progetto di ruolo.

  4. Nella finestra di dialogo Aggiungi nuovo progetto di ruolo fare clic su Worker Role with Service Bus Queue.

  5. Nella casella Nome assegnare il nome OrderProcessingRole. Fare quindi clic su Aggiungi.
  6. Copiare negli Appunti la stringa di connessione ottenuta nel passaggio 9 della sezione "Creare uno spazio dei nomi del bus di servizio".
  7. In Esplora soluzioni fare clic con il pulsante destro del mouse sul ruolo OrderProcessingRole creato nel passaggio 5. Assicurarsi di fare clic con il pulsante destro del mouse su OrderProcessingRole in Ruoli e non sulla classe. Fare quindi clic su Proprietà.
  8. Nella scheda Impostazioni della finestra di dialogo Proprietà posizionare il cursore all'interno della casella Valore per Microsoft.ServiceBus.ConnectionString, quindi incollare il valore dell'endpoint copiato al passaggio 6.

  9. Creare una classe OnlineOrder che rappresenti gli ordini elaborati dalla coda. È possibile riutilizzare una classe creata in precedenza. In Esplora soluzioni fare clic con il pulsante destro del mouse sulla classe OrderProcessingRole. È necessario fare clic con il pulsante destro del mouse sull'icona della classe, non sul ruolo. Fare clic su Aggiungi, quindi su Elemento esistente.
  10. Selezionare la sottocartella per FrontendWebRole\Modelse fare doppio clic su OnlineOrder.cs per aggiungerlo al progetto corrente.
  11. In WorkerRole.cs modificare il valore della variabile QueueName da "ProcessingQueue" in "OrdersQueue" come illustrato nel codice seguente.

    // The name of your queue.
    const string QueueName = "OrdersQueue";
    
  12. Aggiungere l'istruzione using seguente all'inizio del file WorkerRole.cs.

    using FrontendWebRole.Models;
    
  13. Nella funzione Run(), all'interno della chiamata OnMessage(), sostituire il contenuto della clausola try con il codice seguente.

    Trace.WriteLine("Processing", receivedMessage.SequenceNumber.ToString());
    // View the message as an OnlineOrder.
    OnlineOrder order = receivedMessage.GetBody<OnlineOrder>();
    Trace.WriteLine(order.Customer + ": " + order.Product, "ProcessingMessage");
    receivedMessage.Complete();
    
  14. L'applicazione è stata completata. È possibile testare l'applicazione completa facendo clic con il pulsante destro del mouse sul progetto MultiTierApp in Esplora soluzioni. Selezionare quindi Imposta come progetto di avvio e premere F5. Il numero totale dei messaggi non aumenta perché il ruolo di lavoro elabora gli elementi dalla coda e li contrassegna come completati. È possibile verificare l'output di traccia del ruolo di lavoro visualizzando l'interfaccia utente dell'emulatore di calcolo di Azure. Per eseguire questa operazione, fare clic con il pulsante destro del mouse sull'icona dell'emulatore nell'area di notifica della barra delle applicazioni, quindi scegliere Show Compute Emulator UI (Mostra interfaccia utente dell'emulatore di calcolo).

Passaggi successivi

Per ulteriori informazioni sul bus di servizio, vedere le risorse seguenti:

Per altre informazioni sugli scenari multilivello, vedere: