如何使用 JAVA 的佇列儲存體How to use Queue Storage from Java

概觀Overview

本指南將說明如何使用 Azure 佇列儲存體服務來撰寫常見案例的程式碼。This guide will show you how to code for common scenarios using the Azure Queue Storage service. 相關範例是以 Java 撰寫並使用 Azure Storage SDK for JavaThe samples are written in Java and use the Azure Storage SDK for Java. 案例包括 插入查看取得刪除 佇列訊息。Scenarios include inserting, peeking, getting, and deleting queue messages. 此外也涵蓋 建立刪除 佇列的程式碼。Code for creating and deleting queues is also covered. 如需佇列的詳細資訊,請參閱後續步驟一節。For more information on queues, see the Next steps section.

什麼是佇列儲存體?What is Queue storage?

Azure 佇列儲存體是一項儲存大量訊息的服務,全球任何地方都可利用 HTTP 或 HTTPS 並透過驗證的呼叫來存取這些訊息。Azure Queue storage is a service for storing large numbers of messages that can be accessed from anywhere in the world via authenticated calls using HTTP or HTTPS. 單一佇列訊息的大小上限為 64 KB,而一個佇列可以包含數百萬個訊息,以儲存體帳戶的總容量為限。A single queue message can be up to 64 KB in size, and a queue can contain millions of messages, up to the total capacity limit of a storage account. 佇列儲存體通常用來建立要以非同步方式處理的待處理專案(backlog)。Queue storage is often used to create a backlog of work to process asynchronously.

佇列服務概念Queue service concepts

Azure 佇列服務包含下列元件:The Azure Queue service contains the following components:

Azure 佇列服務元件

  • 儲存體帳戶: Azure 儲存體的所有存取都是透過儲存體帳戶完成。Storage Account: All access to Azure Storage is done through a storage account. 如需儲存體帳戶的詳細資訊,請參閱儲存體帳戶概觀For more information about storage accounts, see Storage account overview.

  • 佇列: 佇列包含一組訊息。Queue: A queue contains a set of messages. 所有訊息都必須放在佇列中。All messages must be in a queue. 請注意,佇列名稱必須是小寫。Note that the queue name must be all lowercase. 如需為佇列命名的詳細資訊,請參閱 為佇列和中繼資料命名For information on naming queues, see Naming Queues and Metadata.

  • 訊息: 大小上限為 64 KB 的訊息 (任何格式)。Message: A message, in any format, of up to 64 KB. 訊息可保留在佇列中的時間上限為 7 天。The maximum time that a message can remain in the queue is 7 days. 如需版本 2017-07-29 或更新版本,最大存留時間可以是任何正數,或是表示訊息未過期的 -1。For version 2017-07-29 or later, the maximum time-to-live can be any positive number, or -1 indicating that the message doesn't expire. 如果省略此參數,則預設存留時間為 7 天。If this parameter is omitted, the default time-to-live is seven days.

  • URL 格式: 您可以使用下列 URL 格式來定址佇列: HTTP:// <storage account> . queue.core.windows.net/<queue>URL format: Queues are addressable using the following URL format: http://<storage account>.queue.core.windows.net/<queue>

    下列 URL 可定址圖中的佇列:The following URL addresses a queue in the diagram:

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

建立 Azure 儲存體帳戶Create an Azure storage account

建立您第一個 Azure 儲存體帳戶最簡單的方法,就是使用 Azure 入口網站The easiest way to create your first Azure storage account is by using the Azure portal. 若要深入了解,請參閱 建立儲存體帳戶To learn more, see Create a storage account.

您也可以使用 Azure PowerShellAzure CLI,或 Azure Storage Resource Provider for .NET 來建立 Azure 儲存體帳戶。You can also create an Azure storage account by using Azure PowerShell, Azure CLI, or the Azure Storage Resource Provider for .NET.

如果您目前不想要在 Azure 中建立儲存體帳戶,您也可以使用 Azurite 儲存體模擬器在本機環境中執行並測試您的程式碼。If you prefer not to create a storage account in Azure at this time, you can also use the Azurite storage emulator to run and test your code in a local environment. 如需詳細資訊,請參閱 使用 Azurite 模擬器進行本機 Azure 儲存體開發For more information, see Use the Azurite emulator for local Azure Storage development.

建立 Java 應用程式Create a Java application

首先,請確認您的開發系統符合 適用于 JAVA 的 Azure 佇列儲存體用戶端程式庫 v12中所列的必要條件。First, verify that your development system meets the prerequisites listed in Azure Queue Storage client library v12 for Java.

若要建立名為的 JAVA 應用程式 queues-how-to-v12To create a Java application named queues-how-to-v12:

  1. 在主控台視窗中 (例如 cmd、PowerShell 或 Bash),使用 Maven 建立名為 queues-how-to-v12 的新主控台應用程式。In a console window (such as cmd, PowerShell, or Bash), use Maven to create a new console app with the name queues-how-to-v12. 輸入下列 mvn 命令,以建立 "hello world" Java 專案。Type the following mvn command to create a "hello world" Java project.

     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. 產生專案的輸出應該看起來像這樣:The output from generating the project should look something like this:

    [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. Switch to the newly created queues-howto-v12 directory.

    cd queues-howto-v12
    

安裝套件Install the package

在文字編輯器中開啟 pom.xml 檔案。Open the pom.xml file in your text editor. 將下列相依性元素加入至相依性群組。Add the following dependency element to the group of dependencies.

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

設定您的應用程式以存取佇列儲存體Configure your application to access Queue Storage

在您想要使用 Azure 儲存體 Api 來存取佇列的 JAVA 檔案頂端,新增下列 import 語句:Add the following import statements to the top of the Java file where you want to use Azure Storage APIs to access queues:

// 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 儲存體連接字串Set up an Azure Storage connection string

Azure 儲存體的用戶端會使用儲存體連接字串來存取資料管理服務。An Azure Storage client uses a storage connection string for accessing data management services. 取得 Azure 入口網站中列出的儲存體帳戶名稱和主要存取金鑰。Get the name and the primary access key for your storage account listed in the Azure portal. 使用它們做為 AccountName AccountKey 連接字串中的和值。Use them as the AccountName and AccountKey values in the connection string. 本範例將示範如何宣告靜態欄位來存放連接字串:This example shows how you can declare a static field to hold the connection string:

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

下列範例假設您有一個 String 包含儲存體連接字串的物件。The following samples assume that you have a String object containing the storage connection string.

作法:建立佇列How to: Create a queue

QueueClient物件包含與佇列互動的作業。A QueueClient object contains the operations for interacting with a queue. 下列程式碼會建立 QueueClient 物件。The following code creates a QueueClient object. 使用 QueueClient 物件來建立您要使用的佇列。Use the QueueClient object to create the queue you want to use.

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;
    }
}

作法:將訊息新增至佇列How to: Add a message to a queue

若要將訊息插入現有佇列中,請呼叫 sendMessage 方法。To insert a message into an existing queue, call the sendMessage method. 訊息可以是 UTF-8 格式的字串 () 或位元組陣列。A message can be either a string (in UTF-8 format) or a byte array. 以下是將字串訊息傳送至佇列的程式碼。Here is code that sends a string message into the queue.

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();
    }
}

作法:查看下一個訊息How to: Peek at the next message

您可以藉由呼叫,在佇列前面查看訊息,而不需要將它從佇列中移除 peekMessageYou can peek at the message in the front of a queue without removing it from the queue by calling 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();
    }
}

作法:變更佇列訊息的內容How to: Change the contents of a queued message

您可以在佇列中就地變更訊息內容。You can change the contents of a message in-place in the queue. 如果訊息代表工作工作,您可以使用這項功能來更新狀態。If the message represents a work task, you could use this feature to update the status. 下列程式碼會以新的內容更新佇列訊息,並將可見度 timeout 設定為延長30秒。The following code updates a queue message with new contents and sets the visibility timeout to extend another 30 seconds. 延伸可見度 timeout 可讓用戶端另外30秒繼續處理訊息。Extending the visibility timeout gives the client another 30 seconds to continue working on the message. 您也可以保留重試計數。You could keep a retry count, as well. 如果訊息重試超過 n 次,您會將它刪除。If the message is retried more than n times, you would delete it. 此案例會防止每次處理時都會觸發應用程式錯誤的訊息。This scenario protects against a message that triggers an application error each time it's processed.

下列程式碼範例會搜尋訊息的佇列、找出符合搜尋字串的第一個訊息內容、修改訊息內容,然後結束。The following code sample searches through the queue of messages, locates the first message content that matches a search string, modifies the message content, and exits.

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();
    }
}

下列程式碼範例只會更新佇列中第一個可見的訊息。The following code sample updates just the first visible message in the queue.

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();
    }
}

作法:取得佇列長度How to: Get the queue length

您可以取得佇列中的估計訊息數目。You can get an estimate of the number of messages in a queue.

方法會傳回 getProperties 數個值,包括目前在佇列中的訊息數目。The getProperties method returns several values including the number of messages currently in a queue. 計數只是近似值,因為可以在要求之後新增或移除訊息。The count is only approximate because messages can be added or removed after your request. getApproximateMessageCount方法會傳回呼叫所取出的最後一個值 getProperties ,而不會呼叫佇列儲存體。The getApproximateMessageCount method returns the last value retrieved by the call to getProperties, without calling Queue Storage.

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();
    }
}

作法:清除下一個佇列訊息How to: Dequeue the next message

您的程式碼可以使用兩個步驟來清除佇列訊息。Your code dequeues a message from a queue in two steps. 當您呼叫時 receiveMessage ,會取得佇列中的下一則訊息。When you call receiveMessage, you get the next message in a queue. receiveMessage 傳回的訊息,對於從此佇列讀取訊息的任何其他程式碼而言,將會是不可見的。A message returned from receiveMessage becomes invisible to any other code reading messages from this queue. 依預設,此訊息會維持 30 秒的不可見狀態。By default, this message stays invisible for 30 seconds. 若要完成從佇列中移除訊息,您還必須呼叫 deleteMessageTo finish removing the message from the queue, you must also call deleteMessage. 如果您的程式碼無法處理訊息,此兩步驟程式可確保您可以取得相同的訊息,然後再試一次。If your code fails to process a message, this two-step process ensures that you can get the same message and try again. 您的程式碼會在 deleteMessage 處理完訊息之後立即呼叫。Your code calls deleteMessage right after the message has been processed.

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();
    }
}

清除佇列訊息的其他選項Additional options for dequeuing messages

自訂從佇列中擷取訊息的方法有兩種。There are two ways to customize message retrieval from a queue. 首先,取得一批訊息 (最多 32) 。First, get a batch of messages (up to 32). 其次,設定較長或較短的隱藏 timeout,讓您的程式碼更多或更少的時間來完整處理每個訊息。Second, set a longer or shorter invisibility timeout, allowing your code more or less time to fully process each message.

下列程式碼範例將使用 receiveMessages 方法,在一次呼叫中取得 20 個訊息。The following code example uses the receiveMessages method to get 20 messages in one call. 接著其會使用 for 迴圈處理每個訊息。Then it processes each message using a for loop. 它也會將可見度逾時設定為每個訊息五分鐘 (300 秒)。It also sets the invisibility timeout to five minutes (300 seconds) for each message. 所有訊息的等候時間都是同時啟動的。The timeout starts for all messages at the same time. 當自呼叫後經過五分鐘後 receiveMessages ,任何未刪除的訊息都會重新顯示。When five minutes have passed since the call to receiveMessages, any messages not deleted will become visible again.

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();
    }
}

作法:列出佇列How to: List the queues

若要取得目前佇列的清單,請呼叫 QueueServiceClient.listQueues() 方法,此方法會傳回物件的集合 QueueItemTo obtain a list of the current queues, call the QueueServiceClient.listQueues() method, which will return a collection of QueueItem objects.

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();
    }
}

作法:刪除佇列How to: Delete a queue

若要刪除佇列及其內含的所有訊息,請 delete 在物件上呼叫方法 QueueClientTo delete a queue and all the messages contained in it, call the delete method on the QueueClient object.

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 儲存體程式碼範例儲存機制Check out the Azure Storage code samples repository

如需可供您下載和執行的簡易端對端 Azure 儲存體程式碼範例,請查看我們的 Azure 儲存體範例清單。For easy-to-use end-to-end Azure Storage code samples that you can download and run, please check out our list of Azure Storage Samples.

下一步Next steps

既然您已瞭解佇列儲存體的基本概念,請遵循下列連結以瞭解更複雜的儲存體工作。Now that you've learned the basics of Queue Storage, follow these links to learn about more complex storage tasks.