Como utilizar o Armazenamento de Filas a partir do PHP

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.

Este guia mostra-lhe como realizar cenários comuns com o serviço Armazenamento de Filas do Azure. Os exemplos são escritos através de classes da biblioteca de cliente do Armazenamento do Azure para PHP. Os cenários abrangidos incluem inserir, pré-visualizar, obter e eliminar mensagens de fila, bem como criar e eliminar filas.

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 para processar de forma assíncrona.

Conceitos de serviço de 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 tempo de vida 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 PHP

O único requisito para criar uma aplicação PHP que aceda ao Armazenamento de Filas do Azure é a referência de classes na biblioteca de cliente do Armazenamento do Azure para PHP a partir do seu código. Pode utilizar qualquer ferramenta de desenvolvimento para criar a sua aplicação, incluindo o Notepad.

Neste guia, vai utilizar as funcionalidades do serviço Armazenamento de Filas que podem ser chamadas numa aplicação PHP localmente ou em código em execução numa aplicação Web no Azure.

Obter as bibliotecas de cliente do Azure

Instalar através de compositor

  1. Crie um ficheiro com o nome composer.json na raiz do projeto e adicione o seguinte código ao mesmo:

    {
      "require": {
        "microsoft/azure-storage-queue": "*"
      }
    }
    
  2. Transfira composer.phar na raiz do projeto.

  3. Abra uma linha de comandos e execute o seguinte comando na raiz do projeto:

    php composer.phar install
    

Em alternativa, aceda à biblioteca de cliente PHP do Armazenamento do Azure no GitHub para clonar o código fonte.

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

Para utilizar as APIs para o Armazenamento de Filas do Azure, tem de:

  1. Faça referência ao ficheiro do carregador automático com a require_once instrução .
  2. Faça referência a todas as classes que possa utilizar.

O exemplo seguinte mostra como incluir o ficheiro do carregador automático e referenciar a QueueRestProxy classe.

require_once 'vendor/autoload.php';
use MicrosoftAzure\Storage\Queue\QueueRestProxy;

Nos exemplos seguintes, a require_once instrução é sempre apresentada, mas apenas as classes necessárias para executar o exemplo são referenciadas.

Configurar uma ligação do Armazenamento do Azure

Para instanciar um cliente do Armazenamento de Filas do Azure, primeiro tem de ter uma cadeia de ligação válida. O formato da cadeia de ligação armazenamento de filas é o seguinte.

Para aceder a um serviço em direto:

DefaultEndpointsProtocol=[http|https];AccountName=[yourAccount];AccountKey=[yourKey]

Para aceder ao armazenamento do emulador:

UseDevelopmentStorage=true

Para criar um cliente do Armazenamento de Filas do Azure, tem de utilizar a QueueRestProxy classe. Pode utilizar qualquer uma das seguintes técnicas:

Nos exemplos aqui descritos, a cadeia de ligação é transmitida diretamente.

require_once 'vendor/autoload.php';

use MicrosoftAzure\Storage\Queue\QueueRestProxy;

$connectionString = "DefaultEndpointsProtocol=http;AccountName=<accountNameHere>;AccountKey=<accountKeyHere>";
$queueClient = QueueRestProxy::createQueueService($connectionString);

Criar uma fila

Um QueueRestProxy objeto permite-lhe criar uma fila com o CreateQueue método . Ao criar uma fila, pode definir opções na fila, mas não é necessário fazê-lo. Este exemplo mostra como definir metadados numa fila.

require_once 'vendor/autoload.php';

use MicrosoftAzure\Storage\Queue\QueueRestProxy;
use MicrosoftAzure\Storage\Common\Exceptions\ServiceException;
use MicrosoftAzure\Storage\Queue\Models\CreateQueueOptions;

$connectionString = "DefaultEndpointsProtocol=http;AccountName=<accountNameHere>;AccountKey=<accountKeyHere>";

// Create queue REST proxy.
$queueClient = QueueRestProxy::createQueueService($connectionString);

// OPTIONAL: Set queue metadata.
$createQueueOptions = new CreateQueueOptions();
$createQueueOptions->addMetaData("key1", "value1");
$createQueueOptions->addMetaData("key2", "value2");

try    {
    // Create queue.
    $queueClient->createQueue("myqueue", $createQueueOptions);
}
catch(ServiceException $e){
    // Handle exception based on error codes and messages.
    // Error codes and messages are here:
    // https://msdn.microsoft.com/library/azure/dd179446.aspx
    $code = $e->getCode();
    $error_message = $e->getMessage();
    echo $code.": ".$error_message."<br />";
}

Nota

Não deve depender da sensibilidade a maiúsculas e minúsculas para chaves de metadados. Todas as chaves são lidas a partir do serviço em minúsculas.

Adicionar uma mensagem a uma fila

Para adicionar uma mensagem a uma fila, utilize QueueRestProxy->createMessage. O método utiliza o nome da fila, o texto da mensagem e as opções de mensagem (que são opcionais).

require_once 'vendor/autoload.php';

use MicrosoftAzure\Storage\Queue\QueueRestProxy;
use MicrosoftAzure\Storage\Common\Exceptions\ServiceException;
use MicrosoftAzure\Storage\Queue\Models\CreateMessageOptions;

$connectionString = "DefaultEndpointsProtocol=http;AccountName=<accountNameHere>;AccountKey=<accountKeyHere>";

// Create queue REST proxy.
$queueClient = QueueRestProxy::createQueueService($connectionString);

try    {
    // Create message.
    $queueClient->createMessage("myqueue", "Hello, World");
}
catch(ServiceException $e){
    // Handle exception based on error codes and messages.
    // Error codes and messages are here:
    // https://msdn.microsoft.com/library/azure/dd179446.aspx
    $code = $e->getCode();
    $error_message = $e->getMessage();
    echo $code.": ".$error_message."<br />";
}

Pré-visualização da mensagem seguinte

Pode espreitar uma ou mais mensagens na frente de uma fila sem as remover da fila ao chamar QueueRestProxy->peekMessages. Por predefinição, o peekMessage método devolve uma única mensagem, mas pode alterar esse valor com o PeekMessagesOptions->setNumberOfMessages método .

require_once 'vendor/autoload.php';

use MicrosoftAzure\Storage\Queue\QueueRestProxy;
use MicrosoftAzure\Storage\Common\Exceptions\ServiceException;
use MicrosoftAzure\Storage\Queue\Models\PeekMessagesOptions;

$connectionString = "DefaultEndpointsProtocol=http;AccountName=<accountNameHere>;AccountKey=<accountKeyHere>";

// Create queue REST proxy.
$queueClient = QueueRestProxy::createQueueService($connectionString);

// OPTIONAL: Set peek message options.
$message_options = new PeekMessagesOptions();
$message_options->setNumberOfMessages(1); // Default value is 1.

try    {
    $peekMessagesResult = $queueClient->peekMessages("myqueue", $message_options);
}
catch(ServiceException $e){
    // Handle exception based on error codes and messages.
    // Error codes and messages are here:
    // https://msdn.microsoft.com/library/azure/dd179446.aspx
    $code = $e->getCode();
    $error_message = $e->getMessage();
    echo $code.": ".$error_message."<br />";
}

$messages = $peekMessagesResult->getQueueMessages();

// View messages.
$messageCount = count($messages);
if($messageCount <= 0){
    echo "There are no messages.<br />";
}
else{
    foreach($messages as $message)    {
        echo "Peeked message:<br />";
        echo "Message Id: ".$message->getMessageId()."<br />";
        echo "Date: ".date_format($message->getInsertionDate(), 'Y-m-d')."<br />";
        echo "Message text: ".$message->getMessageText()."<br /><br />";
    }
}

Remover a mensagem seguinte da fila

O código remove uma mensagem de uma fila em dois passos. Primeiro, chama QueueRestProxy->listMessages, o que torna a mensagem invisível para qualquer outro código que esteja a ler a partir da fila. Por predefinição, esta mensagem permanece invisível durante 30 segundos. (Se a mensagem não for eliminada neste período de tempo, ficará novamente visível na fila.) Para concluir a remoção da mensagem da fila, tem de ligar para QueueRestProxy->deleteMessage. Este processo de dois passos de remoção de uma mensagem garante que quando o código não processa uma mensagem devido a uma falha de hardware ou software, outra instância do código pode obter a mesma mensagem e tentar novamente. O código chama deleteMessage logo após o processamento da mensagem.

require_once 'vendor/autoload.php';

use MicrosoftAzure\Storage\Queue\QueueRestProxy;
use MicrosoftAzure\Storage\Common\Exceptions\ServiceException;

$connectionString = "DefaultEndpointsProtocol=http;AccountName=<accountNameHere>;AccountKey=<accountKeyHere>";

// Create queue REST proxy.
$queueClient = QueueRestProxy::createQueueService($connectionString);

// Get message.
$listMessagesResult = $queueClient->listMessages("myqueue");
$messages = $listMessagesResult->getQueueMessages();
$message = $messages[0];

/* ---------------------
    Process message.
   --------------------- */

// Get message ID and pop receipt.
$messageId = $message->getMessageId();
$popReceipt = $message->getPopReceipt();

try    {
    // Delete message.
    $queueClient->deleteMessage("myqueue", $messageId, $popReceipt);
}
catch(ServiceException $e){
    // Handle exception based on error codes and messages.
    // Error codes and messages are here:
    // https://msdn.microsoft.com/library/azure/dd179446.aspx
    $code = $e->getCode();
    $error_message = $e->getMessage();
    echo $code.": ".$error_message."<br />";
}

Alterar os conteúdos de uma mensagem em fila

Pode alterar o conteúdo de uma mensagem no local na fila ao chamar QueueRestProxy->updateMessage. Se a mensagem representa uma tarefa de trabalho, pode utilizar esta funcionalidade para atualizar o estado da tarefa de trabalho. O código seguinte atualiza a mensagem de fila com novos conteúdos e define o tempo limite de visibilidade para prolongar mais 60 segundos. Isto guarda o estado de trabalho associado à mensagem e dá ao cliente mais um 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 desde o 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.

require_once 'vendor/autoload.php';

use MicrosoftAzure\Storage\Queue\QueueRestProxy;
use MicrosoftAzure\Storage\Common\Exceptions\ServiceException;

// Create queue REST proxy.
$queueClient = QueueRestProxy::createQueueService($connectionString);

$connectionString = "DefaultEndpointsProtocol=http;AccountName=<accountNameHere>;AccountKey=<accountKeyHere>";

// Get message.
$listMessagesResult = $queueClient->listMessages("myqueue");
$messages = $listMessagesResult->getQueueMessages();
$message = $messages[0];

// Define new message properties.
$new_message_text = "New message text.";
$new_visibility_timeout = 5; // Measured in seconds.

// Get message ID and pop receipt.
$messageId = $message->getMessageId();
$popReceipt = $message->getPopReceipt();

try    {
    // Update message.
    $queueClient->updateMessage("myqueue",
                                $messageId,
                                $popReceipt,
                                $new_message_text,
                                $new_visibility_timeout);
}
catch(ServiceException $e){
    // Handle exception based on error codes and messages.
    // Error codes and messages are here:
    // https://msdn.microsoft.com/library/azure/dd179446.aspx
    $code = $e->getCode();
    $error_message = $e->getMessage();
    echo $code.": ".$error_message."<br />";
}

Opções adicionais para descodificação de mensagens

Existem duas formas de 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 visibilidade mais longo ou mais curto, permitindo ao código mais ou menos tempo para processar totalmente cada mensagem. O seguinte exemplo de código utiliza o getMessages método para obter 16 mensagens numa chamada. Em seguida, processa cada mensagem através de um for ciclo. Define também o tempo limite de invisibilidade para cinco minutos para cada mensagem.

require_once 'vendor/autoload.php';

use MicrosoftAzure\Storage\Queue\QueueRestProxy;
use MicrosoftAzure\Storage\Common\Exceptions\ServiceException;
use MicrosoftAzure\Storage\Queue\Models\ListMessagesOptions;

$connectionString = "DefaultEndpointsProtocol=http;AccountName=<accountNameHere>;AccountKey=<accountKeyHere>";

// Create queue REST proxy.
$queueClient = QueueRestProxy::createQueueService($connectionString);

// Set list message options.
$message_options = new ListMessagesOptions();
$message_options->setVisibilityTimeoutInSeconds(300);
$message_options->setNumberOfMessages(16);

// Get messages.
try{
    $listMessagesResult = $queueClient->listMessages("myqueue",
                                                     $message_options);
    $messages = $listMessagesResult->getQueueMessages();

    foreach($messages as $message){

        /* ---------------------
            Process message.
        --------------------- */

        // Get message Id and pop receipt.
        $messageId = $message->getMessageId();
        $popReceipt = $message->getPopReceipt();

        // Delete message.
        $queueClient->deleteMessage("myqueue", $messageId, $popReceipt);
    }
}
catch(ServiceException $e){
    // Handle exception based on error codes and messages.
    // Error codes and messages are here:
    // https://msdn.microsoft.com/library/azure/dd179446.aspx
    $code = $e->getCode();
    $error_message = $e->getMessage();
    echo $code.": ".$error_message."<br />";
}

Obter o comprimento da fila

Pode obter uma estimativa do número de mensagens numa fila. O QueueRestProxy->getQueueMetadata método obtém metadados sobre a fila. Chamar o getApproximateMessageCount método no objeto devolvido fornece uma contagem de quantas mensagens estão numa fila. A contagem só é aproximada porque as mensagens podem ser adicionadas ou removidas após o Armazenamento de Filas responder ao seu pedido.

require_once 'vendor/autoload.php';

use MicrosoftAzure\Storage\Queue\QueueRestProxy;
use MicrosoftAzure\Storage\Common\Exceptions\ServiceException;

$connectionString = "DefaultEndpointsProtocol=http;AccountName=<accountNameHere>;AccountKey=<accountKeyHere>";

// Create queue REST proxy.
$queueClient = QueueRestProxy::createQueueService($connectionString);

try    {
    // Get queue metadata.
    $queue_metadata = $queueClient->getQueueMetadata("myqueue");
    $approx_msg_count = $queue_metadata->getApproximateMessageCount();
}
catch(ServiceException $e){
    // Handle exception based on error codes and messages.
    // Error codes and messages are here:
    // https://msdn.microsoft.com/library/azure/dd179446.aspx
    $code = $e->getCode();
    $error_message = $e->getMessage();
    echo $code.": ".$error_message."<br />";
}

echo $approx_msg_count;

Eliminar uma fila

Para eliminar uma fila e todas as mensagens na mesma, chame o QueueRestProxy->deleteQueue método .

require_once 'vendor/autoload.php';

use MicrosoftAzure\Storage\Queue\QueueRestProxy;
use MicrosoftAzure\Storage\Common\Exceptions\ServiceException;

$connectionString = "DefaultEndpointsProtocol=http;AccountName=<accountNameHere>;AccountKey=<accountKeyHere>";

// Create queue REST proxy.
$queueClient = QueueRestProxy::createQueueService($connectionString);

try    {
    // Delete queue.
    $queueClient->deleteQueue("myqueue");
}
catch(ServiceException $e){
    // Handle exception based on error codes and messages.
    // Error codes and messages are here:
    // https://msdn.microsoft.com/library/azure/dd179446.aspx
    $code = $e->getCode();
    $error_message = $e->getMessage();
    echo $code.": ".$error_message."<br />";
}

Passos seguintes

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

Para obter mais informações, veja o centro de programadores PHP.