Partilhar via


Tutorial: Armazenar dados na borda com bancos de dados do SQL Server

Aplica-se a:Marca de verificação do IoT Edge 1.4 IoT Edge 1.4

Importante

IoT Edge 1.5 LTS e IoT Edge 1.4 são versões suportadas. Se você estiver em uma versão anterior, consulte Atualizar o IoT Edge.

Implante um módulo do SQL Server para armazenar dados em um dispositivo que executa o Azure IoT Edge com contêineres Linux.

Use o Azure IoT Edge e o SQL Server para armazenar e consultar dados na borda. O Azure IoT Edge tem recursos básicos de armazenamento para armazenar mensagens em cache se um dispositivo ficar offline e, em seguida, encaminhá-las quando a conexão for restabelecida. No entanto, você pode querer recursos de armazenamento mais avançados, como poder consultar dados localmente. Seus dispositivos IoT Edge podem usar bancos de dados locais para executar computação mais complexa sem precisar manter uma conexão com o Hub IoT.

Este artigo fornece instruções para implantar um banco de dados do SQL Server em um dispositivo IoT Edge. O Azure Functions, em execução no dispositivo IoT Edge, estrutura os dados de entrada e os envia para o banco de dados. As etapas neste artigo também podem ser aplicadas a outros bancos de dados que funcionam em contêineres, como MySQL ou PostgreSQL.

Neste tutorial, você aprenderá a:

  • Usar o Visual Studio Code para criar uma função do Azure
  • Implantar um banco de dados SQL em seu dispositivo IoT Edge
  • Use o Visual Studio Code para criar módulos e implantá-los em seu dispositivo IoT Edge
  • Ver dados gerados

Se não tiver uma conta do Azure, crie uma conta gratuita antes de começar.

Pré-requisitos

Antes de começar este tutorial, você deve ter passado pelo tutorial anterior para configurar seu ambiente de desenvolvimento para desenvolvimento de contêineres Linux: Desenvolver módulos do Azure IoT Edge usando o Visual Studio Code. Ao concluir esse tutorial, você deve ter os seguintes pré-requisitos em vigor:

Este tutorial usa um módulo do Azure Functions para enviar dados para o SQL Server. Para desenvolver um módulo IoT Edge com o Azure Functions, instale os seguintes pré-requisitos adicionais em sua máquina de desenvolvimento:

Criar um projeto de função

Para enviar dados para um banco de dados, você precisa de um módulo que possa estruturar os dados corretamente e, em seguida, armazená-los em uma tabela.

Criar um novo projeto

As etapas a seguir mostram como criar uma função do IoT Edge usando o Visual Studio Code e a extensão do Azure IoT Edge.

  1. Abra o Visual Studio Code.

  2. Abra a paleta de comandos Código do Visual Studio selecionando Exibir>paleta de comandos.

  3. Na paleta de comandos, digite e execute o comando Azure IoT Edge: Nova solução IoT Edge. Na paleta de comandos, forneça as seguintes informações para criar sua solução:

    Campo Valor
    Selecionar pasta Escolha o local em sua máquina de desenvolvimento para Visual Studio Code para criar os arquivos de solução.
    Forneça um nome de solução Insira um nome descritivo para sua solução, como SqlSolution, ou aceite o padrão.
    Selecionar modelo de módulo Escolha Azure Functions - C#.
    Forneça um nome de módulo Nomeie seu módulo sqlFunction.
    Fornecer repositório de imagens do Docker para o módulo Um repositório de imagens inclui o nome do registro do contêiner e o nome da imagem do contêiner. Sua imagem de contêiner é preenchida previamente a partir da última etapa. Substitua localhost:5000 pelo valor do servidor de Logon do seu registro de contêiner do Azure. Você pode recuperar o servidor de Logon na página Visão geral do seu registro de contêiner no portal do Azure.

    A cadeia de caracteres final se parece com <o nome> do Registro.azurecr.io/sqlfunction.

    A janela Código do Visual Studio carrega seu espaço de trabalho da solução IoT Edge.

Adicione as suas credenciais de registo

O arquivo de ambiente armazena as credenciais para seu registro de contêiner e as compartilha com o tempo de execução do IoT Edge. O tempo de execução precisa dessas credenciais para puxar suas imagens privadas para o dispositivo IoT Edge.

A extensão IoT Edge tenta extrair suas credenciais de registro de contêiner do Azure e as preenche no arquivo de ambiente. Verifique se as suas credenciais já estão incluídas. Se não, adicione-os agora:

  1. No explorador de código do Visual Studio, abra o arquivo .env.
  2. Atualize os campos com os valores de nome de usuário e senha que você copiou do seu registro de contêiner do Azure.
  3. Salve este arquivo.

Observação

Este tutorial usa credenciais de logon de administrador para o Registro de Contêiner do Azure, que são convenientes para cenários de desenvolvimento e teste. Quando estiver pronto para cenários de produção, recomendamos uma opção de autenticação de privilégios mínimos, como entidades de serviço. Para obter mais informações, consulte Gerenciar o acesso ao registro de contêiner.

Selecione sua arquitetura de destino

Você precisa selecionar qual arquitetura você está segmentando com cada solução, porque o contêiner é criado e executado de forma diferente para cada tipo de arquitetura. O padrão é Linux AMD64.

  1. Abra a paleta de comandos e procure Azure IoT Edge: set Default Target Platform for Edge Solution ou selecione o ícone de atalho na barra lateral na parte inferior da janela.

  2. Na paleta de comandos, selecione a arquitetura de destino na lista de opções. Para este tutorial, estamos usando uma máquina virtual Ubuntu como o dispositivo IoT Edge, portanto, manteremos o amd64 padrão.

Atualize o módulo com código personalizado

  1. No explorador de código do Visual Studio, abra os módulos>sqlFunction>sqlFunction.csproj.

  2. Localize o grupo de referências de pacote e adicione um novo para incluir SqlClient.

    <PackageReference Include="System.Data.SqlClient" Version="4.5.1"/>
    
  3. Salve o arquivo sqlFunction.csproj .

  4. Abra o arquivo sqlFunction.cs .

  5. Substitua todo o conteúdo do arquivo pelo seguinte código:

    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. Na linha 35, substitua a cadeia> de conexão< sql pela cadeia de caracteres a seguir. A propriedade Data Source faz referência ao contêiner do SQL Server, que ainda não existe. Você irá criá-lo com o nome SQL na próxima seção. Escolha uma palavra-passe forte para a palavra-chave Password .

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

Adicionar o contêiner do SQL Server

Um manifesto de implantação declara quais módulos o tempo de execução do IoT Edge instalará em seu dispositivo IoT Edge. Você forneceu o código para criar um módulo de função personalizado na seção anterior, mas o módulo do SQL Server já está criado e disponível no Microsoft Artifact Registry. Você só precisa dizer ao tempo de execução do IoT Edge para incluí-lo e, em seguida, configurá-lo em seu dispositivo.

  1. No Visual Studio Code, abra a paleta de comandos selecionando Exibir>paleta de comandos.

  2. Na paleta de comandos, digite e execute o comando Azure IoT Edge: Add IoT Edge module. Na paleta de comandos, forneça as seguintes informações para adicionar um novo módulo:

    Campo Valor
    Selecionar arquivo de modelo de implantação A paleta de comandos destaca o arquivo deployment.template.json na pasta de solução atual. Selecione esse arquivo.
    Selecionar modelo de módulo Selecione Módulo existente (insira o URL completo da imagem).
    Forneça um nome de módulo Digite sql. Esse nome corresponde ao nome do contêiner declarado na cadeia de conexão no arquivo sqlFunction.cs.
    Fornecer imagem do Docker para o módulo Insira o seguinte URI para extrair a imagem de contêiner do SQL Server do Microsoft Artifact Registry. Para imagens baseadas no Ubuntu, use mcr.microsoft.com/mssql/server:latesto . Para imagens baseadas no Red Hat Enterprise Linux (RHEL), use mcr.microsoft.com/mssql/rhel/server:latesto .

    A imagem de contêiner do SQL Edge do Azure é uma versão leve e conteinerizada do SQL Server que pode ser executada em dispositivos IoT Edge. Ele é otimizado para cenários de borda e pode ser executado em dispositivos ARM e AMD64.

  3. Na pasta da solução, abra o arquivo deployment.template.json .

  4. Encontre a seção de módulos . Você deve ver três módulos. O módulo SimulatedTemperatureSensor está incluído por padrão em novas soluções e fornece dados de teste para usar com seus outros módulos. O módulo sqlFunction é o módulo que você criou inicialmente e atualizou com o novo código. Finalmente, o módulo sql foi importado do Microsoft Artifact Registry.

    Sugestão

    O módulo SQL Server vem com uma senha padrão definida nas variáveis de ambiente do manifesto de implantação. Sempre que criar um contêiner do SQL Server em um ambiente de produção, você deverá alterar a senha padrão do administrador do sistema.

  5. Feche o arquivodeployment.template.json .

Crie sua solução IoT Edge

Nas seções anteriores, você criou uma solução com um módulo e, em seguida, adicionou outro ao modelo de manifesto de implantação. O módulo SQL Server é hospedado publicamente pela Microsoft, mas você precisa conteinerizar o código no módulo Funções. Nesta seção, você cria a solução, cria imagens de contêiner para o módulo sqlFunction e envia a imagem para o registro de contêiner.

  1. No Visual Studio Code, abra o terminal integrado selecionando View>Terminal.

  2. Entre no registro de contêiner no Visual Studio Code para que você possa enviar suas imagens para o registro. Use as mesmas credenciais do Registro de Contêiner do Azure (ACR) que você adicionou ao arquivo .env. Digite o seguinte comando no terminal integrado:

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

    Você pode ver um aviso de segurança recomendando o uso do parâmetro --password-stdin. Embora seu uso esteja fora do escopo deste artigo, recomendamos seguir essa prática recomendada. Para obter mais informações, consulte a referência do comando docker login .

  3. No explorador de código do Visual Studio, clique com o botão direito do mouse no arquivo dedeployment.template.json e selecione Criar e enviar por push a solução IoT Edge.

    O comando build e push inicia três operações. Primeiro, ele cria uma nova pasta na solução chamada config que contém o manifesto de implantação completo, que é criado a partir de informações no modelo de implantação e outros arquivos de solução. Em segundo lugar, ele é executado docker build para criar a imagem do contêiner com base no dockerfile apropriado para sua arquitetura de destino. Em seguida, ele é executado docker push para enviar o repositório de imagens para o registro do contêiner.

    Esse processo pode levar vários minutos na primeira vez, mas é mais rápido na próxima vez que você executar os comandos.

    Você pode verificar se o módulo sqlFunction foi enviado com êxito para o registro do contêiner. No portal do Azure, navegue até o registro do contêiner. Selecione repositórios e procure sqlFunction. Os outros dois módulos, SimulatedTemperatureSensor e sql, não serão enviados para o registro do contêiner porque seus repositórios já estão nos registros da Microsoft.

Implantar a solução em um dispositivo

Você pode definir módulos em um dispositivo por meio do Hub IoT, mas também pode acessar seu Hub IoT e dispositivos por meio do Visual Studio Code. Nesta seção, você configura o acesso ao seu Hub IoT e, em seguida, usa o Visual Studio Code para implantar sua solução em seu dispositivo IoT Edge.

  1. No explorador de código do Visual Studio, na seção Hub IoT do Azure , expanda Dispositivos para ver sua lista de dispositivos IoT.

  2. Clique com o botão direito do mouse no dispositivo que você deseja direcionar com sua implantação e selecione Criar implantação para um único dispositivo.

  3. Selecione o arquivo deployment.amd64.json na pasta config e clique em Select Edge Deployment Manifest. Não utilize o ficheiro deployment.template.json.

  4. No dispositivo, expanda Módulos para ver uma lista de módulos implantados e em execução. Clique no botão Atualizar. Você deve ver os novos módulos sql e sqlFunction em execução junto com o módulo SimulatedTemperatureSensor e os $edgeAgent e $edgeHub.

    Você também pode verificar se todos os módulos estão funcionando no seu dispositivo. No dispositivo IoT Edge, execute o seguinte comando para ver o status dos módulos.

    iotedge list
    

    Pode levar alguns minutos para que os módulos iniciem. O tempo de execução do IoT Edge precisa receber seu novo manifesto de implantação, extrair as imagens do módulo do tempo de execução do contêiner e iniciar cada novo módulo.

Criar o banco de dados SQL

Ao aplicar o manifesto de implantação ao seu dispositivo, você obtém três módulos em execução. O módulo SimulatedTemperatureSensor gera dados de ambiente simulados. O módulo sqlFunction pega os dados e os formata para um banco de dados. Esta seção o orienta na configuração do banco de dados SQL para armazenar os dados de temperatura.

Execute os seguintes comandos no dispositivo IoT Edge. Esses comandos se conectam ao módulo sql em execução no seu dispositivo e criam um banco de dados e uma tabela para armazenar os dados de temperatura que estão sendo enviados para ele. Substitua <YOUR-STRONG-PASSWORD pela palavra-passe forte que> escolheu na sua cadeia de ligação.

  1. Em uma ferramenta de linha de comando em seu dispositivo IoT Edge, conecte-se ao seu banco de dados.

    sudo docker exec -it sql bash
    
  2. Abra a ferramenta de comando SQL.

    /opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P '<YOUR-STRONG-PASSWORD>'
    
  3. Crie a sua base de dados:

    CREATE DATABASE MeasurementsDB
    ON
    (NAME = MeasurementsDB, FILENAME = '/var/opt/mssql/measurementsdb.mdf')
    GO
    
  4. Defina a sua tabela.

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

Você pode personalizar seu arquivo docker do SQL Server para configurar automaticamente seu SQL Server a ser implantado em vários dispositivos IoT Edge. Para obter mais informações, consulte o projeto de demonstração de contêiner do Microsoft SQL Server.

Ver os dados locais

Depois que a tabela é criada, o módulo sqlFunction começa a armazenar dados em um banco de dados local do SQL Server 2017 em seu dispositivo IoT Edge.

De dentro da ferramenta de comando SQL, execute o seguinte comando para exibir os dados da tabela formatada:

SELECT * FROM MeasurementsDB.dbo.TemperatureMeasurements
GO

Exibir conteúdo do banco de dados local

Limpeza de recursos

Se você planeja continuar para o próximo artigo recomendado, você pode manter os recursos e configurações que você criou e reutilizá-los. Você também pode continuar usando o mesmo dispositivo IoT Edge como um dispositivo de teste.

Caso contrário, você pode excluir as configurações locais e os recursos do Azure criados neste artigo para evitar cobranças.

Excluir recursos do Azure

A exclusão de recursos e grupos de recursos do Azure é irreversível. Certifique-se de que não elimina acidentalmente o grupo de recursos ou recursos errados. Se você criou o hub IoT dentro de um grupo de recursos existente que tem recursos que deseja manter, exclua apenas o recurso do hub IoT em si, não o grupo de recursos.

Para excluir os recursos:

  1. Entre no portal do Azure e selecione Grupos de recursos.

  2. Selecione o nome do grupo de recursos que contém seus recursos de teste do IoT Edge.

  3. Reveja a lista de recursos contidos no seu grupo de recursos. Se quiser excluir todos eles, selecione Excluir grupo de recursos. Se você quiser excluir apenas alguns deles, você pode clicar em cada recurso para excluí-los individualmente.

Neste tutorial, você criou um módulo do Azure Functions que contém código para filtrar dados brutos gerados pelo seu dispositivo IoT Edge. Quando estiver pronto para criar seus próprios módulos, você poderá saber mais sobre como desenvolver módulos do Azure IoT Edge usando o Visual Studio Code.

Próximos passos

Se você quiser tentar outro método de armazenamento na borda, leia sobre como usar o Armazenamento de Blob do Azure no IoT Edge.