分享方式:


處理 Azure Blob 儲存體中的變更摘要

變更摘要提供您儲存體帳戶中 Blob 和 Blob 中繼資料所發生全部變更的交易記錄。 本文說明如何使用 Blob 變更摘要處理器程式庫來讀取變更摘要記錄。

若要深入了解變更摘要,請參閱 Azure Blob 儲存體中的變更摘要

設定您的專案

本節將逐步引導您準備專案,以使用適用於 .NET 的 Blob 變更摘要用戶端連結庫。

安裝套件

從您的項目目錄中,使用 dotnet add package 命令安裝適用於 .NET 的 Azure 儲存體 Blob 變更摘要用戶端連結庫的套件。 在此範例中,我們會將 --prerelease 旗標新增至 命令,以安裝最新的預覽版本。

dotnet add package Azure.Storage.Blobs.ChangeFeed --prerelease

本文中的程式代碼範例也會使用 Azure Blob 儲存體Azure 身分識別套件。

dotnet add package Azure.Identity
dotnet add package Azure.Storage.Blobs

新增 using 指示詞

將下列 using 指示詞新增至您的程式代碼檔案:

using Azure.Identity;
using Azure.Storage.Blobs;
using Azure.Storage.Blobs.ChangeFeed;

建立用戶端物件

若要將應用程式連線到 Blob 記憶體,請建立 類別的 BlobServiceClient 實例。 下列範例示範如何使用 來建立客戶端物件 DefaultAzureCredential 以進行授權。 若要深入瞭解,請參閱 授權存取權並連線到 Blob 記憶體。 若要使用變更摘要,您需要 Azure RBAC 內建角色 記憶體 Blob 數據讀取器 或更新版本。

// TODO: Replace <storage-account-name> with the name of your storage account
string accountName = "<storage-account-name>";

BlobServiceClient client = new(
        new Uri($"https://{accountName}.blob.core.windows.net"),
        new DefaultAzureCredential());

用戶端物件會當做參數傳遞至本文所示的一些方法。

讀取變更摘要中的記錄

注意

變更摘要是您儲存體帳戶中不可變且唯讀的實體。 任意數量的應用程式可以視需要同時或個別讀取和處理變更摘要。 當應用程式讀取記錄時,不會從變更摘要中移除記錄。 每個取用讀取器的讀取或逐一查看狀態都是獨立的,而且只會由您的應用程式維護。

下列程式代碼範例會逐一查看變更摘要中的所有記錄、將它們新增至清單,然後傳回變更摘要事件清單:

public async Task<List<BlobChangeFeedEvent>> ChangeFeedAsync(BlobServiceClient client)
{
    // Create a new BlobChangeFeedClient
    BlobChangeFeedClient changeFeedClient = client.GetChangeFeedClient();

    List<BlobChangeFeedEvent> changeFeedEvents = [];

    // Get all the events in the change feed
    await foreach (BlobChangeFeedEvent changeFeedEvent in changeFeedClient.GetChangesAsync())
    {
        changeFeedEvents.Add(changeFeedEvent);
    }

    return changeFeedEvents;
}

下列程式代碼範例會從變更摘要事件清單中列印一些值:

public void showEventData(List<BlobChangeFeedEvent> changeFeedEvents)
{
    foreach (BlobChangeFeedEvent changeFeedEvent in changeFeedEvents)
    {
        string subject = changeFeedEvent.Subject;
        string eventType = changeFeedEvent.EventType.ToString();
        BlobOperationName operationName = changeFeedEvent.EventData.BlobOperationName;

        Console.WriteLine("Subject: " + subject + "\n" +
        "Event Type: " + eventType + "\n" +
        "Operation: " + operationName.ToString());
    }
}

繼續從儲存的位置讀取記錄

您可以選擇將讀取位置儲存在變更摘要中,日後再繼續逐一查看記錄。 您可以取得變更摘要資料指標來儲存讀取位置。 數據指標是一個 字串 ,您的應用程式可以用任何對應用程式設計有意義的方式儲存該字串,例如,儲存至檔案或資料庫。

此範例會逐一查看變更摘要中的所有記錄,將其新增至清單,並儲存資料指標。 清單和資料指標會傳回給呼叫端。

public async Task<(string, List<BlobChangeFeedEvent>)> ChangeFeedResumeWithCursorAsync(
    BlobServiceClient client,
    string cursor)
{
    // Get a new change feed client
    BlobChangeFeedClient changeFeedClient = client.GetChangeFeedClient();
    List<BlobChangeFeedEvent> changeFeedEvents = new List<BlobChangeFeedEvent>();

    IAsyncEnumerator<Page<BlobChangeFeedEvent>> enumerator = changeFeedClient
        .GetChangesAsync(continuationToken: cursor)
        .AsPages(pageSizeHint: 10)
        .GetAsyncEnumerator();

    await enumerator.MoveNextAsync();

    foreach (BlobChangeFeedEvent changeFeedEvent in enumerator.Current.Values)
    {

        changeFeedEvents.Add(changeFeedEvent);
    }

    // Update the change feed cursor. The cursor is not required to get each page of events,
    // it's intended to be saved and used to resume iterating at a later date.
    cursor = enumerator.Current.ContinuationToken;
    return (cursor, changeFeedEvents);
}

記錄的串流處理

您可以選擇在變更摘要認可變更摘要時處理變更摘要記錄。 請參閱規格。 變更事件平均需要 60 秒的時間發佈到變更摘要。 建議在指定輪詢間隔時,輪詢這段期間的新變更。

此範例會定期輪詢變更。 如果存在變更記錄,則此程式碼會處理這些記錄,並儲存變更摘要資料指標。 如此一來,如果處理程序停止後再次重新開始,應用程式就可以使用資料指標從上次離開的位置繼續處理記錄。 本範例會將游標儲存到本機檔案以供示範之用,但您的應用程式可以將它儲存在任何對您案例最有意義的表單中。

public async Task ChangeFeedStreamAsync(
    BlobServiceClient client,
    int waitTimeMs,
    string cursor)
{
    // Get a new change feed client
    BlobChangeFeedClient changeFeedClient = client.GetChangeFeedClient();

    while (true)
    {
        IAsyncEnumerator<Page<BlobChangeFeedEvent>> enumerator = changeFeedClient
        .GetChangesAsync(continuationToken: cursor).AsPages().GetAsyncEnumerator();

        while (true)
        {
            var result = await enumerator.MoveNextAsync();

            if (result)
            {
                foreach (BlobChangeFeedEvent changeFeedEvent in enumerator.Current.Values)
                {
                    string subject = changeFeedEvent.Subject;
                    string eventType = changeFeedEvent.EventType.ToString();
                    BlobOperationName operationName = changeFeedEvent.EventData.BlobOperationName;

                    Console.WriteLine("Subject: " + subject + "\n" +
                        "Event Type: " + eventType + "\n" +
                        "Operation: " + operationName.ToString());
                }

                // Helper method to save cursor
                SaveCursor(enumerator.Current.ContinuationToken);
            }
            else
            {
                break;
            }

        }
        await Task.Delay(waitTimeMs);
    }
}

void SaveCursor(string cursor)
{
    // Specify the path to the file where you want to save the cursor
    string filePath = "path/to/cursor.txt";

    // Write the cursor value to the file
    File.WriteAllText(filePath, cursor);
}

讀取特定時間範圍內的記錄

您可以讀取落在特定時間範圍內的記錄。 此範例會逐一查看屬於特定日期和時間範圍內之變更摘要中的所有記錄、將它們新增至清單,並傳回清單:

async Task<List<BlobChangeFeedEvent>> ChangeFeedBetweenDatesAsync(BlobServiceClient client)
{
    // Get a new change feed client
    BlobChangeFeedClient changeFeedClient = client.GetChangeFeedClient();
    List<BlobChangeFeedEvent> changeFeedEvents = new List<BlobChangeFeedEvent>();

    // Create the start and end time.  The change feed client will round start time down to
    // the nearest hour, and round endTime up to the next hour if you provide DateTimeOffsets
    // with minutes and seconds.
    DateTimeOffset startTime = new DateTimeOffset(2024, 3, 1, 0, 0, 0, TimeSpan.Zero);
    DateTimeOffset endTime = new DateTimeOffset(2024, 6, 1, 0, 0, 0, TimeSpan.Zero);

    // You can also provide just a start or end time.
    await foreach (BlobChangeFeedEvent changeFeedEvent in changeFeedClient.GetChangesAsync(
        start: startTime,
        end: endTime))
    {
        changeFeedEvents.Add(changeFeedEvent);
    }

    return changeFeedEvents;
}

您提供的開始時間會無條件捨去到最接近的小時,而結束時間則會無條件進入到最接近的小時。 使用者可能會看到在開始時間前和結束時間後發生的事件。 在開始時間到結束時間之間發生的某些事件也可能不會出現。 這是因為可能記錄了開始時間前一小時內或結束時間後一小時內發生的事件。

下一步