適用於:
IoT Edge 1.4
這很重要
IoT Edge 1.5 LTS 和 IoT Edge 1.4 是 支援的版本。 如果您使用的是舊版,請參閱 更新 IoT Edge。
部署 SQL Server 模組,以將資料儲存在執行 Azure IoT Edge 搭配 Linux 容器的裝置上。
使用 Azure IoT Edge 和 SQL Server 在邊緣儲存和查詢資料。 Azure IoT Edge 具有基本儲存體功能,可在裝置離線時快取訊息,然後在重新建立連線時轉送訊息。 但是,您可能需要更高級的存儲功能,例如能夠在本地查詢數據。 您的 IoT Edge 裝置可以使用本機資料庫來執行更複雜的運算,而不需要維護與 IoT 中樞的連線。
本文提供將 SQL Server 資料庫部署至 IoT Edge 裝置的指示。 在 IoT Edge 裝置上執行的 Azure Functions 會建構傳入資料,然後將它傳送至資料庫。 本文中的步驟也可以套用至在容器中運作的其他資料庫,例如 MySQL 或 PostgreSQL。
在本教學課程中,您將瞭解如何:
- 使用 Visual Studio Code 建立 Azure 函式
- 將 SQL 資料庫部署至 IoT Edge 裝置
- 使用 Visual Studio Code 建置模組,並將其部署至 IoT Edge 裝置
- 檢視產生的資料
如果您沒有 Azure 帳戶,請在開始之前建立 免費帳戶 。
先決條件
開始本教學課程之前,您應該先完成上一個教學課程,以設定 Linux 容器開發的開發環境: 使用 Visual Studio Code 開發 Azure IoT Edge 模組。 完成該教學課程後,您應該具備下列必要條件:
- Azure 中的免費或標準層 IoT 中樞 。
- 執行 Azure IoT Edge 搭配 Linux 容器的 AMD64 裝置。 您可以使用快速入門來設定 Linux 裝置 或 Windows 裝置。
- ARM 裝置 (例如 Raspberry Pis) 無法執行 SQL Server。 如果您想要在 ARM 裝置上使用 SQL,您可以使用 Azure SQL Edge。
- 容器登錄,例如 Azure 容器登錄。
- 使用 Azure IoT Edge 和 Azure IoT 中樞延伸模組設定的 Visual Studio Code。 適用於 Visual Studio Code 延伸模組的 Azure IoT Edge 工具處於維護模式。
- 在您的開發機器上下載並安裝 Docker 相容的容器管理系統 。 將其設定為執行 Linux 容器。
本教學課程會使用 Azure Functions 模組將資料傳送至 SQL Server。 若要使用 Azure Functions 開發 IoT Edge 模組,請在開發電腦上安裝下列其他必要條件:
建立函數專案
要將資料傳送到資料庫中,您需要一個能夠正確建構資料的模組,然後將其儲存在表格中。
建立新專案
下列步驟示範如何使用 Visual Studio Code 和 Azure IoT Edge 延伸模組來建立 IoT Edge 函式。
開啟 Visual Studio Code。
選取 [ 檢視>命令面板] 來開啟 Visual Studio Code 命令面板。
在命令面板中,輸入並執行命令 Azure IoT Edge:新的 IoT Edge 解決方案。 在命令選項板中,提供下列資訊來建立您的解決方案:
領域 價值觀 選擇資料夾 選擇 Visual Studio Code 在開發電腦上建立解決方案檔案的位置。 提供解決方案名稱 輸入解決方案的描述性名稱,例如 SqlSolution,或接受預設值。 選取模組範本 選擇 [Azure Functions - C#]。 提供模組名稱 將模組命名為 sqlFunction。 提供模組的Docker映像儲存庫 映像儲存庫包含容器登錄的名稱和容器映像的名稱。 您的容器映像會從最後一個步驟預先填入。 將 localhost:5000 取代為 Azure 容器登錄中的 登入伺服器 值。 您可以從 Azure 入口網站中容器登錄的 [概觀] 頁面擷取登入伺服器。
最後一個字串看起來像 <註冊表名稱>.azurecr.io/sqlfunction。[Visual Studio Code] 視窗會載入您的 IoT Edge 解決方案工作區。
新增您的登錄認證
環境檔案會儲存容器登錄的認證,並與 IoT Edge 執行階段共用。 執行階段需要這些認證,才能將您的私人映像提取到 IoT Edge 裝置上。
IoT Edge 延伸模組會嘗試從 Azure 提取容器登錄認證,並將其填入環境檔案中。 檢查您的認證是否已包含。 如果沒有,請立即添加它們:
- 在 Visual Studio Code 總管中,開啟 .env 檔案。
- 使用您從 Azure 容器登錄複製的 使用者名稱 和 密碼 值來更新欄位。
- 儲存此檔案。
備註
本教學課程會使用 Azure Container Registry 的系統管理員登入認證,方便開發和測試案例。 當您準備好進行生產案例時,建議您使用最低許可權驗證選項,例如服務主體。 如需詳細資訊,請參閱 管理容器登錄的存取權。
選取您的目標架構
您必須選取每個解決方案的目標架構,因為容器的建置和執行方式會針對每個架構類型不同。 預設值為 Linux AMD64。
開啟命令面板並搜尋 Azure IoT Edge:設定 Edge 解決方案的預設目標平台,或選取視窗底部側邊列中的捷徑圖示。
在指令選項板中,從選項清單中選取目標架構。 在本教學課程中,我們使用 Ubuntu 虛擬機器作為 IoT Edge 裝置,因此會保留預設的 amd64。
使用自訂程式碼更新模組
在 Visual Studio Code 總管中,開啟 模組>sqlFunction>sqlFunction.csproj。
尋找套件參考群組,並新增套件參考以包含 SqlClient。
<PackageReference Include="System.Data.SqlClient" Version="4.5.1"/>儲存 sqlFunction.csproj 檔案。
開啟 sqlFunction.cs 檔案。
將檔案的整個內容取代為下列程式碼:
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;} } }在第 35 行中,將字串 <sql 連接字串> 取代為下列字串。 [資料來源] 屬性會參考尚不存在的 SQL Server 容器。 您將在下一節中使用名稱 SQL 建立它。 為 Password 關鍵字選擇強式密碼。
Data Source=tcp:sql,1433;Initial Catalog=MeasurementsDB;User Id=SA;Password=<YOUR-STRONG-PASSWORD>;TrustServerCertificate=False;Connection Timeout=30;儲存 sqlFunction.cs 檔案。
新增 SQL Server 容器
部署資訊清單會宣告 IoT Edge 執行階段將安裝在 IoT Edge 裝置上的模組。 您在上一節中提供了製作自訂函式模組的程式碼,但 SQL Server 模組已建置並可在 Microsoft 成品登錄中使用。 您只需要告訴 IoT Edge 執行階段包含它,然後在您的裝置上進行設定。
在 Visual Studio Code 中,選取 [ 檢視>命令面板] 來開啟命令面板。
在命令選項板中,輸入並執行命令 Azure IoT Edge:新增 IoT Edge 模組。 在命令選項板中,提供下列資訊以新增模組:
領域 價值觀 選取部署範本檔案 命令選項板會反白顯示目前解決方案資料夾中的 deployment.template.json 檔案。 選取該檔案。 選取模組範本 選取 現有模組 (輸入完整影像 URL)。 提供模組名稱 輸入 sql。 此名稱符合sqlFunction.cs檔案中連接字串中宣告的容器名稱。 提供模組的 Docker 映像檔 輸入下列 URI,以從 Microsoft 成品登錄提取 SQL Server 容器映像。 對於 Ubuntu 型映像,請使用 mcr.microsoft.com/mssql/server:latest。 對於 Red Hat Enterprise Linux (RHEL) 型映像,請使用mcr.microsoft.com/mssql/rhel/server:latest。Azure SQL Edge 容器映像是 SQL Server 的輕量型容器化版本,可在 IoT Edge 裝置上執行。 它針對邊緣場景進行了優化,可以在 ARM 和 AMD64 設備上運行。
在您的解決方案資料夾中,開啟 deployment.template.json 檔案。
找到 模組 部分。 您應該會看到三個模組。 SimulatedTemperatureSensor 模組預設包含在新解決方案中,並提供測試資料以與其他模組搭配使用。 模組 sqlFunction 是您最初建立並使用新程式碼更新的模組。 最後,模組 sql 是從 Microsoft 成品登錄匯入的。
小提示
SQL Server 模組隨附在部署資訊清單的環境變數中設定的預設密碼。 每當您在生產環境中建立 SQL Server 容器時,都應該 變更預設的系統管理員密碼。
關閉 deployment.template.json 檔案。
建置您的 IoT Edge 解決方案
在先前的各節中,您已建立具有一個模組的解決方案,然後將另一個模組新增至部署資訊清單範本。 SQL Server 模組由 Microsoft 公開裝載,但您必須將 Functions 模組中的程式碼容器化。 在本節中,您會建置解決方案、建立 sqlFunction 模組的容器映像,並將映像推送至容器登錄。
在 Visual Studio Code 中,選取 [ 檢視>終端機] 來開啟整合式終端機。
在 Visual Studio Code 中登入容器登錄,以便將映像推送至登錄。 使用您新增至 .env 檔案的相同 Azure Container Registry (ACR) 認證。 在整合終端機中輸入下列指令:
docker login -u <ACR username> -p <ACR password> <ACR login server>您可能會看到安全警告,建議使用 --password-stdin 參數。 雖然其使用不在本文的範圍之內,但建議遵循此最佳實務。 如需詳細資訊,請參閱 docker login 命令參考。
在 Visual Studio Code 總管中,以滑鼠右鍵按一下 deployment.template.json 檔案,然後選取 [建置和推送 IoT Edge 解決方案]。
建置和推送命令會啟動三個作業。 首先,它會在解決方案中建立名為 config 的新資料夾,以保存完整的部署資訊清單,該資訊清單是根據部署範本和其他解決方案檔案中的資訊建置的。 其次,它會執行
docker build,以根據目標架構的適當 dockerfile 來建置容器映像。 然後,它會執行以將docker push映像儲存庫推送至您的容器登錄。第一次執行此程式可能需要幾分鐘的時間,但下次執行命令時會更快。
您可以確認 sqlFunction 模組已成功推送至容器登錄。 在 Azure 入口網站中,流覽至您的容器登錄。 選取 存放庫 並搜尋 sqlFunction。 其他兩個模組 SimulatedTemperatureSensor 和 sql 不會推送至您的容器登錄,因為它們的存放庫已位於 Microsoft 登錄中。
將解決方案部署至裝置
您可以透過 IoT 中樞在裝置上設定模組,但您也可以透過 Visual Studio Code 存取 IoT 中樞和裝置。 在本節中,您會設定 IoT 中樞的存取權,然後使用 Visual Studio Code 將解決方案部署至 IoT Edge 裝置。
在 Visual Studio Code 總管的 [ Azure IoT 中樞 ] 區段下,展開 [裝置] 以查看您的 IoT 裝置清單。
以滑鼠右鍵按一下您要以部署為目標的裝置,然後選取 [ 建立單一裝置的部署]。
選取組態資料夾中的 deployment.amd64.json 檔案,然後按一下選取 Edge 部署資訊清單。 請勿使用 deployment.template.json 檔案。
在您的裝置下,展開 [模組] 以查看已部署和執行中的模組清單。 按一下重新整理按鈕。 您應該會看到新的 sql 和 sqlFunction 模組與 SimulatedTemperatureSensor 模組以及 $edgeAgent 和 $edgeHub 一起執行。
您還可以檢查所有模塊是否已在您的設備上啟動並運行。 在您的 IoT Edge 裝置上,執行下列命令以查看模組的狀態。
iotedge list模組可能需要幾分鐘才能啟動。 IoT Edge 執行階段必須接收其新的部署資訊清單、從容器執行階段提取模組映像,然後啟動每個新模組。
建立 SQL 資料庫
當您將部署資訊清單套用至裝置時,您會執行三個模組。 SimulatedTemperatureSensor 模組會產生模擬環境資料。 sqlFunction 模組會取得資料,並針對資料庫格式化它。 本節將引導您設定 SQL 資料庫以儲存溫度資料。
在 IoT Edge 裝置上執行下列命令。 這些命令連接到設備上運行的 sql 模塊,並創建一個數據庫和表來保存發送到它的溫度數據。 將 YOUR-STRONG-PASSWORD> 取代<為您在連接字串中選擇的強式密碼。
在 IoT Edge 裝置上的命令列工具中,連線到您的資料庫。
sudo docker exec -it sql bash開啟 SQL 命令工具。
/opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P '<YOUR-STRONG-PASSWORD>'建立您的資料庫:
CREATE DATABASE MeasurementsDB ON (NAME = MeasurementsDB, FILENAME = '/var/opt/mssql/measurementsdb.mdf') GO定義您的表格。
CREATE TABLE MeasurementsDB.dbo.TemperatureMeasurements (measurementTime DATETIME2, location NVARCHAR(50), temperature FLOAT) GO
您可以自訂 SQL Server Docker 檔案,以自動設定要部署在多個 IoT Edge 裝置上的 SQL Server。 如需詳細資訊,請參閱 Microsoft SQL Server 容器示範專案。
檢視本機資料
建立資料表之後,sqlFunction 模組會開始將資料儲存在 IoT Edge 裝置上的本機 SQL Server 2017 資料庫中。
在 SQL 命令工具內,執行下列命令以檢視格式化的資料表資料:
SELECT * FROM MeasurementsDB.dbo.TemperatureMeasurements
GO
清理資源
如果您打算繼續閱讀下一篇建議的文章,您可以保留您建立的資源和組態,並重複使用它們。 您也可以繼續使用相同的 IoT Edge 裝置作為測試裝置。
否則,您可以刪除本機設定和您在本文中建立的 Azure 資源,以避免收費。
刪除 Azure 資源
刪除 Azure 資源和資源群組是不可逆的。 請確定您不會誤刪錯誤的資源群組或資源。 如果您在現有資源群組內建立 IoT 中樞,且該資源群組具有您想要保留的資源,請只刪除 IoT 中樞資源本身,而不是資源群組。
若要刪除資源:
登入 Azure 入口網站,然後選取 [資源群組]。
選取包含 IoT Edge 測試資源的資源群組名稱。
檢閱資源群組中包含的資源清單。 如果您想要刪除所有資源群組,您可以選取 [刪除資源群組]。 如果您只想刪除其中的一部分,您可以按一下每個資源以個別刪除它們。
在本教學課程中,您已建立 Azure Functions 模組,其中包含篩選 IoT Edge 裝置所產生原始資料的程式碼。 當您準備好建置自己的模組時,您可以深入瞭解如何使用 Visual Studio Code 開發 Azure IoT Edge 模組。
後續步驟
如果您想要在邊緣嘗試其他儲存體方法,請閱讀如何在 IoT Edge 上使用 Azure Blob 儲存體。