Condividi tramite


Esercitazione: Archiviare i dati nella rete perimetrale con i database di SQL Server

Si applica a:IoT Edge 1.4 segno di spunta IoT Edge 1.4

Importante

Le versioni di IoT Edge 1.5 LTS e IoT Edge 1.4 sono supportate. Se si usa una versione precedente, vedere Aggiornare IoT Edge.

Distribuire un modulo di SQL Server per archiviare i dati in un dispositivo che esegue Azure IoT Edge con contenitori Linux.

Usare Azure IoT Edge e SQL Server per archiviare ed eseguire query sui dati nella rete perimetrale. Azure IoT Edge offre funzionalità di archiviazione di base per memorizzare nella cache i messaggi se un dispositivo passa offline e quindi inoltrarli quando la connessione viene ristabilita. Tuttavia, è possibile che si vogliano funzionalità di archiviazione più avanzate, ad esempio essere in grado di eseguire query sui dati in locale. I dispositivi IoT Edge possono usare database locali per eseguire calcoli più complessi senza dover mantenere una connessione all'hub IoT.

Questo articolo fornisce istruzioni per la distribuzione di un database di SQL Server in un dispositivo IoT Edge. Funzioni di Azure, in esecuzione nel dispositivo IoT Edge, struttura i dati in ingresso e li invia al database. I passaggi descritti in questo articolo possono essere applicati anche ad altri database che funzionano in contenitori, ad esempio MySQL o PostgreSQL.

In questa esercitazione si apprenderà come:

  • Usare Visual Studio Code per creare una funzione di Azure
  • Distribuire un database SQL nel dispositivo IoT Edge
  • Usare Visual Studio Code per compilare moduli e distribuirli nel dispositivo IoT Edge
  • Visualizzare i dati generati

Se non si ha un account Azure, creare un account gratuito prima di iniziare.

Prerequisiti

Prima di iniziare questa esercitazione, è necessario eseguire l'esercitazione precedente per configurare l'ambiente di sviluppo per lo sviluppo di contenitori Linux: Sviluppare moduli Azure IoT Edge usando Visual Studio Code. Completando questa esercitazione, è necessario disporre dei prerequisiti seguenti:

Questa esercitazione usa un modulo di Funzioni di Azure per inviare dati a SQL Server. Per sviluppare un modulo IoT Edge con Funzioni di Azure, installare i prerequisiti aggiuntivi seguenti nel computer di sviluppo:

Creare un progetto di funzione

Per inviare dati in un database, è necessario un modulo in grado di strutturare correttamente i dati e quindi archiviarlo in una tabella.

Creare un nuovo progetto

I passaggi seguenti illustrano come creare una funzione IoT Edge usando Visual Studio Code e l'estensione Azure IoT Edge.

  1. Aprire Visual Studio Code.

  2. Aprire il riquadro comandi di Visual Studio Code selezionando Visualizza>riquadro comandi.

  3. Nel riquadro comandi digitare ed eseguire il comando Azure IoT Edge: Nuova soluzione IoT Edge. Nel riquadro comandi specificare le informazioni seguenti per creare la soluzione:

    Campo Value
    Selezionare la cartella Scegliere il percorso nel computer di sviluppo per Visual Studio Code per creare i file della soluzione.
    Specificare un nome di soluzione Immettere un nome descrittivo per la soluzione, ad esempio SqlSolution o accettare l'impostazione predefinita.
    Selezionare il modello di modulo Scegliere Funzioni di Azure - C#.
    Specificare un nome di modulo Assegnare al modulo il nome sqlFunction.
    Fornire il repository di immagini Docker per il modulo Un repository di immagini include il nome del registro contenitori e il nome dell'immagine del contenitore. L'immagine del contenitore è prepopolata dall'ultimo passaggio. Sostituire localhost:5000 con il valore del server di accesso dal registro Azure Container. È possibile recuperare il server di accesso dalla pagina Panoramica del registro contenitori nel portale di Azure.

    La stringa finale è simile <al nome> del Registro di sistema.azurecr.io/sqlfunction.

    La finestra di Visual Studio Code carica l'area di lavoro della soluzione IoT Edge.

Aggiungere le credenziali del Registro di sistema

Il file di ambiente archivia le credenziali per il registro contenitori e le condivide con il runtime di IoT Edge. Il runtime richiede queste credenziali per eseguire il pull delle immagini private nel dispositivo IoT Edge.

L'estensione IoT Edge tenta di estrarre le credenziali del registro contenitori da Azure e le popola nel file di ambiente. Verificare se le credenziali sono già incluse. In caso contrario, aggiungerli ora:

  1. Nello strumento di esplorazione di Visual Studio Code aprire il file con estensione env.
  2. Aggiornare i campi con i valori di nome utente e password copiati dal registro Azure Container.
  3. Salvare il file.

Annotazioni

Questa esercitazione usa le credenziali di accesso amministratore per Registro Azure Container, utili per scenari di sviluppo e test. Quando si è pronti per gli scenari di produzione, è consigliabile usare un'opzione di autenticazione con privilegi minimi, ad esempio le entità servizio. Per altre informazioni, vedere Gestire l'accesso al registro contenitori.

Selezionare l'architettura di destinazione

È necessario selezionare l'architettura di destinazione con ogni soluzione, perché il contenitore viene compilato ed eseguito in modo diverso per ogni tipo di architettura. Il valore predefinito è Linux AMD64.

  1. Aprire il riquadro comandi e cercare Azure IoT Edge: Impostare la piattaforma di destinazione predefinita per la soluzione Edge oppure selezionare l'icona di scelta rapida nella barra laterale nella parte inferiore della finestra.

  2. Nel riquadro comandi selezionare l'architettura di destinazione dall'elenco di opzioni. Per questa esercitazione si usa una macchina virtuale Ubuntu come dispositivo IoT Edge, quindi manterrà l'impostazione predefinita amd64.

Aggiornare il modulo con codice personalizzato

  1. Nello strumento di esplorazione di Visual Studio Code aprire moduli>sqlFunction sqlFunction.csproj>.

  2. Trovare il gruppo di riferimenti al pacchetto e aggiungerne uno nuovo per includere SqlClient.

    <PackageReference Include="System.Data.SqlClient" Version="4.5.1"/>
    
  3. Salvare il file sqlFunction.csproj .

  4. Aprire il file sqlFunction.cs .

  5. Sostituire l'intero contenuto del file con il codice seguente:

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Text;
    using System.Threading.Tasks;
    using Microsoft.Azure.Devices.Client;
    using Microsoft.Azure.WebJobs;
    using Microsoft.Azure.WebJobs.Extensions.EdgeHub;
    using Microsoft.Azure.WebJobs.Host;
    using Microsoft.Extensions.Logging;
    using Newtonsoft.Json;
    using Sql = System.Data.SqlClient;
    
    namespace Functions.Samples
    {
        public static class sqlFunction
        {
            [FunctionName("sqlFunction")]
            public static async Task FilterMessageAndSendMessage(
                [EdgeHubTrigger("input1")] Message messageReceived,
                [EdgeHub(OutputName = "output1")] IAsyncCollector<Message> output,
                ILogger logger)
            {
                const int temperatureThreshold = 20;
                byte[] messageBytes = messageReceived.GetBytes();
                var messageString = System.Text.Encoding.UTF8.GetString(messageBytes);
    
                if (!string.IsNullOrEmpty(messageString))
                {
                    logger.LogInformation("Info: Received one non-empty message");
                    // Get the body of the message and deserialize it.
                    var messageBody = JsonConvert.DeserializeObject<MessageBody>(messageString);
    
                    //Store the data in SQL db
                    const string str = "<sql connection string>";
                    using (Sql.SqlConnection conn = new Sql.SqlConnection(str))
                    {
                        conn.Open();
                        var insertMachineTemperature = "INSERT INTO MeasurementsDB.dbo.TemperatureMeasurements VALUES (CONVERT(DATETIME2,'" + messageBody.timeCreated + "', 127), 'machine', " + messageBody.machine.temperature + ");";
                        var insertAmbientTemperature = "INSERT INTO MeasurementsDB.dbo.TemperatureMeasurements VALUES (CONVERT(DATETIME2,'" + messageBody.timeCreated + "', 127), 'ambient', " + messageBody.ambient.temperature + ");";
                        using (Sql.SqlCommand cmd = new Sql.SqlCommand(insertMachineTemperature + "\n" + insertAmbientTemperature, conn))
                        {
                            //Execute the command and log the # rows affected.
                            var rows = await cmd.ExecuteNonQueryAsync();
                            logger.LogInformation($"{rows} rows were updated");
                        }
                    }
    
                    if (messageBody != null && messageBody.machine.temperature > temperatureThreshold)
                    {
                        // Send the message to the output as the temperature value is greater than the threshold.
                        using (var filteredMessage = new Message(messageBytes))
                        {
                             // Copy the properties of the original message into the new Message object.
                             foreach (KeyValuePair<string, string> prop in messageReceived.Properties)
                             {filteredMessage.Properties.Add(prop.Key, prop.Value);}
                             // Add a new property to the message to indicate it is an alert.
                             filteredMessage.Properties.Add("MessageType", "Alert");
                             // Send the message.
                             await output.AddAsync(filteredMessage);
                             logger.LogInformation("Info: Received and transferred a message with temperature above the threshold");
                        }
                    }
                }
            }
        }
        //Define the expected schema for the body of incoming messages.
        class MessageBody
        {
            public Machine machine {get; set;}
            public Ambient ambient {get; set;}
            public string timeCreated {get; set;}
        }
        class Machine
        {
            public double temperature {get; set;}
            public double pressure {get; set;}
        }
        class Ambient
        {
            public double temperature {get; set;}
            public int humidity {get; set;}
        }
    }
    
  6. Nella riga 35 sostituire la stringa<> di connessione sql con la stringa seguente. La proprietà Origine dati fa riferimento al contenitore di SQL Server, che non esiste ancora. Verrà creato con il nome SQL nella sezione successiva. Scegliere una password complessa per la parola chiave Password .

    Data Source=tcp:sql,1433;Initial Catalog=MeasurementsDB;User Id=SA;Password=<YOUR-STRONG-PASSWORD>;TrustServerCertificate=False;Connection Timeout=30;
    
  7. Salvare il file sqlFunction.cs .

Aggiungere il contenitore di SQL Server

Un manifesto della distribuzione dichiara i moduli che il runtime di IoT Edge installerà nel dispositivo IoT Edge. È stato fornito il codice per creare un modulo funzione personalizzato nella sezione precedente, ma il modulo di SQL Server è già compilato e disponibile nel Registro di sistema degli artefatti di Microsoft. È sufficiente indicare al runtime di IoT Edge di includerlo, quindi configurarlo nel dispositivo.

  1. In Visual Studio Code aprire il riquadro comandi selezionando Visualizza>riquadro comandi.

  2. Nel riquadro comandi digitare ed eseguire il comando Azure IoT Edge: Aggiungi modulo IoT Edge. Nel riquadro comandi specificare le informazioni seguenti per aggiungere un nuovo modulo:

    Campo Value
    Selezionare il file modello di distribuzione Il riquadro comandi evidenzia il file deployment.template.json nella cartella della soluzione corrente. Selezionare il file.
    Selezionare il modello di modulo Selezionare Modulo esistente (immettere l'URL immagine completa).
    Specificare un nome modulo Immettere sql. Questo nome corrisponde al nome del contenitore dichiarato nella stringa di connessione nel file sqlFunction.cs.
    Specificare l'immagine Docker per il modulo Immettere l'URI seguente per eseguire il pull dell'immagine del contenitore di SQL Server dal Registro di sistema degli artefatti di Microsoft. Per le immagini basate su Ubuntu, usare mcr.microsoft.com/mssql/server:latest. Per le immagini basate su Red Hat Enterprise Linux (RHEL), usare mcr.microsoft.com/mssql/rhel/server:latest.

    L'immagine del contenitore SQL Edge di Azure è una versione leggera e in contenitori di SQL Server che può essere eseguita nei dispositivi IoT Edge. È ottimizzato per gli scenari perimetrali e può essere eseguito su dispositivi ARM e AMD64.

  3. Nella cartella della soluzione aprire il file deployment.template.json .

  4. Trovare la sezione moduli . Dovrebbero essere visualizzati tre moduli. Il modulo SimulatedTemperatureSensor è incluso per impostazione predefinita nelle nuove soluzioni e fornisce dati di test da usare con gli altri moduli. Il modulo sqlFunction è il modulo creato e aggiornato inizialmente con il nuovo codice. Infine, il modulo sql è stato importato dal Registro artefatti di Microsoft.

    Suggerimento

    Il modulo SQL Server include una password predefinita impostata nelle variabili di ambiente del manifesto della distribuzione. Ogni volta che si crea un contenitore di SQL Server in un ambiente di produzione, è necessario modificare la password di amministratore di sistema predefinita.

  5. Chiudere il file deployment.template.json .

Creare la soluzione IoT Edge

Nelle sezioni precedenti è stata creata una soluzione con un modulo e quindi è stata aggiunta un'altra al modello di manifesto della distribuzione. Il modulo SQL Server è ospitato pubblicamente da Microsoft, ma è necessario inserire il codice nel modulo Funzioni. In questa sezione si compila la soluzione, si creano immagini del contenitore per il modulo sqlFunction e si esegue il push dell'immagine nel registro contenitori.

  1. In Visual Studio Code aprire il terminale integrato selezionando Visualizza>terminale.

  2. Accedere al registro contenitori in Visual Studio Code in modo da poter eseguire il push delle immagini nel registro. Usare le stesse credenziali di Registro Azure Container aggiunte al file con estensione env. Immettere il comando seguente nel terminale integrato:

    docker login -u <ACR username> -p <ACR password> <ACR login server>
    

    Potrebbe essere visualizzato un avviso di sicurezza che consiglia l'uso del parametro --password-stdin. Anche se l'uso non rientra nell'ambito di questo articolo, è consigliabile seguire questa procedura consigliata. Per altre informazioni, vedere le informazioni di riferimento sul comando docker login .

  3. Nello strumento di esplorazione di Visual Studio Code fare clic con il pulsante destro del mouse sul file dideployment.template.json e scegliere Compila e push della soluzione IoT Edge.

    Il comando di compilazione e push avvia tre operazioni. Prima di tutto, crea una nuova cartella nella soluzione denominata config che contiene il manifesto completo della distribuzione, che viene compilato in base alle informazioni nel modello di distribuzione e in altri file di soluzione. In secondo luogo, viene eseguita docker build per compilare l'immagine del contenitore in base al dockerfile appropriato per l'architettura di destinazione. Viene quindi eseguito docker push per eseguire il push del repository di immagini nel registro contenitori.

    Questo processo può richiedere alcuni minuti la prima volta, ma è più veloce la volta successiva che si eseguono i comandi.

    È possibile verificare che il push del modulo sqlFunction sia stato eseguito correttamente nel registro contenitori. Nel portale di Azure passare al registro contenitori. Selezionare i repository e cercare sqlFunction. Gli altri due moduli, SimulatedTemperatureSensor e sql, non verranno inseriti nel registro contenitori perché i repository sono già presenti nei registri Microsoft.

Distribuire la soluzione in un dispositivo

È possibile impostare moduli in un dispositivo tramite l'hub IoT, ma è anche possibile accedere all'hub IoT e ai dispositivi tramite Visual Studio Code. In questa sezione viene configurato l'accesso all'hub IoT e quindi si usa Visual Studio Code per distribuire la soluzione nel dispositivo IoT Edge.

  1. Nello strumento di esplorazione di Visual Studio Code, nella sezione Hub IoT di Azure espandere Dispositivi per visualizzare l'elenco dei dispositivi IoT.

  2. Fare clic con il pulsante destro del mouse sul dispositivo di destinazione con la distribuzione e selezionare Crea distribuzione per singolo dispositivo.

  3. Selezionare il filedeployment.amd64.json nella cartella config e quindi fare clic su Seleziona manifesto distribuzione Edge. Non usare il file deployment.template.json.

  4. Nel dispositivo espandere Moduli per visualizzare un elenco di moduli distribuiti ed in esecuzione. Fare clic sul pulsante Aggiorna. Verranno visualizzati i nuovi moduli sql e sqlFunction in esecuzione insieme al modulo SimulatedTemperatureSensor e al $edgeAgent e $edgeHub.

    È anche possibile verificare che tutti i moduli siano operativi nel dispositivo. Nel dispositivo IoT Edge eseguire il comando seguente per visualizzare lo stato dei moduli.

    iotedge list
    

    L'avvio dei moduli potrebbe richiedere alcuni minuti. Il runtime di IoT Edge deve ricevere il nuovo manifesto della distribuzione, eseguire il pull delle immagini del modulo dal runtime del contenitore, quindi avviare ogni nuovo modulo.

Creare il database SQL

Quando si applica il manifesto della distribuzione al dispositivo, si ottengono tre moduli in esecuzione. Il modulo SimulatedTemperatureSensor genera dati di ambiente simulati. Il modulo sqlFunction accetta i dati e li formatta per un database. Questa sezione illustra come configurare il database SQL per archiviare i dati relativi alla temperatura.

Eseguire i comandi seguenti nel dispositivo IoT Edge. Questi comandi si connettono al modulo sql in esecuzione nel dispositivo e creano un database e una tabella per contenere i dati relativi alla temperatura inviati. Sostituire <YOUR-STRONG-PASSWORD> con la password complessa scelta nella stringa di connessione.

  1. In uno strumento da riga di comando nel dispositivo IoT Edge connettersi al database.

    sudo docker exec -it sql bash
    
  2. Aprire lo strumento di comando SQL.

    /opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P '<YOUR-STRONG-PASSWORD>'
    
  3. Creare il database:

    CREATE DATABASE MeasurementsDB
    ON
    (NAME = MeasurementsDB, FILENAME = '/var/opt/mssql/measurementsdb.mdf')
    GO
    
  4. Definire la tabella.

    CREATE TABLE MeasurementsDB.dbo.TemperatureMeasurements (measurementTime DATETIME2, location NVARCHAR(50), temperature FLOAT)
    GO
    

È possibile personalizzare il file Docker di SQL Server per configurare automaticamente SQL Server da distribuire in più dispositivi IoT Edge. Per altre informazioni, vedere il progetto demo del contenitore di Microsoft SQL Server.

Visualizzare i dati locali

Dopo aver creato la tabella, il modulo sqlFunction avvia l'archiviazione dei dati in un database SQL Server 2017 locale nel dispositivo IoT Edge.

Dall'interno dello strumento di comando SQL eseguire il comando seguente per visualizzare i dati della tabella formattata:

SELECT * FROM MeasurementsDB.dbo.TemperatureMeasurements
GO

Visualizzare il contenuto del database locale

Pulire le risorse

Se si prevede di continuare con l'articolo consigliato successivo, è possibile mantenere le risorse e le configurazioni create e riutilizzarle. È anche possibile continuare a usare lo stesso dispositivo IoT Edge di un dispositivo di test.

In caso contrario, è possibile eliminare le configurazioni locali e le risorse di Azure create in questo articolo per evitare addebiti.

Eliminare le risorse di Azure

L'eliminazione di risorse e gruppi di risorse di Azure è irreversibile. Assicurarsi di non eliminare accidentalmente il gruppo di risorse sbagliato o le risorse errate. Se è stato creato l'hub IoT all'interno di un gruppo di risorse esistente con risorse da mantenere, eliminare solo la risorsa dell'hub IoT stessa, non il gruppo di risorse.

Per eliminare le risorse:

  1. Accedere al portale di Azure e quindi selezionare Gruppi di risorse.

  2. Selezionare il nome del gruppo di risorse che contiene le risorse di test di IoT Edge.

  3. Esaminare l'elenco delle risorse contenute nel gruppo di risorse. Per eliminarli tutti, è possibile selezionare Elimina gruppo di risorse. Se si desidera eliminare solo alcuni di essi, è possibile fare clic in ogni risorsa per eliminarli singolarmente.

In questa esercitazione è stato creato un modulo di Funzioni di Azure che contiene codice per filtrare i dati non elaborati generati dal dispositivo IoT Edge. Quando si è pronti per creare moduli personalizzati, è possibile ottenere altre informazioni su come sviluppare moduli di Azure IoT Edge con Visual Studio Code.

Passaggi successivi

Per provare un altro metodo di archiviazione all'perimetro, leggere le informazioni su come usare Archiviazione BLOB di Azure in IoT Edge.