共用方式為


如何使用 Java 的佇列記憶體

概觀

本指南將說明如何使用 Azure 佇列記憶體服務撰寫常見案例的程式代碼。 這些範例是以 Java 撰寫,並使用 適用於 Java 的 Azure 記憶體 SDK。 案例包括 插入查看取得刪除 佇列訊息。 也涵蓋 建立刪除 佇列的程序代碼。 如需佇列的詳細資訊,請參閱 後續步驟 一節。

什麼是佇列記憶體?

Azure 佇列記憶體是一項服務,可用來儲存大量訊息,可透過 HTTP 或 HTTPS 的已驗證呼叫從世界各地存取。 單一佇列訊息的大小最多可達 64 KB,而佇列可以包含數百萬則訊息,最多可達記憶體帳戶的總容量限制。 佇列存儲通常用於建立待處理工作的清單,以便進行異步處理。

隊列服務概念

Azure 佇列服務包含下列元件:

Azure 佇列服務元件

  • 記憶體帳戶: 所有對 Azure 記憶體的存取都是透過記憶體帳戶完成。 如需儲存體帳戶的詳細資訊,請參閱儲存體帳戶概觀

  • 佇列:佇列包含一組訊息。 所有訊息都必須在佇列中。 請注意,佇列名稱必須全部小寫。 如需為佇列命名的詳細資訊,請參閱 為佇列和中繼資料命名

  • 訊息:大小上限為 64 KB 的訊息 (任何格式)。 訊息可以保留在佇列中的時間上限為 7 天。 在 2017-07-29 版或更新版本中,存留時間上限可以是任何正數或 -1 (表示訊息不會過期)。 如果省略此參數,則預設存留時間為七天。

  • URL 格式: 佇列可以使用下列 URL 格式尋址:http://<storage account>.queue.core.windows.net/<queue>

    下列 URL 指向圖表中的佇列:

    http://myaccount.queue.core.windows.net/incoming-orders

建立 Azure 儲存體帳戶

建立第一個 Azure 記憶體帳戶最簡單的方式是使用 Azure 入口網站。 若要深入了解,請參閱 建立儲存體帳戶

您也可以使用 Azure PowerShellAzure CLI或適用於 .NET 的 Azure 記憶體資源提供者來建立 Azure 記憶體帳戶。

如果您目前不想在 Azure 中建立記憶體帳戶,您也可以使用 Azurite 記憶體模擬器在本機環境中執行和測試程式代碼。 如需詳細資訊,請參閱 使用 Azurite 模擬器進行本機 Azure 記憶體開發

建立 Java 應用程式

首先,確認您的開發系統符合 適用於 Java 的 Azure 佇列記憶體用戶端連結庫 v12 中列出的必要條件。

若要建立名為 queues-how-to-v12的 Java 應用程式:

  1. 在主控台視窗中(例如 cmd、PowerShell 或 Bash),使用 Maven 建立名稱為 queues-how-to-v12的新控制台應用程式。 輸入下列 mvn 命令以建立 「hello world」 Java 專案。

     mvn archetype:generate \
         --define interactiveMode=n \
         --define groupId=com.queues.howto \
         --define artifactId=queues-howto-v12 \
         --define archetypeArtifactId=maven-archetype-quickstart \
         --define archetypeVersion=1.4
    
    mvn archetype:generate `
        --define interactiveMode=n `
        --define groupId=com.queues.howto `
        --define artifactId=queues-howto-v12 `
        --define archetypeArtifactId=maven-archetype-quickstart `
        --define archetypeVersion=1.4
    
  2. 產生專案的輸出應該看起來像這樣:

    [INFO] Scanning for projects...
    [INFO]
    [INFO] ------------------< org.apache.maven:standalone-pom >-------------------
    [INFO] Building Maven Stub Project (No POM) 1
    [INFO] --------------------------------[ pom ]---------------------------------
    [INFO]
    [INFO] >>> maven-archetype-plugin:3.1.2:generate (default-cli) > generate-sources @ standalone-pom >>>
    [INFO]
    [INFO] <<< maven-archetype-plugin:3.1.2:generate (default-cli) < generate-sources @ standalone-pom <<<
    [INFO]
    [INFO]
    [INFO] --- maven-archetype-plugin:3.1.2:generate (default-cli) @ standalone-pom ---
    [INFO] Generating project in Batch mode
    [INFO] ----------------------------------------------------------------------------
    [INFO] Using following parameters for creating project from Archetype: maven-archetype-quickstart:1.4
    [INFO] ----------------------------------------------------------------------------
    [INFO] Parameter: groupId, Value: com.queues.howto
    [INFO] Parameter: artifactId, Value: queues-howto-v12
    [INFO] Parameter: version, Value: 1.0-SNAPSHOT
    [INFO] Parameter: package, Value: com.queues.howto
    [INFO] Parameter: packageInPathFormat, Value: com/queues/howto
    [INFO] Parameter: version, Value: 1.0-SNAPSHOT
    [INFO] Parameter: package, Value: com.queues.howto
    [INFO] Parameter: groupId, Value: com.queues.howto
    [INFO] Parameter: artifactId, Value: queues-howto-v12
    [INFO] Project created from Archetype in dir: C:\queues\queues-howto-v12
    [INFO] ------------------------------------------------------------------------
    [INFO] BUILD SUCCESS
    [INFO] ------------------------------------------------------------------------
    [INFO] Total time:  6.775 s
    [INFO] Finished at: 2020-08-17T15:27:31-07:00
    [INFO] ------------------------------------------------------------------------
    
  3. 切換至新建立的 queues-howto-v12 目錄。

    cd queues-howto-v12
    

安裝套件

在文字編輯器中開啟 pom.xml 檔案。 將下列相依性元素加入至相依性群組。

<dependency>
  <groupId>com.azure</groupId>
  <artifactId>azure-storage-queue</artifactId>
  <version>12.6.0</version>
</dependency>

設定您的應用程式以存取佇列記憶體

將下列 import 語句新增至您想要使用 Azure 記憶體 API 來存取佇列的 Java 檔案頂端:

// Include the following imports to use queue APIs
import com.azure.core.util.*;
import com.azure.storage.queue.*;
import com.azure.storage.queue.models.*;

建立 Azure 儲存體連接字串

Azure 記憶體用戶端會使用記憶體連接字串來存取資料管理服務。 取得 Azure 入口網站中所列記憶體帳戶的名稱和主要存取密鑰。 使用它們作為 AccountNameAccountKey 在連接字串中的值。 本範例將示範如何宣告靜態欄位來存放連接字串:

// Define the connection-string with your values
final String connectStr = 
    "DefaultEndpointsProtocol=https;" +
    "AccountName=your_storage_account;" +
    "AccountKey=your_storage_account_key";

下列範例假設您有包含 String 記憶體連接字串的物件。

如何:建立佇列

QueueClient物件包含與佇列互動的作業。 下列程式代碼會建立 QueueClient 物件。 使用QueueClient物件來建立您想要使用的佇列。

public static String createQueue(String connectStr)
{
    try
    {
        // Create a unique name for the queue
        String queueName = "queue-" + java.util.UUID.randomUUID();

        System.out.println("Creating queue: " + queueName);

        // Instantiate a QueueClient which will be
        // used to create and manipulate the queue
        QueueClient queue = new QueueClientBuilder()
                                .connectionString(connectStr)
                                .queueName(queueName)
                                .buildClient();

        // Create the queue
        queue.create();
        return queue.getQueueName();
    }
    catch (QueueStorageException e)
    {
        // Output the exception message and stack trace
        System.out.println("Error code: " + e.getErrorCode() + "Message: " + e.getMessage());
        return null;
    }
}

作法:將訊息新增至佇列

若要將訊息插入現有的佇列,請呼叫 sendMessage 方法。 訊息可以是字串(採用UTF-8格式)或位元組陣列。 以下是將字串訊息傳送至佇列的程序代碼。

public static void addQueueMessage
    (String connectStr, String queueName, String messageText)
{
    try
    {
        // Instantiate a QueueClient which will be
        // used to create and manipulate the queue
        QueueClient queueClient = new QueueClientBuilder()
                                    .connectionString(connectStr)
                                    .queueName(queueName)
                                    .buildClient();

        System.out.println("Adding message to the queue: " + messageText);

        // Add a message to the queue
        queueClient.sendMessage(messageText);
    }
    catch (QueueStorageException e)
    {
        // Output the exception message and stack trace
        System.out.println(e.getMessage());
        e.printStackTrace();
    }
}

如何:查看下一則訊息

您可以呼叫peekMessage來查看佇列前方的訊息而不需將其從佇列中移除。

public static void peekQueueMessage
    (String connectStr, String queueName)
{
    try
    {
        // Instantiate a QueueClient which will be
        // used to create and manipulate the queue
        QueueClient queueClient = new QueueClientBuilder()
                                    .connectionString(connectStr)
                                    .queueName(queueName)
                                    .buildClient();

        // Peek at the first message
        PeekedMessageItem peekedMessageItem = queueClient.peekMessage();
        System.out.println("Peeked message: " + peekedMessageItem.getMessageText());
    }
    catch (QueueStorageException e)
    {
        // Output the exception message and stack trace
        System.out.println(e.getMessage());
        e.printStackTrace();
    }
}

如何:變更佇列訊息的內容

您可以直接在佇列中變更訊息的內容。 如果訊息代表工作工作,您可以使用此功能來更新狀態。 下列程式代碼會以新的內容更新佇列訊息,並設定可見度逾時以延長 30 秒。 延長可見時間可使客戶端再有 30 秒繼續處理訊息。 您也可以保留重試計數。 如果訊息重試超過 n 次,您會將其刪除。 此情境可防止在每次處理時觸發應用程式錯誤的訊息。

下列程式代碼範例會搜尋訊息佇列、找出符合搜尋字串的第一個訊息內容、修改訊息內容,然後結束。

public static void updateQueueMessage
    (String connectStr, String queueName,
    String searchString, String updatedContents)
{
    try
    {
        // Instantiate a QueueClient which will be
        // used to create and manipulate the queue
        QueueClient queueClient = new QueueClientBuilder()
                                    .connectionString(connectStr)
                                    .queueName(queueName)
                                    .buildClient();

        // The maximum number of messages to retrieve is 32
        final int MAX_MESSAGES = 32;

        // Iterate through the queue messages
        for (QueueMessageItem message : queueClient.receiveMessages(MAX_MESSAGES))
        {
            // Check for a specific string
            if (message.getMessageText().equals(searchString))
            {
                // Update the message to be visible in 30 seconds
                queueClient.updateMessage(message.getMessageId(),
                                          message.getPopReceipt(),
                                          updatedContents,
                                          Duration.ofSeconds(30));
                System.out.println(
                    String.format("Found message: \'%s\' and updated it to \'%s\'",
                                    searchString,
                                    updatedContents)
                                  );
                break;
            }
        }
    }
    catch (QueueStorageException e)
    {
        // Output the exception message and stack trace
        System.out.println(e.getMessage());
        e.printStackTrace();
    }
}

下列程式代碼範例只會更新佇列中的第一個可見訊息。

public static void updateFirstQueueMessage
    (String connectStr, String queueName, String updatedContents)
{
    try
    {
        // Instantiate a QueueClient which will be
        // used to create and manipulate the queue
        QueueClient queueClient = new QueueClientBuilder()
                                    .connectionString(connectStr)
                                    .queueName(queueName)
                                    .buildClient();

        // Get the first queue message
        QueueMessageItem message = queueClient.receiveMessage();

        // Check for a specific string
        if (null != message)
        {
            // Update the message to be visible in 30 seconds
            UpdateMessageResult result = queueClient.updateMessage(message.getMessageId(),
                                                                   message.getPopReceipt(),
                                                                   updatedContents,
                                                                   Duration.ofSeconds(30));
            System.out.println("Updated the first message with the receipt: " +
                    result.getPopReceipt());
        }
    }
    catch (QueueStorageException e)
    {
        // Output the exception message and stack trace
        System.out.println(e.getMessage());
        e.printStackTrace();
    }
}

如何:取得佇列長度

您可估計佇列中的訊息數目。

方法 getProperties 會傳回數個值,包括目前在佇列中的訊息數目。 計數只是近似值,因為您可以在要求之後新增或移除訊息。 方法 getApproximateMessageCount 會傳回呼叫 getProperties所擷取的最後一個值,而不呼叫佇列記憶體。

public static void getQueueLength(String connectStr, String queueName)
{
    try
    {
        // Instantiate a QueueClient which will be
        // used to create and manipulate the queue
        QueueClient queueClient = new QueueClientBuilder()
                                    .connectionString(connectStr)
                                    .queueName(queueName)
                                    .buildClient();

        QueueProperties properties = queueClient.getProperties();
        long messageCount = properties.getApproximateMessagesCount();

        System.out.println(String.format("Queue length: %d", messageCount));
    }
    catch (QueueStorageException e)
    {
        // Output the exception message and stack trace
        System.out.println(e.getMessage());
        e.printStackTrace();
    }
}

如何:出列下一則訊息

您的程式碼以兩個步驟從佇列中移出一個訊息。 當您呼叫 receiveMessage時,您會在佇列中取得下一個訊息。 讀取此佇列訊息的任何其他程式碼皆無法看到從 receiveMessage 傳回的訊息。 根據預設,此訊息會保持不可見 30 秒。 若要完成從佇列中移除訊息,您也必須呼叫 deleteMessage。 如果您的程式代碼無法處理訊息,此雙步驟程式可確保您可以取得相同的訊息,然後再試一次。 已處理訊息後,程式碼便會立即呼叫 deleteMessage

public static void dequeueMessage(String connectStr, String queueName)
{
    try
    {
        // Instantiate a QueueClient which will be
        // used to create and manipulate the queue
        QueueClient queueClient = new QueueClientBuilder()
                                    .connectionString(connectStr)
                                    .queueName(queueName)
                                    .buildClient();

        // Get the first queue message
        QueueMessageItem message = queueClient.receiveMessage();

        // Check for a specific string
        if (null != message)
        {
            System.out.println("Dequeing message: " + message.getMessageText());

            // Delete the message
            queueClient.deleteMessage(message.getMessageId(), message.getPopReceipt());
        }
        else
        {
            System.out.println("No visible messages in queue");
        }
    }
    catch (QueueStorageException e)
    {
        // Output the exception message and stack trace
        System.out.println(e.getMessage());
        e.printStackTrace();
    }
}

清除佇列訊息的其他選項

有兩種方式可以自訂從佇列擷取訊息。 首先,取得一批訊息(最多32個)。 其次,設定較長或較短的隱藏時間,讓您的程式碼有更充裕或更少的時間完整處理每個訊息。

下列程式碼範例將使用 receiveMessages 方法,在一次呼叫中取得 20 個訊息。 接著其會使用 for 迴圈處理每個訊息。 它也會將每個訊息的可見逾時設定為5分鐘(300秒)。 所有訊息的逾時限制將同時開始。 當呼叫 receiveMessages之後經過五分鐘時,任何未刪除的訊息都會再次顯示。

public static void dequeueMessages(String connectStr, String queueName)
{
    try
    {
        // Instantiate a QueueClient which will be
        // used to create and manipulate the queue
        QueueClient queueClient = new QueueClientBuilder()
                                    .connectionString(connectStr)
                                    .queueName(queueName)
                                    .buildClient();

        // The maximum number of messages to retrieve is 20
        final int MAX_MESSAGES = 20;

        // Retrieve 20 messages from the queue with a
        // visibility timeout of 300 seconds (5 minutes)
        for (QueueMessageItem message : queueClient.receiveMessages(MAX_MESSAGES,
                Duration.ofSeconds(300), Duration.ofSeconds(1), new Context("key1", "value1")))
        {
            // Do processing for all messages in less than 5 minutes,
            // deleting each message after processing.
            System.out.println("Dequeing message: " + message.getMessageText());
            queueClient.deleteMessage(message.getMessageId(), message.getPopReceipt());
        }
    }
    catch (QueueStorageException e)
    {
        // Output the exception message and stack trace
        System.out.println(e.getMessage());
        e.printStackTrace();
    }
}

如何列出佇列

若要取得目前佇列的清單,請呼叫 QueueServiceClient.listQueues() 方法,以傳回 物件的集合 QueueItem

public static void listQueues(String connectStr)
{
    try
    {
        // Instantiate a QueueServiceClient which will be
        // used to list the queues
        QueueServiceClient queueServiceClient = new QueueServiceClientBuilder()
                                    .connectionString(connectStr)
                                    .buildClient();

        // Loop through the collection of queues.
        for (QueueItem queue : queueServiceClient.listQueues())
        {
            // Output each queue name.
            System.out.println(queue.getName());
        }
    }
    catch (QueueStorageException e)
    {
        // Output the exception message and stack trace
        System.out.println(e.getMessage());
        e.printStackTrace();
    }
}

如何:刪除佇列

若要刪除佇列及其中包含的所有訊息,請在 delete 物件上呼叫 QueueClient 方法。

public static void deleteMessageQueue(String connectStr, String queueName)
{
    try
    {
        // Instantiate a QueueClient which will be
        // used to create and manipulate the queue
        QueueClient queueClient = new QueueClientBuilder()
                                    .connectionString(connectStr)
                                    .queueName(queueName)
                                    .buildClient();

        System.out.println("Deleting queue: " + queueClient.getQueueName());

        // Delete the queue
        queueClient.delete();
    }
    catch (QueueStorageException e)
    {
        // Output the exception message and stack trace
        System.out.println(e.getMessage());
        e.printStackTrace();
    }
}

小提示

請參考 Azure 儲存體程式碼範例儲存庫

如需可供您下載和執行的簡易端對端 Azure 儲存體程式碼範例,請查看我們的 Azure 儲存體範例清單。

後續步驟

既然您已瞭解佇列記憶體的基本概念,請遵循這些鏈接來瞭解更複雜的記憶體工作。

如需使用已取代 JAVA 第 8 版 SDK 的相關程式碼範例,請參閱使用 JAVA 第 8 版的程式碼範例