Condividi tramite


Come usare l'archiviazione code da Java

Panoramica

Questa guida illustra come eseguire il codice per scenari comuni usando il servizio Archiviazione code di Azure. Gli esempi sono scritti in Java e usano Azure Storage SDK per Java. Gli scenari includono l'inserimento,la visualizzazione, la visualizzazione e l'eliminazione dei messaggi della coda. Il codice per la creazione e l'eliminazione di code è anche coperto. Per altre informazioni sulle code, vedere la sezione Passaggi successivi .

Che cos'è l'archiviazione code?

Il servizio di archiviazione di accodamento di Azure consente di archiviare grandi quantità di messaggi ai quali è possibile accedere da qualsiasi parte del mondo mediante chiamate autenticate tramite HTTP o HTTPS. La dimensione massima di un singolo messaggio della coda è di 64 KB e una coda può contenere milioni di messaggi, nei limiti della capacità complessiva di un account di archiviazione. L'archiviazione code viene spesso usata per creare un backlog di lavoro per elaborare in modo asincrono.

Concetti del servizio di accodamento

Il servizio Code di Azure contiene i componenti seguenti:

Componenti del servizio Code di Azure

  • Account di archiviazione: Tutto l'accesso ad Archiviazione di Azure viene eseguito tramite un account di archiviazione. Per altre informazioni sugli account di archiviazione, vedere Panoramica dell'account di archiviazione.

  • Coda: una coda contiene un set di messaggi. Tutti i messaggi devono essere inclusi in una coda. Si noti che il nome della coda deve essere in lettere minuscole. Per altre informazioni, vedere Denominazione di code e metadati.

  • Messaggio: un messaggio, in qualsiasi formato, con dimensioni massime di 64 KB. Il tempo massimo che un messaggio può rimanere nella coda è di 7 giorni. Per la versione 2017-07-29 o successive, la durata massima consentita può essere un numero positivo qualsiasi o -1, a indicare che il messaggio non scade. Se questo parametro viene omesso, la durata predefinita è di sette giorni.

  • Formato URL: Le code sono indirizzabili usando il formato URL seguente: http://.queue.core.windows.net/<storage account><queue>

    L'URL seguente fa riferimento a una delle code nel diagramma:

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

Creare un account di archiviazione di Azure

Il modo più semplice per creare il primo account di archiviazione di Azure consiste nell'usare il portale di Azure. Per altre informazioni, vedere Creare un account di archiviazione.

È anche possibile creare un account di archiviazione di Azure usando Azure PowerShell, l'interfaccia della riga di comando di Azure o il provider di risorse di archiviazione di Azure per .NET.

Se si preferisce non creare un account di archiviazione in Azure in questo momento, è anche possibile usare l'emulatore di archiviazione Azurite per eseguire e testare il codice in un ambiente locale. Per altre informazioni, vedere Usare l'emulatore Azurite per lo sviluppo locale di Archiviazione di Azure.

Creare un'applicazione Java

Verificare prima di tutto che il sistema di sviluppo soddisfi i prerequisiti elencati nella libreria client di Archiviazione code di Azure v12 per Java.

Per creare un'applicazione Java denominata queues-how-to-v12:

  1. Nella finestra di una console (ad esempio cmd, PowerShell o Bash) usare Maven queues-how-to-v12blob-quickstart-v12. Digitare il comando mvn seguente per creare un progetto Java "hello world".

     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. L'output della generazione del progetto avrà un aspetto simile al seguente:

    [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. Passare alla directory queues-howto-v12 appena creata.

    cd queues-howto-v12
    

Installare il pacchetto

Aprire il file pom.xml nell'editor di testo. Aggiungere l'elemento di dipendenza seguente al gruppo di dipendenze.

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

Configurazione dell'applicazione per l’accesso ad Archiviazione di accodamento

Aggiungere le istruzioni di importazione seguenti all'inizio del file Java in cui si desidera usare le API di Archiviazione di Azure per accedere alle code:

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

Configurare una stringa di connessione di archiviazione di Azure

Un client di archiviazione di Azure usa una stringa di connessione di archiviazione per accedere ai servizi di gestione dei dati. Ottenere il nome e la chiave di accesso primaria per l'account di archiviazione elencato nella portale di Azure. Usarli come AccountName valori e AccountKey nella stringa di connessione. In questo esempio viene illustrato come dichiarare un campo statico per memorizzare la stringa di connessione:

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

Gli esempi seguenti presuppongono che sia presente un String oggetto contenente la stringa di connessione di archiviazione.

Procedura: creare una coda

Un QueueClient oggetto contiene le operazioni per interagire con una coda. Il codice seguente crea un QueueClient oggetto. Usare l'oggetto QueueClient per creare la coda da usare.

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

Procedura: aggiungere un messaggio a una coda

Per inserire un messaggio in una coda esistente, chiamare il metodo sendMessage. Un messaggio può essere una stringa (in formato UTF-8) o una matrice di byte. Ecco il codice che invia un messaggio stringa alla coda.

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

Procedura: visualizzare il messaggio successivo

È possibile visualizzare il messaggio davanti a una coda senza rimuoverlo dalla coda chiamando 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();
    }
}

Procedura: cambiare il contenuto di un messaggio accodato

È possibile cambiare il contenuto di un messaggio inserito nella coda. Se il messaggio rappresenta un'attività di lavoro, è possibile usare questa funzionalità per aggiornare lo stato. Il codice seguente aggiorna un messaggio di coda con nuovi contenuti e imposta il timeout di visibilità per estendere un altro 30 secondi. L'estensione del timeout di visibilità offre al client un altro 30 secondi per continuare a lavorare sul messaggio. È anche possibile mantenere un numero di tentativi. Se il messaggio viene riprovato più di n volte, è necessario eliminarlo. Questo scenario protegge da un messaggio che attiva un errore dell'applicazione ogni volta che viene elaborato.

Nell'esempio di codice seguente viene eseguita la ricerca nella coda di messaggi, viene individuato il primo contenuto del messaggio corrispondente a una stringa di ricerca, modifica il contenuto del messaggio e termina.

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

L'esempio di codice seguente aggiorna solo il primo messaggio visibile nella coda.

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

Procedura: recuperare la lunghezza delle code

È possibile ottenere una stima sul numero di messaggi presenti in una coda.

Il getProperties metodo restituisce diversi valori, tra cui il numero di messaggi attualmente presenti in una coda. Il conteggio è approssimativo perché i messaggi possono essere aggiunti o rimossi dopo la richiesta. Il getApproximateMessageCount metodo restituisce l'ultimo valore recuperato dalla chiamata a getProperties, senza chiamare Archiviazione coda.

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

Procedura: rimuovere il messaggio successivo dalla coda

Il codice consente di rimuovere un messaggio da una coda in due passaggi. Quando si chiama receiveMessage, viene visualizzato il messaggio successivo in una coda. Un messaggio restituito da receiveMessage diventa invisibile a qualsiasi altro elemento di codice che legge i messaggi di questa coda. Per impostazione predefinita, il messaggio rimane invisibile per 30 secondi. Per completare la rimozione del messaggio dalla coda, è necessario chiamare anche deleteMessage. Se il codice non riesce a elaborare un messaggio, questo processo in due passaggi garantisce che sia possibile ottenere lo stesso messaggio e riprovare. Il codice chiama deleteMessage subito dopo l'elaborazione del messaggio.

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

Opzioni aggiuntive per rimuovere i messaggi dalla coda

Esistono due modi per personalizzare il recupero di messaggi da una coda. Prima di tutto, ottenere un batch di messaggi (fino a 32). In secondo luogo, impostare un timeout di invisibilità più lungo o più breve, consentendo al codice più o meno tempo di elaborare completamente ogni messaggio.

Nell'esempio di codice seguente viene usato il metodo receiveMessages per recuperare 20 messaggi con una sola chiamata. Ogni messaggio viene poi elaborato con un ciclo for. Per ogni messaggio, inoltre, il timeout di invisibilità viene impostato su cinque minuti (300 secondi). Il timeout viene avviato per tutti i messaggi contemporaneamente. Quando sono trascorsi cinque minuti dalla chiamata a receiveMessages, tutti i messaggi non eliminati diventeranno nuovamente visibili.

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

Procedura: elencare le code

Per ottenere un elenco delle code correnti, chiamare il QueueServiceClient.listQueues() metodo , che restituirà una raccolta di QueueItem oggetti .

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

Procedura: eliminare una coda

Per eliminare una coda e tutti i messaggi contenuti, chiamare il delete metodo sull'oggetto 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();
    }
}

Suggerimento

Estrarre il repository degli esempi di codice di Archiviazione di Azure

Per esempi di codice end-to-end facile da usare che è possibile scaricare ed eseguire, vedere l'elenco di esempi di Archiviazione di Azure.

Passaggi successivi

Dopo aver appreso le nozioni di base di Archiviazione code, seguire questi collegamenti per informazioni sulle attività di archiviazione più complesse.

Per esempi di codice correlati che usano SDK java versione 8 deprecati, vedere Esempi di codice con Java versione 8.