Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Visão geral
O Armazenamento de Filas do Azure fornece mensagens na nuvem entre componentes de aplicativos. Ao projetar aplicativos para escala, os componentes do aplicativo geralmente são dissociados para que possam ser dimensionados de forma independente. O Armazenamento em Fila fornece mensagens assíncronas entre componentes de aplicativos, estejam eles em execução na nuvem, na área de trabalho, em um servidor local ou em um dispositivo móvel. O armazenamento em fila também oferece suporte ao gerenciamento de tarefas assíncronas e à criação de fluxos de trabalho do processo.
Acerca deste tutorial
Este tutorial mostra como escrever código .NET para alguns cenários comuns usando o Armazenamento de Filas do Azure. Os cenários abordados incluem a criação e exclusão de filas e a adição, leitura e exclusão de mensagens de fila.
Tempo estimado para conclusão: 45 minutos
Pré-requisitos
- Estúdio Microsoft Visual
- Conta de Armazenamento Azure
O que é armazenamento em fila?
O Armazenamento de Filas do Azure é um serviço para armazenar um grande número de mensagens que podem ser acessadas de qualquer lugar do mundo por meio de chamadas autenticadas usando HTTP ou HTTPS. Uma única mensagem de fila pode ter até 64 KB de tamanho e uma fila pode conter milhões de mensagens, até o limite de capacidade total de uma conta de armazenamento. O armazenamento em fila é frequentemente usado para criar uma lista de pendências de trabalho para processar de forma assíncrona.
Conceitos do Serviço de Fila
O serviço de Fila do Azure contém os seguintes componentes:
Conta de armazenamento: Todo o acesso ao Armazenamento do Azure é feito através de uma conta de armazenamento. Para obter mais informações sobre contas de armazenamento, consulte Visã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 como nomear filas, consulte Nomeando filas e metadados.
Mensagem: Uma mensagem, em qualquer formato, de até 64 KB. O tempo máximo que uma mensagem pode permanecer na fila é 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 indicando que a mensagem não expira. Se esse parâmetro for omitido, o tempo de vida padrão será de sete dias.
Formato URL: As filas podem ser endereçadas usando o seguinte formato de URL: http://
<storage account>
.queue.core.windows.net/<queue>
A seguinte URL aponta para uma fila no diagrama:
http://myaccount.queue.core.windows.net/incoming-orders
Criar uma conta de armazenamento do Azure
A maneira mais fácil de criar sua primeira conta de armazenamento do Azure é usando o portal do Azure. Para saber mais, consulte Criar uma conta de armazenamento.
Você também pode criar uma conta de armazenamento do Azure usando o Azure PowerShell, a CLI do Azure ou o Provedor de Recursos de Armazenamento do Azure para .NET.
Se preferir não criar uma conta de armazenamento no Azure neste momento, você também pode usar o emulador de armazenamento Azurite para executar e testar seu código em um ambiente local. Para obter mais informações, consulte Usar o emulador Azurite para o desenvolvimento local do Armazenamento do Azure.
Configurar seu ambiente de desenvolvimento
Em seguida, configure seu ambiente de desenvolvimento no Visual Studio para que você esteja pronto para experimentar os exemplos de código neste guia.
Criar um projeto de aplicativo de console do Windows
No Visual Studio, crie uma nova aplicação de consola do Windows. As etapas a seguir mostram como criar um aplicativo de console no Visual Studio 2019. Os passos são semelhantes aos de outras versões do Visual Studio.
- Selecionar arquivo>novo>projeto
- Selecionar Plataforma>Windows
- Selecione Aplicativo de Console (.NET Framework)
- Selecione Avançar
- No campo Nome do projeto , insira um nome para seu aplicativo
- Selecione Criar
Todos os exemplos de código neste tutorial podem ser adicionados ao método Main()
do arquivo Program.cs
do aplicativo de console.
Você pode usar as bibliotecas de cliente do Armazenamento do Azure em qualquer tipo de aplicativo .NET, incluindo um serviço de nuvem ou aplicativo Web do Azure e aplicativos móveis e de área de trabalho. Neste guia, usamos um aplicativo de console para simplificar.
Utilizar o NuGet para instalar os pacotes necessários
Você precisa fazer referência aos quatro pacotes a seguir em seu projeto para concluir este tutorial:
- Biblioteca Azure.Core para .NET: este pacote fornece primitivas, abstrações e auxiliares compartilhados para bibliotecas de cliente modernas do SDK do .NET Azure.
- Biblioteca de cliente Azure.Storage.Common para .NET: este pacote fornece infraestrutura compartilhada pelas outras bibliotecas de cliente do Armazenamento do Azure.
- Biblioteca de cliente Azure.Storage.Queues para .NET: este pacote permite trabalhar com o Armazenamento de Filas do Azure para armazenar mensagens que podem ser acessadas por um cliente.
- Biblioteca System.Configuration.ConfigurationManager para .NET: Este pacote fornece acesso a arquivos de configuração para aplicativos cliente.
Você pode usar o NuGet para obter esses pacotes. Siga estes passos:
- Clique com o botão direito do mouse em seu projeto no Gerenciador de Soluções e escolha Gerenciar Pacotes NuGet.
- Selecione Procurar
- Pesquise online
Azure.Storage.Queues
, e selecione Instalar para instalar a biblioteca de cliente do Armazenamento do Azure e as suas dependências. Isso também instalará as bibliotecas Azure.Storage.Common e Azure.Core, que são dependências da biblioteca de filas. - Pesquise online por
System.Configuration.ConfigurationManager
e selecione Instalar para instalar o Configuration Manager.
Determine seu ambiente de destino
Você tem duas opções de ambiente para executar os exemplos neste guia:
- Você pode executar seu código em uma conta de Armazenamento do Azure na nuvem.
- Você pode executar seu código no emulador de armazenamento Azurite. O Azurite é um ambiente local que emula uma conta de Armazenamento do Azure na nuvem. O Azurite é uma opção gratuita para testar e depurar seu código enquanto seu aplicativo está em desenvolvimento. O emulador usa uma conta e chave bem conhecidas. Para obter mais informações, consulte Usar o emulador Azurite para desenvolvimento e teste do Armazenamento do Azure local.
Observação
Você pode direcionar o emulador de armazenamento para evitar incorrer em quaisquer custos associados ao Armazenamento do Azure. No entanto, se você optar por direcionar uma conta de Armazenamento do Azure na nuvem, os custos para executar este tutorial serão insignificantes.
Obter sua cadeia de conexão de armazenamento
As bibliotecas de cliente do Armazenamento do Azure para .NET suportam o uso de uma cadeia de ligação de armazenamento para configurar pontos de extremidade e credenciais para aceder a serviços de armazenamento. Para obter mais informações, consulte Gerenciar chaves de acesso da conta de armazenamento.
Copiar as credenciais do Portal do Azure
O código de exemplo precisa autorizar o acesso à sua conta de armazenamento. Para autorizar, forneça ao aplicativo as credenciais da conta de armazenamento na forma de uma cadeia de conexão. Para ver as credenciais da sua conta de armazenamento:
Navegue até o portal do Azure.
Localize a sua conta de armazenamento.
Na seção Configurações da visão geral da conta de armazenamento, selecione Chaves de acesso. As chaves de acesso da conta são apresentadas, bem como a cadeia de ligação completa para cada chave.
Localize o valor da cadeia de conexão em key1 e clique no botão Copiar para copiar a cadeia de conexão. Você adicionará o valor da cadeia de conexão a uma variável de ambiente na próxima etapa.
Para obter mais informações sobre cadeias de conexão, consulte Configurar uma cadeia de conexão para o Armazenamento do Azure.
Observação
A chave da conta de armazenamento é semelhante à palavra-passe de raiz da conta de armazenamento. Tenha sempre cuidado para proteger a chave da sua conta de armazenamento. Evite distribuí-lo a outros usuários, codificá-lo ou salvá-lo em um arquivo de texto simples acessível a outras pessoas. Regenere sua chave usando o portal do Azure se você acredita que ela pode ter sido comprometida.
A melhor maneira de manter a cadeia de conexão de armazenamento é em um arquivo de configuração. Para configurar sua cadeia de conexão, abra o arquivo app.config
do Gerenciador de Soluções no Visual Studio. Adicione o conteúdo do elemento <appSettings>
mostrado aqui. Substitua connection-string
pelo valor copiado da sua conta de armazenamento no portal:
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
</startup>
<appSettings>
<add key="StorageConnectionString" value="connection-string" />
</appSettings>
</configuration>
Por exemplo, a sua definição de configuração é semelhante a:
<add key="StorageConnectionString" value="DefaultEndpointsProtocol=https;AccountName=storagesample;AccountKey=GMuzNHjlB3S9itqZJHHCnRkrokLkcSyW7yK9BRbGp0ENePunLPwBgpxV1Z/pVo9zpem/2xSHXkMqTHHLcx8XRA==EndpointSuffix=core.windows.net" />
Para direcionar o emulador de armazenamento Azurite, pode-se usar um atalho que faz a correspondência com o nome e a chave da conta conhecidos. Nesse caso, a configuração da cadeia de conexão é:
<add key="StorageConnectionString" value="UseDevelopmentStorage=true" />
Adicionar diretivas de utilização
Adicione as seguintes diretivas using
à parte superior do arquivo Program.cs
:
using System; // Namespace for Console output
using System.Configuration; // Namespace for ConfigurationManager
using System.Threading.Tasks; // Namespace for Task
using Azure.Identity;
using Azure.Storage.Queues; // Namespace for Queue storage types
using Azure.Storage.Queues.Models; // Namespace for PeekedMessage
Criar o cliente de armazenamento em fila
A classe QueueClient
permite recuperar filas armazenadas no Armazenamento de Filas. Aqui está uma maneira de criar o cliente de serviço:
//-------------------------------------------------
// Create the queue service client
//-------------------------------------------------
public void CreateQueueClient(string queueName)
{
// Get the connection string from app settings
string connectionString = ConfigurationManager.AppSettings["StorageConnectionString"];
// Instantiate a QueueClient which will be used to create and manipulate the queue
QueueClient queueClient = new QueueClient(connectionString, queueName);
}
Sugestão
As mensagens enviadas usando a classe QueueClient
devem estar em um formato que possa ser incluído em uma solicitação XML com codificação UTF-8. Opcionalmente, você pode definir a opção MessageEncoding como Base64 para lidar com mensagens não compatíveis.
Agora você está pronto para escrever código que lê e grava dados no Armazenamento de Filas.
Criar uma fila
Este exemplo mostra como criar uma fila:
//-------------------------------------------------
// Create a message queue
//-------------------------------------------------
public bool CreateQueue(string queueName)
{
try
{
// Get the connection string from app settings
string connectionString = ConfigurationManager.AppSettings["StorageConnectionString"];
// Instantiate a QueueClient which will be used to create and manipulate the queue
QueueClient queueClient = new QueueClient(connectionString, queueName);
// Create the queue
queueClient.CreateIfNotExists();
if (queueClient.Exists())
{
Console.WriteLine($"Queue created: '{queueClient.Name}'");
return true;
}
else
{
Console.WriteLine($"Make sure the Azurite storage emulator running and try again.");
return false;
}
}
catch (Exception ex)
{
Console.WriteLine($"Exception: {ex.Message}\n\n");
Console.WriteLine($"Make sure the Azurite storage emulator running and try again.");
return false;
}
}
Inserir uma mensagem numa fila
Para inserir uma mensagem em uma fila existente, chame o método SendMessage
. Uma mensagem pode ser uma cadeia de caracteres (no formato UTF-8) ou uma matriz de bytes. O código a seguir cria uma fila (se ela não existir) e insere uma mensagem:
//-------------------------------------------------
// Insert a message into a queue
//-------------------------------------------------
public void InsertMessage(string queueName, string message)
{
// Get the connection string from app settings
string connectionString = ConfigurationManager.AppSettings["StorageConnectionString"];
// Instantiate a QueueClient which will be used to create and manipulate the queue
QueueClient queueClient = new QueueClient(connectionString, queueName);
// Create the queue if it doesn't already exist
queueClient.CreateIfNotExists();
if (queueClient.Exists())
{
// Send a message to the queue
queueClient.SendMessage(message);
}
Console.WriteLine($"Inserted: {message}");
}
Espreite a próxima mensagem
Você pode espiar as mensagens na fila sem removê-las da fila chamando o método PeekMessages
. Se você não passar um valor para o parâmetro maxMessages
, o padrão é espiar uma mensagem.
//-------------------------------------------------
// Peek at a message in the queue
//-------------------------------------------------
public void PeekMessage(string queueName)
{
// Get the connection string from app settings
string connectionString = ConfigurationManager.AppSettings["StorageConnectionString"];
// Instantiate a QueueClient which will be used to manipulate the queue
QueueClient queueClient = new QueueClient(connectionString, queueName);
if (queueClient.Exists())
{
// Peek at the next message
PeekedMessage[] peekedMessage = queueClient.PeekMessages();
// Display the message
Console.WriteLine($"Peeked message: '{peekedMessage[0].Body}'");
}
}
Alterar o conteúdo de uma mensagem em fila
Você pode alterar o conteúdo de uma mensagem diretamente na fila. Se a mensagem representar uma tarefa de trabalho, você poderá usar esse recurso para atualizar o status da tarefa de trabalho. O código a seguir atualiza a mensagem de fila com novos conteúdos e define o tempo limite de visibilidade para estender mais 60 segundos. Isso salva o estado de trabalho associado à mensagem e dá ao cliente mais um minuto para continuar trabalhando na mensagem. Você pode usar essa técnica para rastrear fluxos de trabalho de várias etapas em mensagens de fila, sem ter que começar de novo desde o início se uma etapa de processamento falhar devido a uma falha de hardware ou software. Normalmente, você também manteria uma contagem de tentativas e, se a mensagem for repetida mais de n vezes, você a excluirá. Isso protege contra uma mensagem que dispara um erro de aplicativo cada vez que ele é processado.
//-------------------------------------------------
// Update an existing message in the queue
//-------------------------------------------------
public void UpdateMessage(string queueName)
{
// Get the connection string from app settings
string connectionString = ConfigurationManager.AppSettings["StorageConnectionString"];
// Instantiate a QueueClient which will be used to manipulate the queue
QueueClient queueClient = new QueueClient(connectionString, queueName);
if (queueClient.Exists())
{
// Get the message from the queue
QueueMessage[] message = queueClient.ReceiveMessages();
// Update the message contents
queueClient.UpdateMessage(message[0].MessageId,
message[0].PopReceipt,
"Updated contents",
TimeSpan.FromSeconds(60.0) // Make it invisible for another 60 seconds
);
}
}
Retirar a próxima mensagem da fila
Remova uma mensagem da fila em duas etapas. Quando você liga para ReceiveMessages
, você recebe a próxima mensagem em uma fila. Uma mensagem retornada do ReceiveMessages
torna-se invisível para qualquer outro código que lê mensagens dessa fila. Por padrão, essa mensagem permanece invisível por 30 segundos. Para concluir a remoção da mensagem da fila, você também deve chamar DeleteMessage
. Esse processo de duas etapas de remoção de uma mensagem garante que, se o código falhar ao processar uma mensagem devido a uma falha de hardware ou software, outra instância do código poderá receber a mesma mensagem e tentar novamente. O seu código chama DeleteMessage
imediatamente após a mensagem ter sido processada.
//-------------------------------------------------
// Process and remove a message from the queue
//-------------------------------------------------
public void DequeueMessage(string queueName)
{
// Get the connection string from app settings
string connectionString = ConfigurationManager.AppSettings["StorageConnectionString"];
// Instantiate a QueueClient which will be used to manipulate the queue
QueueClient queueClient = new QueueClient(connectionString, queueName);
if (queueClient.Exists())
{
// Get the next message
QueueMessage[] retrievedMessage = queueClient.ReceiveMessages();
// Process (i.e. print) the message in less than 30 seconds
Console.WriteLine($"Dequeued message: '{retrievedMessage[0].Body}'");
// Delete the message
queueClient.DeleteMessage(retrievedMessage[0].MessageId, retrievedMessage[0].PopReceipt);
}
}
Usar o padrão Async-Await com APIs comuns de armazenamento em fila
Este exemplo mostra como usar o padrão Async-Await com APIs comuns de armazenamento em fila. O exemplo invoca a versão assíncrona de cada um dos métodos fornecidos, conforme indicado pelo sufixo Async
de cada método. Quando um método assíncrono é usado, o padrão Async-Await suspende a execução local até que a chamada seja concluída. Esse comportamento permite que o thread atual faça outro trabalho, o que ajuda a evitar gargalos de desempenho e melhora a capacidade de resposta geral do seu aplicativo. Para obter mais detalhes sobre como usar o padrão Async-Await no .NET, consulte Async and Await (C# e Visual Basic)
//-------------------------------------------------
// Perform queue operations asynchronously
//-------------------------------------------------
public async Task QueueAsync(string queueName)
{
// Get the connection string from app settings
string connectionString = ConfigurationManager.AppSettings["StorageConnectionString"];
// Instantiate a QueueClient which will be used to manipulate the queue
QueueClient queueClient = new QueueClient(connectionString, queueName);
// Create the queue if it doesn't already exist
await queueClient.CreateIfNotExistsAsync();
if (await queueClient.ExistsAsync())
{
Console.WriteLine($"Queue '{queueClient.Name}' created");
}
else
{
Console.WriteLine($"Queue '{queueClient.Name}' exists");
}
// Async enqueue the message
await queueClient.SendMessageAsync("Hello, World");
Console.WriteLine($"Message added");
// Async receive the message
QueueMessage[] retrievedMessage = await queueClient.ReceiveMessagesAsync();
Console.WriteLine($"Retrieved message with content '{retrievedMessage[0].Body}'");
// Async delete the message
await queueClient.DeleteMessageAsync(retrievedMessage[0].MessageId, retrievedMessage[0].PopReceipt);
Console.WriteLine($"Deleted message: '{retrievedMessage[0].Body}'");
// Async delete the queue
await queueClient.DeleteAsync();
Console.WriteLine($"Deleted queue: '{queueClient.Name}'");
}
Usar opções adicionais para enfileirar mensagens
Há duas maneiras de personalizar a recuperação de mensagens de uma fila. Primeiro, você pode receber um lote de mensagens (até 32). Em segundo lugar, você pode definir um tempo limite de invisibilidade maior ou menor, permitindo que seu código tenha mais ou menos tempo para processar completamente cada mensagem.
O exemplo de código a seguir usa o método ReceiveMessages
para obter 20 mensagens em uma chamada. Em seguida, ele processa cada mensagem usando um loop de foreach
. Também define o tempo limite de invisibilidade para cinco minutos para cada mensagem. Observe que os cinco minutos começam para todas as mensagens ao mesmo tempo, portanto, após cinco minutos desde a chamada para ReceiveMessages
, todas as mensagens que não foram excluídas se tornarão visíveis novamente.
//-----------------------------------------------------
// Process and remove multiple messages from the queue
//-----------------------------------------------------
public void DequeueMessages(string queueName)
{
// Get the connection string from app settings
string connectionString = ConfigurationManager.AppSettings["StorageConnectionString"];
// Instantiate a QueueClient which will be used to manipulate the queue
QueueClient queueClient = new QueueClient(connectionString, queueName);
if (queueClient.Exists())
{
// Receive and process 20 messages
QueueMessage[] receivedMessages = queueClient.ReceiveMessages(20, TimeSpan.FromMinutes(5));
foreach (QueueMessage message in receivedMessages)
{
// Process (i.e. print) the messages in less than 5 minutes
Console.WriteLine($"De-queued message: '{message.Body}'");
// Delete the message
queueClient.DeleteMessage(message.MessageId, message.PopReceipt);
}
}
}
Obter o comprimento da fila
Você pode obter uma estimativa do número de mensagens em uma fila. O método GetProperties
retorna propriedades de fila, incluindo a contagem de mensagens. A propriedade ApproximateMessagesCount
contém o número aproximado de mensagens na fila. Esse número não é menor do que o número real de mensagens na fila, mas pode ser maior.
//-----------------------------------------------------
// Get the approximate number of messages in the queue
//-----------------------------------------------------
public void GetQueueLength(string queueName)
{
// Get the connection string from app settings
string connectionString = ConfigurationManager.AppSettings["StorageConnectionString"];
// Instantiate a QueueClient which will be used to manipulate the queue
QueueClient queueClient = new QueueClient(connectionString, queueName);
if (queueClient.Exists())
{
QueueProperties properties = queueClient.GetProperties();
// Retrieve the cached approximate message count.
int cachedMessagesCount = properties.ApproximateMessagesCount;
// Display number of messages.
Console.WriteLine($"Number of messages in queue: {cachedMessagesCount}");
}
}
Excluir uma fila
Para excluir uma fila e todas as mensagens contidas nela, chame o método Delete
no objeto queue.
//-------------------------------------------------
// Delete the queue
//-------------------------------------------------
public void DeleteQueue(string queueName)
{
// Get the connection string from app settings
string connectionString = ConfigurationManager.AppSettings["StorageConnectionString"];
// Instantiate a QueueClient which will be used to manipulate the queue
QueueClient queueClient = new QueueClient(connectionString, queueName);
if (queueClient.Exists())
{
// Delete the queue
queueClient.Delete();
}
Console.WriteLine($"Queue deleted: '{queueClient.Name}'");
}
Próximos passos
Agora que você aprendeu as noções básicas do armazenamento em fila, siga estes links para saber mais sobre tarefas de armazenamento mais complexas.
- Consulte a documentação de referência do Armazenamento em fila para obter detalhes completos sobre as APIs disponíveis:
- Biblioteca de cliente do Armazenamento do Azure para referência do .NET
- de referência da API REST do Armazenamento do Azure
- Veja mais guias de recursos para saber mais sobre opções adicionais para armazenar dados no Azure.
- Introdução ao Armazenamento de Tabela do Azure usando .NET para armazenar dados estruturados.
- Introdução ao Armazenamento de Blobs do Azure usando o .NET para armazenar dados não estruturados.
- Conecte-se ao Banco de dados SQL usando .NET (C#) para armazenar dados relacionais.
- Saiba como simplificar o código que você escreve para trabalhar com o Armazenamento do Azure usando o SDK de WebJobs do Azure.
Para exemplos de código relacionados usando SDKs do .NET versão 11.x preteridos, consulte Exemplos de código usando o .NET versão 11.x.