練習 - 建立儲存體帳戶並部署虛擬相機

已完成

在本單元中,您將建立 Azure 儲存體帳戶,然後在 Node.js 中實作模擬相機陣列,以將野生動物相片上傳至儲存體帳戶。 儲存體帳戶會儲存您所部署相機拍攝到的相片。

建立儲存體帳戶並將野生動物相片上傳至帳戶是建置端對端解決方案的第一個步驟,其會示範如何結合 Azure 服務來建立包含雲端服務及 AI 的複雜系統。

建立儲存體帳戶

首先,您會使用 Azure Cloud Shell 來建立 Azure 儲存體帳戶。 Cloud Shell 提供以瀏覽器為基礎的命令列,可讓您用來執行 Azure 命令。 Cloud Shell 是在您自己電腦上安裝 Azure CLI 以外的替代方案。

注意

至於要使用 CLI 或 Cloud Shell,通常是依據個人喜好決定。 Cloud Shell 的優點之一是不需要安裝任何軟體。 另一個優點是您不需要像執行 CLI 一樣定期更新 Cloud Shell。

  1. 在瀏覽器中,移至 Azure 入口網站。 如果系統提示您登入,請使用 Microsoft 帳戶登入。

  2. 在入口網站的全域控制項中,選取 [Azure Cloud Shell]

    Screenshot that shows the Azure Cloud Shell icon highlighted in the Azure portal global controls.

    開啟 Azure Cloud Shell

    當系統提示您選擇程式設計語言,請選取 [Bash]。 當系統提示您允許 Cloud Shell 建立儲存體帳戶 (未裝載任何儲存體),請選擇 [建立新的儲存體] 選項。 Cloud Shell 會為您裝載新的儲存體,並開啟 [命令提示字元] 視窗。 您會看到歡迎訊息,然後看到命令提示字元。

    您也可以在另一個瀏覽器視窗中前往 https://shell.Azure.com 以開啟 Cloud Shell。

  3. 下一個工作是建立資源群組,以保存儲存體帳戶及其他組成解決方案的 Azure 資源。 請確定在 Cloud Shell 中選取的語言是 Bash。 然後,在 Azure 美國中南部區域中,建立名為 polar-bear-rg 的資源群組:

    az group create --name polar-bear-rg --location southcentralus
    

    若要在 Cloud Shell 中貼上命令,請選取 Shift+Insert。 若要將文字從 Cloud Shell 複製到剪貼簿,請選取 Ctrl+Insert。

  4. 執行下列命令,以儲存您想要用於儲存體帳戶的名稱。 在命令中,以您要使用的名稱取代 <account-name>。 您稍後會在 $ACCOUNT_NAME 欄位中參考帳戶名稱。

    ACCOUNT_NAME="<account-name>"
    

    注意

    儲存體帳戶名稱的長度必須介於 3 到 24 個字元之間,且只能包含數字和小寫字母。 帳戶名稱在 Azure 中不能重複。 如果因為儲存體帳戶名稱已在使用中而導致命令失敗,請變更名稱,然後再試一次。

  5. 執行下列命令,以在 polar-bear-rg 資源群組中建立儲存體帳戶:

    az storage account create --name $ACCOUNT_NAME --resource-group polar-bear-rg --location southcentralus --sku Standard_LRS
    
  6. Azure 儲存體帳戶支援四種儲存體類型:Blob、資料表、檔案和佇列。 Azure Blob 儲存體會為文字和二進位資料提供可大幅調整的物件存放區。 上傳至儲存體帳戶的相片會儲存為 Blob。 在將 Blob 上傳至儲存體帳戶之前,您必須先建立用來儲存這些 Blob 的容器。

    執行下列命令,以在儲存體帳戶中建立名為 photos 的容器:

    az storage container create --name photos --account-name $ACCOUNT_NAME
    
  7. 在 Cloud Shell 中執行下列命令,以列出儲存體帳戶的存取金鑰:

    az storage account keys list --account-name $ACCOUNT_NAME
    
  8. 主要存取金鑰為 key1 屬性值,其中包含長串的字母和數字。 從輸出複製主要存取金鑰,並將其貼上至文字檔,讓您可於稍後擷取金鑰。

    請記住,您可以選取 Ctrl+Insert 將文字從 Cloud Shell 複製到剪貼簿。

您現在擁有用於儲存相片的儲存體帳戶,以及用來儲存儲存體帳戶的容器。 現在,讓我們部署一些相機來拍攝野生動物相片,並將其上傳至 Blob 儲存體。

部署模擬相機陣列

下一個工作是建立 Node.js 應用程式,用來模擬以動作啟動的相機陣列。 相機會將在野外所拍攝相片上傳到儲存體帳戶的 photos 容器。

  1. 如果電腦上未安裝 Node.js,請前往 https://node.js.org/ 並立即安裝。 若要檢查是否已安裝 Node.js 以及安裝的版本,請在命令提示字元或終端機視窗中執行此命令:

    node -v
    

    如果已安裝 Node.js,輸出就會顯示其版本號碼。 如果版本號碼小於 8.0,請下載並安裝最新版本

  2. 在硬碟上建立目錄以作為專案目錄。 然後,在命令提示字元中執行 cd,以變更至該目錄。

  3. 執行下列命令,將專案目錄初始化以裝載 Node.js 專案並安裝套件:

    npm init -y
    npm install azure-storage --save
    

    azure-storage 套件為 Node.js 應用程式提供 Azure 儲存體 (包括 Blob 儲存體) 的程式設計介面。

  4. 當安裝完成後,在專案目錄中建立名為 photos 的子目錄。 下載相機影像的 .zip 檔案。 將檔案解壓縮,然後將 .zip 檔案中的 30 個 .JPG 檔案複製到 photos 子目錄中。 模擬相機會將這些影像上傳至 Blob 儲存體。

    下列影像是資料集內影像的範例。 影像中所顯示的野生動物包括北極狐、北極熊以及海象。

    Two photos of Arctic foxes, four photos of polar bears, and two photos of walruses.

  5. 在專案目錄中,使用 Visual Studio Code 建立名為 cameras.json 的檔案。 在檔案中貼上下列 JSON:

    [
        {
            "deviceId" : "polar_cam_0001",
            "latitude" : 75.401451,
            "longitude" : -95.722518
        },
        {
            "deviceId" : "polar_cam_0002",
            "latitude" : 75.027715,
            "longitude" : -96.041859
        },
        {
            "deviceId" : "polar_cam_0003",
            "latitude" : 74.996653,
            "longitude" : -96.601780
        },
        {
            "deviceId" : "polar_cam_0004",
            "latitude" : 75.247701,
            "longitude" : -96.074436
        },
        {
            "deviceId" : "polar_cam_0005",
            "latitude" : 75.044926,
            "longitude" : -93.651951
        },
        {
            "deviceId" : "polar_cam_0006",
            "latitude" : 75.601571,
            "longitude" : -95.294407
        },
        {
            "deviceId" : "polar_cam_0007",
            "latitude" : 74.763102,
            "longitude" : -95.091160
        },
        {
            "deviceId" : "polar_cam_0008",
            "latitude" : 75.473988,
            "longitude" : -94.069432
        },
        {
            "deviceId" : "polar_cam_0009",
            "latitude" : 75.232307,
            "longitude" : -96.277683
        },
        {
            "deviceId" : "polar_cam_0010",
            "latitude" : 74.658811,
            "longitude" : -93.783787
        }
    ]
    

    此檔案會定義 10 部虛擬相機,以將相片上傳至 Blob 儲存體。 每部相機執行個體都會包含裝置識別碼,以及指定相機位置的緯度與經度。

    這些緯度與經度值分別對應至北加拿大康沃利斯島海岸上的點。 該島是加拿大中最容易發現北極熊的地點之一。 康沃利斯島鄰近巴瑟斯特島,這座島是北極熊路國家野生動物保護區的所在地。

  6. 在專案目錄中建立名為 run.js 的檔案。 將下列程式碼貼到 檔案中:

    'use strict';
    
    // Connect to the storage account
    var storage = require('azure-storage');
    
    var blobService = storage.createBlobService(
        process.env.ACCOUNT_NAME,
        process.env.ACCOUNT_KEY
    );
    
    // Load image file names and create an array of cameras
    var fs = require('fs');
    
    fs.readdir('photos', (err, files) => {
        var cameras = JSON.parse(fs.readFileSync('cameras.json', 'utf8')).map(
            camera => new Camera(
                camera.deviceId,
                camera.latitude,
                camera.longitude,
                blobService,
                files
            )
        );
    
        // Start the cameras
        cameras.forEach(camera => {
            camera.start();
        });
    });
    
    class Camera {
        constructor(id, latitude, longitude, blobService, files) {
            this._id = id;
            this._latitude = latitude;
            this._longitude = longitude;
            this._blobService = blobService;
            this._files = files.slice(0);
            this._interval = 300000;
        }
    
        start() {
            // Register the first callback
            setTimeout(this.timer, Math.random() * this._interval, this);
            console.log('Started ' + this._id);
        }
    
        timer(self) {
            // Randomly select a photo
            var index = Math.floor(Math.random() * self._files.length);
            var filename = self._files[index]
    
            // Define the metadata to be written to the blob
            var metadata = {
                'latitude': self._latitude,
                'longitude': self._longitude,
                'id': self._id
            };
    
            // Upload the blob
            self._blobService.createBlockBlobFromLocalFile('photos', filename, 'photos/' + filename, { 'metadata': metadata }, (err, result) => {
                if (!err) {
                    console.log(self._id + ': Uploaded ' + filename);
                }
                else {
                    console.log(self._id + ': Error uploading ' + filename);
                }
            });
    
            // Register the next callback
            setTimeout(self.timer, Math.random() * self._interval, self);
        }
    }
    

    此程式碼會使用 ECMAScript 6 (ES6) 中的類別支援來定義名為 Camera 的類別。 然後其會建立 10 個 Camera 執行個體,並加以啟動。 每部相機都會使用隨機計時器,其會每隔幾分鐘觸發一次,以將野生動物影像上傳至 Blob 儲存體中的 photos 容器。 影像會從專案目錄中 photos 子目錄的檔案隨機選取。 每個建立的 Blob 都會包含中繼資料,用於識別已上傳相片的相機及相機位置。

  7. 如果您執行的是 Windows,請執行下列命令建立一對環境變數。 在此命令中,使用您稍早建立的儲存體帳戶名稱取代 STORAGE_ACCOUNT_NAME,並使用儲存體帳戶的存取金鑰取代 STORAGE_ACCOUNT_KEY

    set ACCOUNT_NAME=STORAGE_ACCOUNT_NAME
    set ACCOUNT_KEY=STORAGE_ACCOUNT_KEY
    

    如果您執行 Linux 或macOS,或執行 Windows 命令時收到認證錯誤,請改用下列命令:

    export ACCOUNT_NAME=STORAGE_ACCOUNT_NAME
    export ACCOUNT_KEY=STORAGE_ACCOUNT_KEY
    

    在執行階段中,run.js 會讀取這些環境變數,並使用這些變數連線到儲存體帳戶。 在環境變數中儲存「祕密」之類的資訊,會比將其內嵌在原始程式碼中更為安全。 如果您關閉執行這些命令的命令提示字元或終端機視窗,則必須重新予以執行,才能執行 run.js

  8. 執行下列程式碼以執行 run.js

    node run.js
    
  9. 確認您看到的輸出類似如下列範例。 此輸出表示全部 10 部相機皆正在執行:

    Started polar_cam_0001
    Started polar_cam_0002
    Started polar_cam_0003
    Started polar_cam_0004
    Started polar_cam_0005
    Started polar_cam_0006
    Started polar_cam_0007
    Started polar_cam_0008
    Started polar_cam_0009
    Started polar_cam_0010
    
  10. 在接下來的一兩分鐘內,確認您看到類似下列範例的輸出。 每一行都會對應至由其中一部虛擬相機上傳至 Blob 儲存體的相片:

    polar_cam_0001: Uploaded image_19.jpg
    polar_cam_0005: Uploaded image_26.jpg
    polar_cam_0003: Uploaded image_11.jpg
    

    因為 run.js 會使用亂數產生器決定要上傳的相片及上傳時間,所以結果會與上方範例顯示的結果不同。

  11. run.js 執行,直到上傳三個或更多 Blob 為止。 然後返回正在執行 run.js 的命令提示字元或終端機視窗,並選取 Ctrl+C 停止執行 run.js

  12. 在瀏覽器中,移至 Azure 入口網站。 開啟您先前建立的儲存體帳戶,然後開啟 photos 容器。 確認容器內有數個 .JPG 影像,如下列範例所示:

    Screenshot that shows images uploaded to the photos container.

    上傳至 photos 容器的影像

  13. 選取其中一個 Blob 以顯示 Blob 詳細資料,並查看 Blob 的中繼資料。 確認 Blob 中繼資料包含名為 latitudelongitudeid 的屬性:

    Screenshot that shows blob metadata fields in the Metadata pane.

    檢視 Blob 中繼資料

  14. 開啟 Blob 以檢視實際影像:

    • 選取省略符號 (),然後選取 [檢視]>[編輯]。 重複此動作,以檢視數個 Blob 的影像。

    哪些影像包含北極熊,而哪些影像不包含?