Руководство по хранению данных в пограничной системе с помощью баз данных SQL Server

Область применения:IoT Edge 1.4 checkmark IoT Edge 1.4

Важно!

IoT Edge 1.4 является поддерживаемым выпуском. Если вы используете более ранний выпуск, см. статью Обновление IoT Edge.

Разверните модуль SQL Server для хранения данных на устройстве, на котором выполняется Azure IoT Edge с контейнерами Linux.

Используйте Azure IoT Edge и SQL Server для хранения и запроса данных в пограничной системе. Azure IoT Edge предоставляет базовые функции хранения для кэширования сообщений при переходе устройства в автономный режим и последующей их переадресацией при повторном подключении. Однако вам могут потребоваться дополнительные возможности хранения данных, например возможность запрашивать данные локально. С помощью локальных баз данных устройства IoT Edge могут выполнять более сложные вычисления без необходимости поддерживать соединение с Центром Интернета вещей.

В этой статье содержатся сведения для развертывания базы данных SQL Server на устройство IoT Edge. Функции Azure, запущенные на устройстве IoT Edge, структурируют входящие данные, а затем отправляют их в базу данных. Шаги, описанные в этой статье, также можно применить к другим базам данных, которые работают в контейнерах, например MySQL или PostgreSQL.

В этом руководстве описано следующее:

  • Использование Visual Studio Code для создания функции Azure
  • Развертывание базы данных SQL на устройстве IoT Edge
  • Использование кода Visual Studio для создания модулей и их развертывание на устройстве IoT Edge
  • просмотр сформированных данных.

Если у вас еще нет подписки Azure, создайте бесплатную учетную запись Azure, прежде чем начинать работу.

Необходимые компоненты

Прежде чем приступить к работе с этим руководством, необходимо выполнить инструкции по настройке среды разработки для контейнеров Linux: разработка модулей Azure IoT Edge с помощью Visual Studio Code. После работы с ним у вас должны быть готовы все необходимые компоненты:

  • Центр Интернета вещей ценовой категории "Бесплатный" или "Стандартный" в Azure.
  • Устройство AMD64, на котором выполняется Azure IoT Edge с контейнерами Linux. Вы можете воспользоваться краткими руководствами для настройки устройства Linux или Windows.
  • реестр контейнеров, например Реестр контейнеров Azure;
  • Visual Studio Code, настроенный с помощью расширений Azure IoT Edge и Центр Интернета вещей Azure. Средства Azure IoT Edge для расширения Visual Studio Code в режиме обслуживания.
  • Скачайте и установите совместимую систему управления контейнерами Docker на компьютере разработки. Настройте его для запуска контейнеров Linux.

Для отправки данных в SQL Server в рамках этого руководства используется модуль Функций Azure. Для разработки модуля IoT Edge с использованием Функций Azure установите на компьютере разработки следующие дополнительные компоненты:

Создание проекта функции

Чтобы отправить данные в базу данных, необходим модуль, который может правильно структурировать данные, а затем сохранить их в таблице.

Создание нового проекта

Следующий процесс позволяет создать модуль IoT Edge с использованием Visual Studio Code и расширения Azure IoT Edge.

  1. Откройте Visual Studio Code.

  2. Откройте палитру команд Visual Studio Code, выбрав палитру команд View>.

  3. В палитре команд введите и выполните командуAzure IoT Edge: New IoT Edge solution. В палитре команд укажите следующие сведения для создания решения:

    Поле значение
    Выбрать папку Выберите расположение на компьютере разработчика для Visual Studio Code, чтобы создать файлы решения.
    Введите название решения. Введите описательное имя для решения, например SqlSolution, или примите значение по умолчанию.
    Выбор шаблона модуля Выберите Функции Azure — C#.
    Указание имени модуля Назовите модуль sqlFunction.
    Указание репозитория изображений Docker для модуля Репозиторий изображений включает в себя имя реестра контейнеров и имя образа контейнера. Образ контейнера предварительно заполняется на последнем шаге. Замените localhost:5000 значением сервера входа из реестра контейнеров Azure. Вы можете узнать сервер входа на странице "Обзор" реестра контейнеров на портале Azure.

    Последняя строка выглядит следующим образом: <имя реестра>.azurecr.io/sqlfunction.

    После этого окно VS Code открывает рабочую область решения IoT Edge.

Добавление учетных данных реестра

Файл среды хранит учетные данные для реестра контейнеров и совместно использует их со средой выполнения IoT Edge. Среде выполнения нужны эти учетные данные, чтобы извлечь частный образ на устройство IoT Edge.

Расширение IoT Edge пытается извлечь учетные данные реестра контейнеров из Azure и заполнить их в файле среды. Проверьте, включены ли ваши учетные данные. В противном случае добавьте их:

  1. В обозревателе Visual Studio Code откройте env-файл.
  2. Обновите поля с именем пользователя и паролем, скопированные из своего реестра контейнера Azure.
  3. Сохраните этот файл.

Примечание.

При работе с этим руководством используются учетные данные администратора для Реестра контейнеров Azure, что удобно для сценариев разработки и тестирования. Но после перехода в рабочую среду рекомендуется использовать для проверки подлинности вариант с минимальными правами, например субъект-службу. Дополнительные сведения см. в разделе Управление доступом к реестру контейнеров.

Выбор целевой архитектуры

Для каждого решения вам нужно выбрать одну целевую платформу, так как сборка и запуск контейнера для разных архитектур различается. По умолчанию используется Linux AMD64.

  1. Откройте палитру команд и найдите Azure IoT Edge: задайте целевую платформу по умолчанию для решения Edge или щелкните значок ярлыка в боковой строке в нижней части окна.

  2. В палитре команд выберите целевую архитектуру из списка параметров. В рамках этого руководства мы используем в качестве устройства IoT Edge виртуальную машину Ubuntu. Поэтому сохраним значение по умолчанию amd64.

Обновление модуля с помощью пользовательского кода

  1. В обозревателе Visual Studio Code откройте модули>sqlFunction>sqlFunction.csproj.

  2. Найдите группу ссылок на пакеты и добавьте новую для SqlClient.

    <PackageReference Include="System.Data.SqlClient" Version="4.5.1"/>
    
  3. Сохраните файл sqlFunction.csproj.

  4. Откройте файл sqlFunction.cs.

  5. Замените все содержимое файла следующим кодом:

    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. В строке 35 замените строку <sql connection string> следующей строкой. Свойство Источник данных ссылается на контейнер SQL Server, которого пока не существует. Он будет создан в следующем разделе, и будет иметь имя — SQL.

    Data Source=tcp:sql,1433;Initial Catalog=MeasurementsDB;User Id=SA;Password=Strong!Passw0rd;TrustServerCertificate=False;Connection Timeout=30;
    
  7. Сохраните файл sqlFunction.cs.

Добавление контейнера SQL Server

Манифест развертывания объявляет модули, которые среда выполнения IoT Edge установит на вашем устройстве IoT Edge. Вы добавили код для создания настраиваемого модуля службы "Функции" в предыдущем разделе, но модуль SQL Server уже создан и доступен в Azure Marketplace. Необходимо сообщить среде выполнения IoT Edge о том, что его нужно включить и настроить на устройстве.

  1. В Visual Studio Code откройте палитру команд, выбрав Представление>Палитра команд.

  2. В палитре команд введите и запустите команду Azure IoT Edge: добавьте модуль IoT Edge. В палитре команд укажите следующую информацию для добавления нового модуля:

    Поле значение
    Выбор файла шаблона развертывания Палитра команд выделяет файл deployment.template.json в текущей папке решения. Выберите этот файл.
    Выбор шаблона модуля Выберите Module from Azure Marketplace (Модуль в Azure Marketplace).
  3. В окне Azure IoT Edge Module Marketplace найдите и выберите Модуль SQL Server.

  4. Измените имя модуля на sql (полностью прописными буквами). Это имя совпадает с именем контейнера, объявленного в строке подключения в файле sqlFunction.cs.

  5. Выберите команду Импорт, чтобы добавить модуль в свое решение.

  6. Откройте файл deployment.template.json в папке решения.

  7. Перейдите в раздел Модули. Вы должны увидеть три модуля. Модуль SimulatedTemperatureSensor по умолчанию добавляется в новые решения и предоставляет тестовые данные для использования с другими модулями. Модуль sqlFunction создается в самом начале, и в него добавляется новый код. Наконец, модуль sql был импортирован из Azure Marketplace.

    Совет

    Модуль SQL Server поставляется с паролем по умолчанию, заданным в переменных среды манифеста развертывания. Каждый раз при создании контейнера SQL Server в рабочей среде нужно изменять стандартный пароль системного администратора.

  8. Закройте файл deployment.template.json.

Сборка решения IoT Edge

В предыдущих разделах было создано решение с одним модулем, а затем добавлено другое в шаблон манифеста развертывания. Модуль SQL Server размещается корпорацией Майкрософт в открытом доступе, но чтобы им воспользоваться, нужно поместить код в модуле функции. В этом разделе выполняется сборка решения, создание образов контейнеров для модуля sqlFunction и отправка образа в реестр контейнеров.

  1. В Visual Studio Code откройте интегрированный терминал, последовательно выбрав элементы Вид>Терминал.

  2. Войдите в реестр контейнеров в Visual Studio Code, чтобы вы могли отправить свои образы в реестр. Используйте те же учетные данные Реестра контейнеров Azure, добавленные в файле ENV. Введите следующую команду в окне интегрированного терминала:

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

    На экране может отобразиться предупреждение системы безопасности с рекомендацией использовать параметр password-stdin. Хотя его использование выходит за рамки данной статьи, мы рекомендуем следовать данной рекомендации. Чтобы получить дополнительные сведения, ознакомьтесь с описанием команды docker login.

  3. В обозревателе Visual Studio Code щелкните правой кнопкой мыши файл deployment.template.json и выберите "Сборка и отправка решения IoT Edge".

    Эта команда сборки и отправки позволяет запустить три операции. Во-первых, в решении создается папка с именем config, которая содержит полный манифест развертывания на основе информации из шаблона развертывания и других файлов решения. Во-вторых, выполняется docker build для сборки образа контейнера на основе подходящего файла dockerfile для целевой архитектуры. В-третьих, выполняется docker push для отправки образа в реестр контейнеров.

    В первый раз выполнение этого процесса может занять несколько минут, но при следующем запуске команд он будет быстрее.

    Вы можете убедиться, что модуль sqlFunction был успешно отправлен в реестр контейнеров. На портале Azure перейдите в реестр контейнеров. Выберите Репозитории и выполните поиск по имени sqlFunction. Другие два модуля (SimulatedTemperatureSensor и sql) не помещены в реестр контейнеров, так как их репозитории уже находятся в реестрах Microsoft.

Развертывание решения на устройстве

Модули на устройстве можно задать с помощью Центра Интернета вещей, однако доступ к Центру Интернета вещей и устройствам можно также получить через Visual Studio Code. В этом разделе описано, как настроить доступ к Центр Интернета вещей затем использовать Visual Studio Code для развертывания решения на устройстве IoT Edge.

  1. В обозревателе Visual Studio Code в разделе Центр Интернета вещей Azure разверните меню Устройства, чтобы отобразить список устройств Интернета вещей.

  2. Щелкните правой кнопкой мыши имя устройства, которое необходимо сделать целевым объектом развертывания, и выберите Create Deployment for IoT Edge (Создать развертывание для устройств IoT Edge).

  3. Выберите файл deployment.amd64.json в папке config и щелкните Select Edge Deployment Manifest (Выбрать манифест развертывания Edge). Не используйте файл deployment.template.json.

  4. Разверните меню Модули для своего устройства, чтобы просмотреть список развернутых и запущенных модулей. Нажмите кнопку "Обновить". Появятся новые модули sql и sqlFunction, выполняющиеся вместе с модулем SimulatedTemperatureSensor, а также с $edgeAgent и $edgeHub.

    Кроме того, можно проверить, все ли модули отображаются и запущены на своем устройстве. На своем устройстве IoT Edge выполните следующую команду, чтобы увидеть состояние модулей.

    iotedge list
    

    На запуск модулей может потребоваться несколько минут. Среда выполнения IoT Edge должна получить новый манифест развертывания, извлечь образы модулей из среды выполнения контейнеров, а затем запустить каждый новый модуль.

Создание базы данных SQL

При применении манифеста развертывания на устройстве вы получаете три выполняемых модуля. Модуль SimulatedTemperatureSensor создает данные имитируемой среды. Модуль sqlFunction принимает данные и форматирует их для базы данных. В этом разделе показано, как настроить базу данных SQL для хранения данных температуры, полученных с датчиков.

Выполните следующие команды на устройстве IoT Edge. Эти команды подключаются к модулю sql, запущенному на устройстве, и который создает базу данных и таблицу для хранения отправляемых ему данных температуры.

  1. В программе командной строки устройства IoT Edge подключитесь к базе данных.

    sudo docker exec -it sql bash
    
  2. Откройте программу командной строки для SQL.

    /opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P 'Strong!Passw0rd'
    
  3. Создайте базу данных:

    CREATE DATABASE MeasurementsDB
    ON
    (NAME = MeasurementsDB, FILENAME = '/var/opt/mssql/measurementsdb.mdf')
    GO
    
  4. Определите таблицу.

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

Можно настроить файл Docker SQL Server таким образом, чтобы SQL Server автоматически настраивался для развертывания на нескольких устройствах IoT Edge. Дополнительные сведения см. в статье о демонстрационном проекте контейнера Microsoft SQL Server.

Просмотр локальных данных

После создания таблицы модуль sqlFunction начинает сохранять данные в локальную базу данных SQL Server 2017 на устройстве IoT Edge.

Изнутри программы командной строки SQL выполните следующую команду, чтобы просмотреть данные отформатированной таблицы:

SELECT * FROM MeasurementsDB.dbo.TemperatureMeasurements
GO

View contents of local database

Очистка ресурсов

Если вы планируете перейти к следующей рекомендуемой статье, можно сохранить созданные и повторно используемые ресурсы и конфигурации. Это же устройство IoT Edge также можно использовать в качестве тестового устройства.

В противном случае чтобы избежать расходов, можно удалить локальные конфигурации и ресурсы Azure, созданные в рамках этой статьи.

Удаление ресурсов Azure

Удаление ресурсов и групп ресурсов Azure является необратимым. Будьте внимательны, чтобы случайно не удалить не ту группу ресурсов или не те ресурсы. Если вы создали центр Интернета вещей в группе ресурсов, содержащей ресурсы, которые нужно сохранить, удалите только ресурс Центра Интернета вещей, не удаляя всю группу ресурсов.

Удаление ресурсов:

  1. Войдите на портал Azure и щелкните Группы ресурсов.

  2. Выберите группу ресурсов, содержащую тестовые ресурсы IoT Edge.

  3. Просмотрите список ресурсов, содержащихся в группе ресурсов. Если вы хотите удалить их все, щелкните Удалить группу ресурсов. Если вы хотите удалить только некоторые из них, щелкните нужные ресурсы отдельно.

В этом руководстве вы создали модуль службы "Функции Azure", который содержит код для фильтрации необработанных данных, созданных вашим устройством IoT Edge. Когда вы будете готовы к созданию собственных модулей, вы можете узнать больше о том, как разрабатывать модули Azure IoT Edge с помощью Visual Studio Code.

Следующие шаги

Если вы хотите применить другой метод хранения данных на пограничных устройствах, прочитайте о том, как использовать хранилище BLOB-объектов Azure в IoT Edge.