Como utilizar o Armazenamento de Filas a partir do C++

Dica

Experimentar o Explorador de Armazenamento do Microsoft Azure

O Explorador de Armazenamento do Microsoft Azure é uma aplicação autónoma e gratuita da Microsoft, que lhe permite trabalhar visualmente com dados do Armazenamento do Azure no Windows, macOS e Linux.

Descrição Geral

Este guia irá mostrar-lhe como realizar cenários comuns com o serviço Armazenamento de Filas do Azure. Os exemplos são escritos em C++ e utilizam a biblioteca de cliente do Armazenamento do Microsoft Azure para C++. Os cenários abrangidos incluem inserir, pré-visualizar, obter e eliminar mensagens de fila, bem como criar e eliminar filas.

Nota

Este guia destina-se à biblioteca de cliente do Armazenamento do Azure para C++ v1.0.0 e superior. A versão recomendada é a biblioteca de cliente do Armazenamento do Microsoft Azure v2.2.0, que está disponível através do NuGet ou do GitHub.

O que é o Armazenamento de filas?

O Armazenamento de Filas do Azure é um serviço para armazenar um grande número de mensagens que podem ser acedidas a partir de qualquer local no mundo através de chamadas autenticadas com HTTP ou HTTPS. Uma mensagem de fila única pode ter até 64 KB e uma fila pode conter milhões de mensagens, até ao limite da capacidade total de uma conta de armazenamento. O armazenamento de filas é frequentemente utilizado para criar um registo de tarefas pendentes de trabalho para processar de forma assíncrona.

Conceitos do serviço fila

O serviço Fila do Azure contém os seguintes componentes:

Componentes do serviço Fila do Azure

  • Conta de Armazenamento: todos os acessos ao Storage do Azure são efetuados através de uma conta de armazenamento. Para obter mais informações sobre contas de armazenamento, veja Descrição geral da conta de armazenamento.

  • Fila: uma fila contém um conjunto de mensagens. Todas as mensagens têm de estar numa fila. Tenha em atenção que o nome da fila tem de estar todo em minúsculas. Para obter informações sobre a nomenclatura de filas, veja Nomenclatura de Filas e Metadados.

  • Mensagem: uma mensagem, em qualquer formato, até 64 KB. O tempo máximo que uma mensagem pode permanecer na fila de espera é de 7 dias. Para a versão 2017-07-29 ou posterior, o tempo máximo de vida pode ser qualquer número positivo ou -1 que indique que a mensagem não expira. Se este parâmetro for omitido, o time-to-live predefinido é de sete dias.

  • Formato de URL: As filas são endereçáveis com o seguinte formato de URL: http://<storage account>.queue.core.windows.net/<queue>

    O seguinte URL endereça uma fila no diagrama:

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

Criar uma conta de armazenamento do Azure

A forma mais fácil de criar a primeira conta de armazenamento do Azure é com o portal do Azure. Para saber mais, veja Criar uma conta de armazenamento.

Também pode utilizar o Azure PowerShell, a CLI do Azure ou o Fornecedor de Recursos do Armazenamento do Azure para .NET.

Se preferir não criar uma conta de armazenamento no Azure neste momento, também pode utilizar o emulador de armazenamento do Azurite para executar e testar o código num ambiente local. Para obter mais informações, veja Utilizar o emulador do Azurite para o desenvolvimento local do Armazenamento do Azure.

Criar uma aplicação C++

Neste guia, irá utilizar funcionalidades de armazenamento que podem ser executadas numa aplicação C++.

Para tal, terá de instalar a biblioteca de cliente do Armazenamento do Microsoft Azure para C++ e criar uma conta de Armazenamento do Azure na sua subscrição do Azure.

Para instalar a biblioteca de cliente do Armazenamento do Microsoft Azure para C++, pode utilizar os seguintes métodos:

.\vcpkg.exe install azure-storage-cpp

Pode encontrar um guia sobre como criar o código fonte e exportar para o NuGet no ficheiro README .

Configurar a sua aplicação para aceder ao Armazenamento de Filas

Adicione as seguintes instruções include à parte superior do ficheiro C++ onde pretende utilizar as APIs de Armazenamento do Azure para aceder às filas:

#include <was/storage_account.h>
#include <was/queue.h>

Configurar uma cadeia de ligação do Armazenamento do Microsoft Azure

Um cliente de Armazenamento do Azure utiliza uma cadeia de ligação de armazenamento para armazenar pontos finais e credenciais para aceder aos serviços de gestão de dados. Ao executar numa aplicação cliente, tem de fornecer a cadeia de ligação de armazenamento no seguinte formato, utilizando o nome da sua conta de armazenamento e a chave de acesso ao armazenamento para a conta de armazenamento listada no portal do Azure para os AccountName valores eAccountKey. Para obter informações sobre contas de armazenamento e chaves de acesso, veja Acerca das contas de Armazenamento do Azure. Este exemplo mostra como pode declarar um campo estático para conter a cadeia de ligação:

// Define the connection-string with your values.
const utility::string_t storage_connection_string(U("DefaultEndpointsProtocol=https;AccountName=your_storage_account;AccountKey=your_storage_account_key"));

Para testar a sua aplicação no computador Windows local, pode utilizar o emulador de armazenamento do Azurite. O Azurite é um utilitário que simula Armazenamento de Blobs do Azure e o Armazenamento de Filas no seu computador de desenvolvimento local. O seguinte exemplo mostra como pode declarar um campo estático para conter a cadeia de ligação para o seu emulador local de armazenamento:

// Define the connection-string with Azurite.
const utility::string_t storage_connection_string(U("UseDevelopmentStorage=true;"));  

Para iniciar o Azurite, veja Utilizar o emulador do Azurite para desenvolvimento local do Armazenamento do Azure.

Os exemplos seguintes partem do princípio de que utiliza um destes dois métodos para obter a cadeia de ligação de armazenamento.

Obter a sua cadeia de ligação

Pode utilizar a cloud_storage_account classe para representar as informações da conta de armazenamento. Para obter as informações da conta de armazenamento a partir da cadeia de ligação de armazenamento, pode utilizar o parse método .

// Retrieve storage account from connection string.
azure::storage::cloud_storage_account storage_account = azure::storage::cloud_storage_account::parse(storage_connection_string);

Como: Criar uma fila

Um cloud_queue_client objeto permite-lhe obter objetos de referência para filas. O código seguinte cria um cloud_queue_client objeto.

// Retrieve storage account from connection string.
azure::storage::cloud_storage_account storage_account = azure::storage::cloud_storage_account::parse(storage_connection_string);

// Create a queue client.
azure::storage::cloud_queue_client queue_client = storage_account.create_cloud_queue_client();

Utilize o cloud_queue_client objeto para obter uma referência à fila que pretende utilizar. Se não existir, pode criar a fila.

// Retrieve a reference to a queue.
azure::storage::cloud_queue queue = queue_client.get_queue_reference(U("my-sample-queue"));

// Create the queue if it doesn't already exist.
queue.create_if_not_exists();  

Como: Inserir uma mensagem numa fila

Para inserir uma mensagem numa fila existente, crie primeiro um novo cloud_queue_message. Em seguida, chame o add_message método . Um cloud_queue_message pode ser criado a partir de uma cadeia (no formato UTF-8) ou de uma matriz de bytes. Eis o código que cria uma fila (se não existir) e insere a mensagem Hello, World:

// Retrieve storage account from connection-string.
azure::storage::cloud_storage_account storage_account = azure::storage::cloud_storage_account::parse(storage_connection_string);

// Create the queue client.
azure::storage::cloud_queue_client queue_client = storage_account.create_cloud_queue_client();

// Retrieve a reference to a queue.
azure::storage::cloud_queue queue = queue_client.get_queue_reference(U("my-sample-queue"));

// Create the queue if it doesn't already exist.
queue.create_if_not_exists();

// Create a message and add it to the queue.
azure::storage::cloud_queue_message message1(U("Hello, World"));
queue.add_message(message1);  

Como: Pré-visualizar a mensagem seguinte

Pode espreitar a mensagem à frente de uma fila sem a remover da fila ao chamar o peek_message método .

// Retrieve storage account from connection-string.
azure::storage::cloud_storage_account storage_account = azure::storage::cloud_storage_account::parse(storage_connection_string);

// Create the queue client.
azure::storage::cloud_queue_client queue_client = storage_account.create_cloud_queue_client();

// Retrieve a reference to a queue.
azure::storage::cloud_queue queue = queue_client.get_queue_reference(U("my-sample-queue"));

// Peek at the next message.
azure::storage::cloud_queue_message peeked_message = queue.peek_message();

// Output the message content.
std::wcout << U("Peeked message content: ") << peeked_message.content_as_string() << std::endl;

Como: Alterar o conteúdo de uma mensagem em fila

Pode alterar os conteúdos de uma mensagem no local na fila de espera. Se a mensagem representa uma tarefa de trabalho, pode utilizar esta funcionalidade para atualizar o estado da tarefa de trabalho. O seguinte código atualiza a mensagem de filas com novos conteúdos e expande o tempo limite de visibilidade em 60 segundos. Isto guarda o estado do trabalho associado à mensagem e atribui ao cliente outro minuto para continuar a trabalhar na mensagem. Pode utilizar esta técnica para controlar fluxos de trabalho de vários passos em mensagens de fila, sem ter de recomeçar a partir do início se um passo de processamento falhar devido a uma falha de hardware ou software. Normalmente, também manteria uma contagem de tentativas e se a mensagem for repetida mais do que n vezes, deveria eliminá-la. Esta ação protege contra uma mensagem que aciona um erro da aplicação sempre que é processada.

// Retrieve storage account from connection-string.
azure::storage::cloud_storage_account storage_account = azure::storage::cloud_storage_account::parse(storage_connection_string);

// Create the queue client.
azure::storage::cloud_queue_client queue_client = storage_account.create_cloud_queue_client();

// Retrieve a reference to a queue.
azure::storage::cloud_queue queue = queue_client.get_queue_reference(U("my-sample-queue"));

// Get the message from the queue and update the message contents.
// The visibility timeout "0" means make it visible immediately.
// The visibility timeout "60" means the client can get another minute to continue
// working on the message.
azure::storage::cloud_queue_message changed_message = queue.get_message();

changed_message.set_content(U("Changed message"));
queue.update_message(changed_message, std::chrono::seconds(60), true);

// Output the message content.
std::wcout << U("Changed message content: ") << changed_message.content_as_string() << std::endl;  

Como: Desconsultar a mensagem seguinte

O código descongestiona uma mensagem de uma fila em dois passos. Quando chama get_message, recebe a mensagem seguinte numa fila. Uma mensagem devolvida get_message torna-se invisível para qualquer outra mensagem de leitura de código desta fila. Para concluir a remoção da mensagem da fila, também tem de chamar delete_message. Este processo de dois passos da remoção de uma mensagem garante que se o código não conseguir processar uma mensagem devido a uma falha de hardware ou software, outra instância do seu código poderá obter a mesma mensagem e tentar novamente. O código chama delete_message logo após o processamento da mensagem.

// Retrieve storage account from connection-string.
azure::storage::cloud_storage_account storage_account = azure::storage::cloud_storage_account::parse(storage_connection_string);

// Create the queue client.
azure::storage::cloud_queue_client queue_client = storage_account.create_cloud_queue_client();

// Retrieve a reference to a queue.
azure::storage::cloud_queue queue = queue_client.get_queue_reference(U("my-sample-queue"));

// Get the next message.
azure::storage::cloud_queue_message dequeued_message = queue.get_message();
std::wcout << U("Dequeued message: ") << dequeued_message.content_as_string() << std::endl;

// Delete the message.
queue.delete_message(dequeued_message);

Como: Utilizar opções adicionais para desaconsultar mensagens

Existem duas formas através das quais pode personalizar a obtenção de mensagens a partir de uma fila. Em primeiro lugar, pode obter um lote de mensagens (até 32). Em segundo lugar, pode definir um tempo limite de invisibilidade superior ou inferior, dando mais ou menos tempo ao código para processar totalmente cada mensagem. O seguinte exemplo de código utiliza o get_messages método para obter 20 mensagens numa chamada. Em seguida, processa cada mensagem com um for ciclo. Define também o tempo limite de invisibilidade para cinco minutos para cada mensagem. Tenha em atenção que os cinco minutos são iniciados para todas as mensagens ao mesmo tempo, pelo que após cinco minutos passaram desde a chamada para get_messageso , quaisquer mensagens que não tenham sido eliminadas voltarão a ficar visíveis.

// Retrieve storage account from connection-string.
azure::storage::cloud_storage_account storage_account = azure::storage::cloud_storage_account::parse(storage_connection_string);

// Create the queue client.
azure::storage::cloud_queue_client queue_client = storage_account.create_cloud_queue_client();

// Retrieve a reference to a queue.
azure::storage::cloud_queue queue = queue_client.get_queue_reference(U("my-sample-queue"));

// Dequeue some queue messages (maximum 32 at a time) and set their visibility timeout to
// 5 minutes (300 seconds).
azure::storage::queue_request_options options;
azure::storage::operation_context context;

// Retrieve 20 messages from the queue with a visibility timeout of 300 seconds.
std::vector<azure::storage::cloud_queue_message> messages = queue.get_messages(20, std::chrono::seconds(300), options, context);

for (auto it = messages.cbegin(); it != messages.cend(); ++it)
{
    // Display the contents of the message.
    std::wcout << U("Get: ") << it->content_as_string() << std::endl;
}

Como: Obter o comprimento da fila

Pode obter uma estimativa do número de mensagens numa fila. O download_attributes método devolve as propriedades da fila, incluindo a contagem de mensagens. O approximate_message_count método obtém o número aproximado de mensagens na fila.

// Retrieve storage account from connection-string.
azure::storage::cloud_storage_account storage_account = azure::storage::cloud_storage_account::parse(storage_connection_string);

// Create the queue client.
azure::storage::cloud_queue_client queue_client = storage_account.create_cloud_queue_client();

// Retrieve a reference to a queue.
azure::storage::cloud_queue queue = queue_client.get_queue_reference(U("my-sample-queue"));

// Fetch the queue attributes.
queue.download_attributes();

// Retrieve the cached approximate message count.
int cachedMessageCount = queue.approximate_message_count();

// Display number of messages.
std::wcout << U("Number of messages in queue: ") << cachedMessageCount << std::endl;  

Procedimentos: Eliminar uma fila

Para eliminar uma fila e todas as mensagens contidas na mesma, chame o delete_queue_if_exists método no objeto de fila.

// Retrieve storage account from connection-string.
azure::storage::cloud_storage_account storage_account = azure::storage::cloud_storage_account::parse(storage_connection_string);

// Create the queue client.
azure::storage::cloud_queue_client queue_client = storage_account.create_cloud_queue_client();

// Retrieve a reference to a queue.
azure::storage::cloud_queue queue = queue_client.get_queue_reference(U("my-sample-queue"));

// If the queue exists and delete it.
queue.delete_queue_if_exists();  

Passos seguintes

Agora que aprendeu as noções básicas do Armazenamento de Filas, siga estas ligações para saber mais sobre o Armazenamento do Azure.