Uso de Queue Storage de Java

Información general

Esta guía muestra cómo codificar algunos escenarios comunes a través del servicio Azure Queue Storage. Los ejemplos están escritos en Java y utilizan el SDK de Azure Storage para Java. Entre los escenarios descritos se incluyen insertar, inspeccionar, obtener y eliminar mensajes de la cola. También se incluye código para crear y eliminar colas. Para obtener más información sobre las colas, consulte la sección Pasos siguientes .

¿Qué es Queue Storage?

El almacenamiento en cola de Azure es un servicio para almacenar grandes cantidades de mensajes a los que puede obtenerse acceso desde cualquier lugar del mundo a través de llamadas autenticadas con HTTP o HTTPS. Un único mensaje en cola puede tener un tamaño de hasta 64 KB y una cola puede contener millones de mensajes, hasta el límite de capacidad total de una cuenta de almacenamiento. Queue Storage se usa normalmente para crear un trabajo pendiente del trabajo que se va a procesar de forma asincrónica.

Conceptos del servicio Queue

Azure Queue service contiene los siguientes componentes:

Componentes de Azure Queue service

  • Cuenta de almacenamiento: Todo el acceso a Azure Storage se realiza a través de una cuenta de almacenamiento. Para más información sobre las cuentas de almacenamiento, consulte Introducción a las cuentas de Storage.

  • Cola: una cola contiene un conjunto de mensajes. Todos los mensajes deben encontrarse en una cola. Tenga en cuenta que el nombre de la cola debe ir en minúsculas. Para más información, consulte Asignar nombres a colas y metadatos.

  • Mensaje: un mensaje, en cualquier formato, de hasta 64 KB. El tiempo máximo que un mensaje puede permanecer en la cola es de 7 días. A partir de la versión del 2017-07-29, inclusive, el tiempo de vida máximo puede ser cualquier número positivo o -1, lo que indica que el mensaje no expira. Si se omite este parámetro, el tiempo de vida predeterminado es siete días.

  • Formato de URL: las colas son direccionables mediante el siguiente formato de dirección URL: http://<storage account>.queue.core.windows.net/<queue>

    La siguiente dirección URL dirige a una cola del diagrama:

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

Creación de una cuenta de Azure Storage

La forma más fácil de crear la primera cuenta de Azure Storage es a través de Azure Portal. Para obtener más información, consulte Crear una cuenta de almacenamiento.

Puede crear también una cuenta de Azure Storage mediante Azure PowerShell, la CLI de Azure o el proveedor de recursos de Azure Storage para .NET.

Si no quiere crear una cuenta de almacenamiento en Azure en este momento, también puede utilizar el emulador de almacenamiento Azurite para ejecutar y probar el código en un entorno local. Para más información, consulte Uso del emulador de Azurite para desarrollo y pruebas locales de Azure Storage.

Creación de una aplicación Java

En primer lugar, compruebe que el sistema de desarrollo cumple los requisitos previos enumerados en Biblioteca cliente de Azure Queue Storage v12 para Java.

Para crear una aplicación Java denominada queues-how-to-v12:

  1. En una ventana de consola (por ejemplo, cmd, PowerShell o Bash), use Maven para crear una nueva aplicación de consola con el nombre queues-how-to-v12. Escriba el siguiente comando mvn para crear un proyecto "Hola mundo" en 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. La salida a partir de la generación del proyecto debe ser similar a la siguiente:

    [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. Cambie al directorio queues-howto-v12 recién creado.

    cd queues-howto-v12
    

Instalar el paquete

Abra el archivo pom.xml en el editor de texto. Agregue el siguiente elemento de dependencia al grupo de dependencias.

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

Configuración de la aplicación para obtener acceso a Queue Storage

Agregue las siguientes instrucciones de importación en la parte superior del archivo Java en el que desea utilizar las API de Azure Storage para obtener acceso a las colas:

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

Configuración de una cadena de conexión de Azure Storage

Un cliente de Azure Storage usa una cadena de conexión de almacenamiento para tener acceso a los servicios de administración de datos. Obtenga el nombre y la clave de acceso principal de la cuenta de almacenamiento que aparecen en Azure Portal. Úselos como los valores AccountName y AccountKey en la cadena de conexión. En este ejemplo se muestra cómo puede declarar un campo estático para mantener la cadena de conexión:

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

En los ejemplos siguientes se supone que tiene un objeto String que contiene la cadena de conexión de almacenamiento.

Procedimientos: Creación de una cola

Un objeto QueueClient contiene las operaciones para interactuar con una cola. El código siguiente crea un objeto QueueClient. Use el objeto QueueClient para crear la cola que desea utilizar.

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

Procedimientos: un mensaje a una cola

Para insertar un mensaje en una cola existente, llame al método sendMessage. Un mensaje puede ser una cadena (en formato UTF-8) o una matriz de bytes. Este es el código que envía un mensaje de cadena a la cola.

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

Procedimientos: siguiente mensaje

Puede inspeccionar el mensaje situado en la parte delantera de una cola, sin quitarlo de la cola, mediante una llamada a 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();
    }
}

Procedimientos: contenido de un mensaje en cola

Puede cambiar el contenido de un mensaje local en la cola. Si el mensaje representa una tarea de trabajo, puede usar esta característica para actualizar el estado. El siguiente código actualiza el mensaje de la cola con contenido nuevo y amplía el tiempo de espera de la visibilidad en 30 segundos más. La extensión del tiempo de espera de visibilidad proporciona al cliente otros 30 segundos para seguir trabajando en el mensaje. También puede mantener un número de reintentos. Si el mensaje se vuelve a intentar más de n veces, lo eliminaría. Este escenario proporciona protección frente a un mensaje que produce un error en la aplicación cada vez que se procesa.

El siguiente código de ejemplo busca en la cola de mensajes, encuentra el primer mensaje cuyo contenido coincide con una cadena de búsqueda, modifica el contenido del mensaje y se cierra.

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

El siguiente código de ejemplo actualiza únicamente el primer mensaje visible de la cola.

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

Procedimientos: la longitud de la cola

Puede obtener una estimación del número de mensajes existentes en una cola.

El método getProperties devuelve varios valores, incluido el número de mensajes que hay actualmente en una cola. El recuento solo es aproximado, ya que se pueden agregar o borrar mensajes después de que el servicio de cola haya respondido su solicitud. El método getApproximateMessageCount devuelve el último valor recuperado por la llamada a getProperties, sin llamar a 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();
    }
}

Procedimientos: Extracción del siguiente mensaje de la cola

El código extrae un mensaje de una cola en dos pasos. Al llamar a receiveMessage, obtiene el siguiente mensaje de una cola. Un mensaje devuelto por receiveMessage se hace invisible a cualquier otro código de lectura de mensajes de esta cola. De forma predeterminada, este mensaje permanece invisible durante 30 segundos. Para terminar quitando el mensaje de la cola, también debe llamar a deleteMessage. Si el código no puede procesar un mensaje, este proceso de dos pasos garantiza que pueda obtener el mismo mensaje e intentarlo de nuevo. El código siguiente llama a deleteMessage justo después de haberse procesado el mensaje.

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

Opciones adicionales para quitar mensajes de la cola

Hay dos formas de personalizar la recuperación de mensajes de una cola. En primer lugar, obtenga un lote de mensajes (hasta 32). En segundo lugar, establezca r un tiempo de espera de la invisibilidad más largo o más corto para que el código disponga de más o menos tiempo para procesar cada mensaje.

El siguiente ejemplo de código utiliza el método receiveMessages para obtener veinte mensajes en una llamada. A continuación, procesa cada mensaje con un bucle for. También establece el tiempo de espera de la invisibilidad en cinco minutos (300 segundos) para cada mensaje. El tiempo de espera se inicia para todos los mensajes al mismo tiempo. Cuando hayan transcurrido cinco minutos desde la llamada a receiveMessages, todos los mensajes que no se eliminen volverán a estar visibles.

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

Procedimientos: Enumeración de las colas

Para obtener una lista de las colas actuales, llame al método QueueServiceClient.listQueues() , el cual devolverá una colección de objetos 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();
    }
}

Procedimientos: Eliminación de una cola

Para eliminar una cola y todos los mensajes contenidos en ella, llame al método delete en el objeto de cola 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();
    }
}

Sugerencia

Extraer del repositorio ejemplos de código de Azure Storage

Para encontrar ejemplos de código de Azure Storage de un extremo a otro y fáciles de usar que se pueden descargar y ejecutar, consulte nuestra lista de ejemplos de Azure Storage.

Pasos siguientes

Ahora que está familiarizado con los aspectos básicos de Queue Storage, utilice estos vínculos para obtener más información acerca de tareas de almacenamiento más complejas.