Bootiful Azure:物件儲存服務 (5/6)

工程 | Josh Long | 2019 年 1 月 17 日 | ...

這是共 6 部分系列的第 5 部分,每週一和週四都會發布新文章,介紹適用於 Spring 開發人員的 Microsoft Azure。 如果沒有 Microsoft 的 Asir Vedamuthu Selvasingh、Yitao Dong、Bruno Borges、Brian Benz 和 Theresa Nguyen 的投入,我不可能將其組合在一起。您可以在 Github 上找到本系列的程式碼。在您閱讀這些文章時,請在 Twitter (@starbuxman) 上告訴我您的意見或問題。您也可以在我的 Spring Tips (@SpringTipsLive) 文章 Bootiful Azure 中了解更多關於 Microsoft Azure 的資訊

以下是所有文章:

現在讓我們轉向一些更……平凡的東西。理想情況下,您甚至不會經常考慮它。應用程式通常有儲存需求:它們可能需要儲存上傳的使用者內容(例如圖片或文件的二進位資料)、產生的成品(例如 PDF 檔案、視訊、音樂等)。它們可能想要儲存日誌。不難想到應用程式可能想要持久儲存的東西。

這些應用程式可以使用檔案系統,例如本地電腦上的檔案系統或網路連接的檔案系統,如 NFS(網路檔案系統)。我將使用 NFS 來泛指任何網路連接的檔案系統,如 Samba、NFS(那些使用 NFS 協定掛載的檔案系統)本身或傳統選項,如 DAC、FAL 等。NFS 選項提供類似檔案系統的檔案介面,通常採用階層格式。NFS 選項很有趣,因為它們就像我們都熟悉的檔案系統,而且每個人都知道如何使用檔案系統,對吧?當然,一切都看起來像 Windows 檔案總管中表達的階層?或 macOS Finder?但事實上,它們彼此之間看起來完全不一樣...

仔細想想,當我說 NFS 選項檔案系統時,我不得不使用「像」。有些支援比其他檔案系統更細緻的權限模型。有些支援編碼和複製附加到樹狀結構中檔案和目錄的元資料。有些支援針對不同操作的不同速度保證;有些檔案系統可能會針對讀取而非寫入進行最佳化。有些可能會針對目錄遍歷進行最佳化。客戶端對檔案讀取或寫入的觀點會因使用的客戶端而異。(在所有複製節點上,寫入是否立即一致?)

即使我們假設所有我們想要寫入的檔案系統都與 POSIX 相容 - 您可以使用 int open(const char *path, int flags)java.io.File - 這可能不適用於我們的客戶端。如果客戶端不「說」檔案系統,並且更喜歡以其他方式操作資料怎麼辦?如果客戶端只能說 HTTP 呢?或者如果它想要說 Bittorrent 以更有效地通過點對點網路整合下載呢?

由於這些原因以及更多原因,Amazon Web Services 推出了 S3,即簡單雲端儲存服務(明白了?「S」乘以 3?「S3」?),自那以後,它已成為所有其他雲端供應商都需要支援的流行標準。對於 Microsoft Azure,物件儲存服務 (OSS) 提供了類似 S3 的體驗。它不是 POSIX 檔案系統。您可以直接使用其 API,就像我們在這裡所做的一樣,但是 也可以使用 S3Proxy 來代理使用 AWS S3 客戶端寫入 OSS,這其中有數不清的客戶端!Azure 的物件儲存服務確實枯燥乏味,這正是您在處理像檔案型資料的持續卷這樣基本的事物時所希望的。它甚至提供一個獨立的瀏覽器,稱為 Microsoft Azure Storage Explorer,它可以在 Linux、Macintosh 和 Windows 上執行(沒錯!)。該獨立瀏覽器可讓您查詢 OSS 儲存體以及 CosmosDB 資料。這樣是否方便?您當然可以使用 az CLI 或 API 本身。我們將使用 Spring 集成來用於 Java API。

配置 Azure 物件儲存服務

您必須建立一個分配給現有資源群組 bootiful 的 Azure 物件儲存服務帳戶 (bootiful)。然後,建立一個分配給剛建立的儲存帳戶的儲存容器 (files)。這是一個範例腳本。

#!/usr/bin/env bash

rg=$1
accountname=bootiful

az storage account create --name ${accountname} --resource-group ${rg}
az storage container create -n files --account-name ${accountname}

使用以下命令來確定連接到應用程式所需的連接字串。

az storage account show-connection-string --resource-group bootiful --name bootiful

請記下連接字串以供稍後使用。

將 Azure 物件儲存服務引入您的 Spring 應用程式

com.microsoft.azure: azure-storage-spring-boot-starter 新增至您應用程式的建置檔案。確保您已為 azure.storage.connection-string 屬性指定了 OSS 連接字串。

我們將讀取應用程式 src/main/resources 目錄中貓圖片的位元組,然後將這些位元組作為「區塊 blob」寫入物件儲存服務。還有其他介面可以讓您與 OSS 通訊,但就我們的目的而言,將其視為「容器」(事物的邏輯分組,幾乎就像 S3 用語中的目錄或儲存桶)和「blob」的集合是非常自然的。Blob 基本上是一個檔案,帶有與其關聯的名稱和元資料。以下範例所做的只是將貓照片的位元組儲存到名為 files 的容器中,該容器的名稱以 cat- 為前綴,並以 .jpg 為後綴。

package com.example.bootifulazure;

import com.microsoft.azure.storage.CloudStorageAccount;
import com.microsoft.azure.storage.StorageException;
import com.microsoft.azure.storage.blob.CloudBlobContainer;
import com.microsoft.azure.storage.blob.CloudBlockBlob;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.event.EventListener;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Component;

import java.io.InputStream;
import java.net.URISyntaxException;
import java.util.UUID;

@Log4j2
@Component
class ObjectStorageServiceDemo {

    private final CloudStorageAccount cloudStorageAccount;
    private final Resource resource;
    private final CloudBlobContainer files;

    ObjectStorageServiceDemo(
        CloudStorageAccount csa,
        @Value("classpath:/cat.jpg") Resource cat) throws URISyntaxException, StorageException {
        this.resource = cat;
        this.cloudStorageAccount = csa;
        this.files = this.cloudStorageAccount
            .createCloudBlobClient()
            .getContainerReference("files");
    }

    @EventListener(ApplicationReadyEvent.class)
    public void demo() throws Exception {
        CloudBlockBlob blockBlobReference = this.files.getBlockBlobReference("cat-" + UUID.randomUUID().toString() + ".jpg");
        try (InputStream in = this.resource.getInputStream()) {
            blockBlobReference.upload(in, this.resource.contentLength());
            log.info("uploaded blockblob to " + blockBlobReference.getStorageUri());
        }

    }
}

特定於 Microsoft Azure 的位元並非微不足道。我們取得對容器的引用,然後寫入該容器,然後記錄資源的可定址 URI。多麼平淡!這正是您在像檔案系統這樣的計算系統原始物件中所希望的。它應該平淡。老實說,我更高興能使用 Java 7 的 try-with-resources 語法來用於 Autocloseable InputStream 引用!

取得 Spring 電子報

隨時掌握 Spring 電子報的最新消息

訂閱

領先一步

VMware 提供培訓和認證,以加速您的進度。

了解更多

獲得支援

Tanzu Spring 在一個簡單的訂閱中提供 OpenJDK™、Spring 和 Apache Tomcat® 的支援和二進位檔案。

了解更多

即將舉行的活動

查看 Spring 社群中所有即將舉行的活動。

查看全部