Dela via


Självstudie: Lagra data på gränsen med SQL Server-databaser

Gäller för:Bockmarkering för IoT Edge 1.5 IoT Edge 1.5 Bockmarkering för IoT Edge 1.4 IoT Edge 1.4

Viktigt!

IoT Edge 1.5 LTS och IoT Edge 1.4 LTS stöds. IoT Edge 1.4 LTS upphör den 12 november 2024. Om du har en tidigare version läser du Uppdatera IoT Edge.

Distribuera en SQL Server-modul för att lagra data på en enhet som kör Azure IoT Edge med Linux-containrar.

Använda Azure IoT Edge och SQL Server för att lagra och fråga efter data på gränsen. Azure IoT Edge har grundläggande lagringsfunktioner för att cachelagra meddelanden om en enhet tas offline och sedan vidarebefordra dem när anslutningen återupprättas. Du kanske behöver mer avancerade funktioner, som t.ex. att kunna fråga efter data lokalt. Dina IoT Edge-enheter kan använda lokala databaser för att utföra mer komplex databehandling utan att behöva underhålla en anslutning till IoT Hub.

Den här artikeln innehåller instruktioner för hur man distribuerar en SQL Server-databas till en IoT Edge-enhet. Azure Functions körs på IoT Edge-enheten och strukturerar inkommande data och skickar dem sedan till databasen. Stegen i den här artikeln kan också tillämpas på andra databaser som fungerar i containrar, t.ex. MySQL eller PostgreSQL.

I den här självstudien lär du dig att:

  • Använd Visual Studio Code för att skapa en Azure-funktion
  • Distribuera en SQL-databas till din IoT Edge-enhet
  • Använd Visual Studio Code för att bygga moduler och distribuera dem till din IoT Edge-enhet
  • Visa genererade data

Om du inte har en Azure-prenumeration skapar du ett kostnadsfritt Azure-konto innan du börjar.

Förutsättningar

Innan du påbörjar den här självstudien bör du ha gått igenom den tidigare självstudien för att konfigurera utvecklingsmiljön för Linux-containerutveckling: Utveckla Azure IoT Edge-moduler med Visual Studio Code. Genom att slutföra den självstudien bör du ha följande förutsättningar på plats:

I den här självstudien används en Azure Functions-modul för att skicka data till SQL Server. Om du vill utveckla en IoT Edge-modul med Azure Functions installerar du följande ytterligare krav på utvecklingsdatorn:

Skapa ett funktionsprojekt

Om du vill skicka data till en databas behöver du en modul som kan strukturera data korrekt och lagra den i en tabell.

Skapa ett nytt projekt

Följande steg visar hur du skapar en IoT Edge-funktion med Visual Studio Code och Azure IoT Edge-tillägget.

  1. Öppna Visual Studio Code.

  2. Öppna Visual Studio Code-kommandopaletten genom att välja Visa>kommandopalett.

  3. Skriv och kör kommandot Azure IoT Edge: New IoT Edge solution (Ny IoT Edge-lösning) i kommandopaletten. Ange följande information i kommandopaletten för att skapa din lösning:

    Fält Värde
    Välj mapp Välj platsen på utvecklingsdatorn för Visual Studio Code för att skapa lösningsfilerna.
    Ange ett namn på lösningen Ange ett beskrivande namn för lösningen, till exempel SqlSolution, eller acceptera standardnamnet.
    Välj modulmall Välj Azure Functions - C#.
    Ange ett modulnamn Ge modulen namnet sqlFunction.
    Ange Docker-bildlagringsplats för modulen En bildlagringsplats innehåller namnet på containerregistret och namnet på containeravbildningen. Containeravbildningen har fyllts i från föregående steg. Ersätt localhost:5000 med värdet för inloggningsservern från azure-containerregistret. Du kan hämta inloggningsservern från sidan Översikt i containerregistret i Azure-portalen.

    Den sista strängen ser ut som <registernamn.azurecr.io/sqlfunction>.

    Visual Studio Code-fönstret läser in arbetsytan för IoT Edge-lösningen.

Lägg till autentiseringsuppgifter för registret

Miljöfilen lagrar autentiseringsuppgifterna för containerregistret och delar dem med körningsmiljön för IoT Edge. Körningen behöver dessa autentiseringsuppgifter för att hämta dina privata avbildningar till IoT Edge-enheten.

IoT Edge-tillägget försöker hämta dina autentiseringsuppgifter för containerregistret från Azure och fylla i dem i miljöfilen. Kontrollera om dina autentiseringsuppgifter redan ingår. Om inte lägger du till dem nu:

  1. Öppna .env-filen i Visual Studio Code-utforskaren.
  2. Uppdatera fälten med det användarnamn och lösenord som du kopierade från Azure Container-registret.
  3. Spara filen.

Kommentar

I den här självstudien används autentiseringsuppgifter för administratörsinloggning för Azure Container Registry, vilket är praktiskt för utvecklings- och testscenarier. När du är redo för produktionsscenarier rekommenderar vi ett alternativ för autentisering med minst privilegier som tjänstens huvudnamn. Mer information finns i Hantera åtkomst till containerregistret.

Välj målarkitektur

Du måste välja vilken arkitektur du riktar in dig på för varje lösning, eftersom containern skapas och körs på olika sätt för varje arkitekturtyp. Standardvärdet är Linux AMD64.

  1. Öppna kommandopaletten och sök efter Azure IoT Edge: Ange standardmålplattform för Edge-lösning eller välj genvägsikonen i sidofältet längst ned i fönstret.

  2. I kommandopaletten väljer du målarkitekturen i listan med alternativ. I den här självstudien använder vi en virtuell Ubuntu-dator som IoT Edge-enhet, så vi behåller standardvärdet amd64.

Uppdatera modulen med anpassad kod

  1. I Visual Studio Code-utforskaren öppnar du modulerna>sqlFunction>sqlFunction.csproj.

  2. Leta upp gruppen med paketreferenser och lägg till en ny som ska inkludera SqlClient.

    <PackageReference Include="System.Data.SqlClient" Version="4.5.1"/>
    
  3. Spara filen sqlFunction.csproj.

  4. Öppna filen sqlFunction.cs .

  5. Ersätt hela innehållet i filen med följande kod:

    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 threashold.
                        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. På rad 35 ersätter du strängen <sql connection string> med följande sträng. Egenskapen Datakälla refererar till SQL Server-containern, som inte finns ännu. Du skapar den med namnet SQL i nästa avsnitt.

    Data Source=tcp:sql,1433;Initial Catalog=MeasurementsDB;User Id=SA;Password=Strong!Passw0rd;TrustServerCertificate=False;Connection Timeout=30;
    
  7. Spara filen sqlFunction.cs.

Lägg till SQL Server-containern

Ett distributionsmanifest deklarerar vilka moduler IoT Edge-körningen kommer installera på din IoT Edge-enhet. Du angav koden för att skapa en anpassad funktionsmodul i föregående avsnitt, men SQL Server-modulen är redan skapad och tillgänglig på Azure Marketplace. Du behöver bara tala om för IoT Edge-körningen att inkludera den och sedan konfigurera den på din enhet.

  1. Öppna kommandopaletten i Visual Studio Code genom att välja Visa>kommandopalett.

  2. I kommandopaletten skriver och kör du kommandot Azure IoT Edge: Add IoT Edge module (Lägg till IoT Edge-modul). I kommandopaletten anger du följande information för att lägga till en ny modul:

    Fält Värde
    Välj distributionsmallfil Kommandopaletten visar filen deployment.template.json i den aktuella lösningsmappen. Välj den filen.
    Välj modulmall Välj Modul från Azure Marketplace.
  3. På Azure IoT Edge-modulens marknadsplats söker du efter och väljer SQL Server-modul.

  4. Ändra modulnamnet till sql, alla gemener. Det här namnet matchar containernamnet som deklarerats i anslutningssträng i filen sqlFunction.cs.

  5. Välj Importera för att lägga till modulen i din lösning.

  6. Öppna filen deployment.template.json i lösningsmappen.

  7. Leta upp avsnittet modules (moduler). Du bör se tre moduler. Modulen SimulatedTemperatureSensor ingår som standard i nya lösningar och tillhandahåller testdata som ska användas med dina andra moduler. Modulen sqlFunction är den modul som du först skapade och uppdaterade med ny kod. Slutligen importerades modulen sql från Azure Marketplace.

    Dricks

    SQL Server-modulen levereras med ett standardlösenord i miljövariablerna för distributionsmanifestet. Varje gång du skapar en SQL Server-container i en produktionsmiljö bör du ändra standardlösenord för systemadministratören.

  8. Stäng filen deployment.template.json .

Skapa din IoT Edge-lösning

I föregående avsnitt skapade du en lösning med en modul och lade sedan till en annan till distributionsmanifestet. SQL Server-modulen hanteras offentligt av Microsoft, men du måste containerisera koden i Functions-modulen. I det här avsnittet skapar du lösningen, skapar containeravbildningar för sqlFunction-modulen och push-överför avbildningen till containerregistret.

  1. I Visual Studio Code öppnar du den integrerade terminalen genom att välja Visa>Terminal.

  2. Logga in på ditt containerregister i Visual Studio Code så att du kan push-överföra avbildningarna till registret. Använd samma autentiseringsuppgifter för Azure Container Registry (ACR) som du lade till i .env-filen. Ange följande kommando i den integrerade terminalen:

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

    Du kan se en säkerhetsvarning som rekommenderar användning av parametern --password-stdin. Även om användning av denna ligger utanför vad som tas upp i denna artikel rekommenderar vi att du följer denna bästa metod. Mer information finns i kommandoreferensen för docker-inloggning .

  3. I Visual Studio Code-utforskaren högerklickar du på filen deployment.template.json och väljer Build and Push IoT Edge solution (Skapa och push-lösning för IoT Edge).

    Kommandot build och push startar tre åtgärder. Först skapar den en ny mapp i lösningen med namnet config som innehåller det fullständiga distributionsmanifestet, som är inbyggt med information i distributionsmallen och andra lösningsfiler. För det andra körs docker build den för att skapa containeravbildningen baserat på lämplig dockerfile för målarkitekturen. Sedan körs docker push den för att skicka avbildningslagringsplatsen till containerregistret.

    Den här processen kan ta flera minuter första gången, men det går snabbare nästa gång du kör kommandona.

    Du kan kontrollera att sqlFunction-modulen har överförts till containerregistret. I Azure-portalen går du till containerregistret. Välj lagringsplatser och sök efter sqlFunction. De andra två modulerna, SimulatedTemperatureSensor och sql, skickas inte till containerregistret eftersom deras lagringsplatser redan finns i Microsoft-register.

Distribuera lösningen till en enhet

Du kan ange moduler på en enhet via IoT Hub, men du kan också komma åt din IoT Hub och enheter via Visual Studio Code. I det här avsnittet konfigurerar du åtkomst till din IoT Hub och använder sedan Visual Studio Code för att distribuera din lösning till din IoT Edge-enhet.

  1. I Visual Studio Code-utforskaren under avsnittet Azure IoT Hub expanderar du Enheter för att se din lista över IoT-enheter.

  2. Högerklicka på den enhet som du vill rikta in dig på med distributionen och välj Skapa distribution för enskild enhet.

  3. Välj filen deployment.amd64.json i mappen config och klicka sedan på Välj Edge-distributionsmanifest. Använd inte filen deployment.template.json.

  4. Under enheten expanderar du Moduler för att se en lista över distribuerade och körande moduler. Klicka på uppdateringsknappen. Du bör se de nya sql - och sqlFunction-modulerna som körs tillsammans med modulen SimulatedTemperatureSensor och $edgeAgent och $edgeHub.

    Du kan också kontrollera att alla moduler är igång på enheten. Kör följande kommando på IoT Edge-enheten för att se status för modulerna.

    iotedge list
    

    Det kan ta några minuter innan modulerna startas. IoT Edge-körningen måste ta emot sitt nya distributionsmanifest, hämta modulavbildningarna från containerkörningen och starta sedan varje ny modul.

Skapa SQL-databasen

När du applicerar distributionsmanifestet på din enhet körs tre moduler. Modulen SimulatedTemperatureSensor genererar simulerade miljödata. Modulen sqlFunction hämtar data och formaterar dem för en databas. Det här avsnittet hjälper dig att konfigurera SQL-databasen för lagring av temperaturdata.

Kör följande kommandon på din IoT Edge-enhet. De kommandona ansluter till den sql-modul som körs på enheten och skapar en databas och en tabell som ska innehålla temperaturdata som skickas till den.

  1. I ett kommandoradsverktyg på IoT Edge-enheten ansluter du till din databas.

    sudo docker exec -it sql bash
    
  2. Öppna SQL-kommandoverktyget.

    /opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P 'Strong!Passw0rd'
    
  3. Skapa databasen:

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

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

Du kan anpassa din SQL Server Docker-fil så att SQL Server automatiskt konfigureras för distribuering till flera IoT Edge-enheter. Mer information finns i demoprojektet för Microsoft SQL Server-containern.

Visa lokala data

När din tabell har skapats börjar modulen sqlFunction lagra data i en lokal SQL Server 2017-databas på IoT Edge-enheten.

Kör följande kommando från SQL-kommandoverktyget för att visa formaterade tabelldata:

SELECT * FROM MeasurementsDB.dbo.TemperatureMeasurements
GO

Visa innehållet i en lokal databas

Rensa resurser

Om du tänker fortsätta till nästa rekommenderade artikel kan du behålla de resurser och konfigurationer du har skapat och använda dem igen. Du kan även fortsätta att använda samma IoT Edge-enhet som en testenhet.

Annars kan du ta bort de lokala konfigurationerna och de Azure-resurser som du har skapat i den här artikeln för att därigenom undvika kostnader.

Ta bort Azure-resurser

Det går inte att ångra borttagningen av Azure-resurser och resursgrupper. Var noga så att du inte tar bort fel resursgrupp eller resurser av misstag. Om du har skapat IoT-hubben i en befintlig resursgrupp som har resurser som du vill behålla tar du bara bort själva IoT Hub-resursen, inte resursgruppen.

Ta bort resurser:

  1. Logga in på Azure-portalen och välj Resursgrupper.

  2. Välj namnet på resursgruppen som innehåller dina IoT Edge-testresurser.

  3. Granska listan över resurser som finns i resursgruppen. Om du vill ta bort alla kan du välja Ta bort resursgrupp. Om du bara vill ta bort några av dem kan du klicka i varje resurs och ta bort dem individuellt.

I den här självstudien skapade du en Azure Functions-modul som innehåller kod för att filtrera rådata som genereras av din IoT Edge-enhet. När du är redo att skapa egna moduler kan du lära dig mer om hur du utvecklar Azure IoT Edge-moduler med Visual Studio Code.

Nästa steg

Om du vill prova en annan lagringsmetod vid gränsen kan du läsa om hur du använder Azure Blob Storage på IoT Edge.