Использование Хранилища очередей из PHP

Совет

Пробное использование обозревателя хранилищ Microsoft Azure

Обозреватель хранилищ Microsoft Azure — это бесплатное автономное приложение от корпорации Майкрософт, позволяющее визуализировать данные из службы хранилища Azure на платформе Windows, macOS и Linux.

В этом руководстве показано, как реализовывать распространенные сценарии с использованием службы "Хранилище очередей Azure". Примеры написаны с использованием классов из клиентской библиотеки службы хранилища Azure для PHP. Здесь описаны такие сценарии, как вставка, просмотр, получение и удаление сообщений очереди, а также создание и удаление очередей.

Что такое хранилище очередей?

Хранилище очередей Azure — это служба для хранения большого количества сообщений, к которым можно получить доступ практически из любой точки мира с помощью вызовов с проверкой подлинности по протоколам HTTP или HTTPS. Одно сообщение очереди может быть размером до 64 КБ, а очередь может содержать миллионы сообщений до общего ограничения емкости учетной записи хранения. Хранилище очередей часто используется для создания списка невыполненных заданий для асинхронной обработки.

Основные понятия службы очередей

Служба очередей Azure содержит следующие компоненты:

Компоненты служба очередей Azure

  • Учетная запись хранения. Весь доступ к хранилищу Azure осуществляется с помощью учетной записи хранения. См. сведения об учетных записях хранения.

  • Очередь. Очередь содержит набор сообщений. Все сообщения должны находиться в очереди. Обратите внимание: имя очереди должно содержать только строчные символы. Дополнительные сведения см. в статье о присвоении имен очередям и метаданным.

  • Сообщение. Сообщение в любом формате размером до 64 КБ. Сообщение может оставаться в очереди не более 7 дней. Начиная с версии 2017-07-29, максимальный срок жизни может быть задан любым положительным числом или значением -1, свидетельствующим о том, что срок жизни сообщения неограничен. Если этот параметр не указан, срок жизни по умолчанию составляет семь дней.

  • Формат URL-адреса: обращаться к очередям можно с помощью URL-адреса следующего вида: http://<storage account>.queue.core.windows.net/<queue>

    Следующий URL-адрес позволяет обратиться к очереди на схеме:

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

Создание учетной записи хранения Azure

Самый простой способ создать первую учетную запись хранения Azure — воспользоваться порталом Azure. Дополнительную информацию см. в статье Об учетных записях хранения Azure.

Кроме того, создать учетную запись хранения Azure можно с помощью Azure PowerShell, Azure CLI или поставщика ресурсов службы хранилища Azure для .NET.

Если вы не хотите сейчас создавать учетную запись хранения в Azure, код можно запустить и протестировать в локальной среде с помощью эмулятора хранилища Azurite. Дополнительные сведения см. в статье Использование эмулятора Azurite для разработки и тестирования службы хранилища Azure.

Создание приложения PHP

Единственное, что требуется для создания приложения на языке PHP, которое получает доступ к Хранилищу очередей Azure — это дать из кода приложения ссылку на классы клиентской библиотеки службы хранилища Azure для PHP. Можно использовать любые средства разработки для создания приложения, включая программу "Блокнот".

В этом руководстве будут использоваться компоненты службы "Хранилище очередей", которые могут быть вызваны локально из приложения на языке PHP или из кода, работающего в веб-приложении Azure.

Получение клиентских библиотек Azure

Установка с помощью Composer

  1. Создайте файл с именем composer.json в корневой папке проекта и добавьте в него следующий код:

    {
      "require": {
        "microsoft/azure-storage-queue": "*"
      }
    }
    
  2. Скачайте файл composer.phar в корневую папку проекта.

  3. Откройте командную строку и выполните следующую команду в корневом каталоге проекта:

    php composer.phar install
    

Как вариант, можно перейти в клиентскую библиотеку службы хранилища Azure для PHP на GitHub и клонировать исходный код оттуда.

Настройка приложения для доступа к хранилищу очередей

Чтобы использовать API Хранилища очередей Azure, требуется:

  1. Ссылка на файл автозагрузчика с использованием оператора require_once.
  2. Ссылка на любые классы, которые могут использоваться.

В следующем примере показано, как включить файл автозагрузчика и добавить ссылку на класс QueueRestProxy.

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

В следующих примерах оператор require_once показан всегда, но ссылки даются только на классы, необходимые для выполнения примера.

Настройка подключения к службе хранилища Azure

Чтобы создать экземпляр клиента Хранилища очередей Azure, необходимо сначала сформировать правильную строку подключения. Строка подключения к Хранилищу очередей имеет следующий формат.

Для доступа к службе в режиме реального времени:

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

Для доступа к хранилищу эмулятора:

UseDevelopmentStorage=true

Для создания клиента Хранилища очередей Azure необходимо использовать класс QueueRestProxy. Для этого можно использовать один из следующих методов.

В приведенных здесь примерах строка подключения передается напрямую.

require_once 'vendor/autoload.php';

use MicrosoftAzure\Storage\Queue\QueueRestProxy;

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

Создание очереди

Объект QueueRestProxy позволяет создать очередь с использованием метода CreateQueue. При создании очереди можно задать ее параметры, однако это не является обязательным. В этом примере показано, как задать метаданные очереди.

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

Примечание

Не следует полагаться на учет регистра для ключей метаданных. Все параметры считываются из службы в нижнем регистре.

Добавление сообщения в очередь

Чтобы добавить сообщение в очередь, используйте метод QueueRestProxy->createMessage. Этот метод принимает имя очереди, текст сообщения и параметры сообщения (которые не являются обязательными).

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

Просмотр следующего сообщения

Вы можете просмотреть одно или несколько сообщений в начале очереди, не удаляя его из очереди, вызвав метод QueueRestProxy->peekMessages. По умолчанию метод peekMessage возвращает одно сообщение, но это можно изменить, воспользовавшись методом PeekMessagesOptions->setNumberOfMessages.

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

Удаление следующего сообщения из очереди

Ваш код удаляет сообщение из очереди в два этапа. Сначала вызовите метод QueueRestProxy->listMessages, который делает сообщение невидимым для любого другого кода, который считывает данные из очереди. По умолчанию это сообщение остается невидимым в течение 30 секунд. (Если сообщение не удаляется в течение этого периода, оно снова становится видимым в очереди.) Чтобы завершить удаление сообщения из очереди, необходимо далее вызвать метод QueueRestProxy->deleteMessage. Этот двухэтапный процесс удаления сообщения позволяет удостовериться, что если коду не удастся обработать сообщение из-за сбоя оборудования или программного обеспечения, другой экземпляр кода сможет получить то же сообщение и повторить попытку. Код вызывает deleteMessage сразу после обработки сообщения.

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

Изменение содержимого сообщения в очереди

Изменить содержимое сообщения можно непосредственно в очереди, вызвав метод QueueRestProxy->updateMessage. Если сообщение представляет собой рабочую задачу, можно использовать эту функцию для обновления состояния рабочей задачи. Следующий код добавляет новое содержимое в сообщение очереди и продлевает время ожидания видимости еще на 60 секунд. Это сохраняет состояние работы, связанной с данным сообщением, и позволяет клиенту продолжить работу с сообщением на протяжении еще одной минуты. Этот метод можно использовать для отслеживания многошаговых рабочих процессов по сообщениям в очереди без необходимости начинать с самого начала в случае сбоя шага обработки в связи с ошибкой аппаратного или программного обеспечения. Обычно также сохраняется счетчик повторов. Если количество повторов сообщения превысит n раз, его нужно удалить. Это обеспечивает защиту от сообщений, которые инициируют ошибку приложения при каждой попытке обработки.

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

Дополнительные варианты удаления сообщений из очереди

Существует два способа настройки извлечения сообщения из очереди. Во-первых, можно получить пакет сообщений (до 32 сообщений). Во-вторых, можно задать более длительное или короткое время ожидания видимости, чтобы предоставить коду больше или меньше времени на полную обработку каждого сообщения. В следующем примере кода метод getMessages используется для получения 16 сообщений за один вызов. Затем каждое сообщение обрабатывается в цикле for. Он также задает время ожидания невидимости 5 минут для каждого сообщения.

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

Получение длины очереди

Вы можете узнать приблизительное количество сообщений в очереди. Метод QueueRestProxy->getQueueMetadata служит для получения метаданных очереди. Вызов метода getApproximateMessageCount для возвращенного объекта позволяет получить число сообщений в очереди. Число это будет лишь приблизительным, так как сообщения могут быть добавлены или удалены после ответа Хранилища очередей на ваш запрос.

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;

Удаление очереди

Чтобы удалить очередь и все содержащиеся в ней сообщения, вызовите метод QueueRestProxy->deleteQueue.

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

Дальнейшие действия

Вы получили основные сведения о Хранилище очередей Azure. Подробнее о решении более сложных задач с использованием Хранилища можно узнать по следующим ссылкам.

Дополнительные сведения см. в Центре разработчиков PHP.