如何使用 PHP 的佇列儲存體

提示

Microsoft Azure 儲存體總管

Microsoft Azure 儲存體總管 是一個免費的獨立應用程式,可讓您在 Windows、MacOS 和 Linux 上以視覺化方式處理 Azure 儲存體資料。

本指南說明如何使用 Azure 佇列儲存體服務執行一般案例。 這些範例是透過適用於 PHP 的 Azure 儲存體用戶端程式庫的類別所撰寫。 所涵蓋的案例包括插入、查看、取得和刪除佇列訊息,以及建立和刪除佇列。

什麼是佇列儲存體?

Azure 佇列儲存體是一項儲存大量訊息的服務,全球任何地方都可利用 HTTP 或 HTTPS 並透過驗證的呼叫來存取這些訊息。 單一佇列訊息的大小上限為 64 KB,而一個佇列可以包含數百萬個訊息,以儲存體帳戶的總容量為限。 佇列儲存體通常用來建立要以非同步方式處理的待處理項目。

佇列服務概念

Azure 佇列服務包含下列元件:

Azure 佇列服務元件

  • 儲存體帳戶: 一律透過儲存體帳戶來存取 Azure 儲存體。 如需儲存體帳戶的詳細資訊,請參閱儲存體帳戶概觀

  • 佇列: 佇列包含一組訊息。 所有訊息都必須放在佇列中。 請注意,佇列名稱必須是小寫。 如需為佇列命名的詳細資訊,請參閱 為佇列和中繼資料命名

  • 訊息: 大小上限為 64 KB 的訊息 (任何格式)。 訊息可保留在佇列中的時間上限為 7 天。 如需版本 2017-07-29 或更新版本,最大存留時間可以是任何正數,或是表示訊息未過期的 -1。 如果省略此參數,則預設存留時間為 7 天。

  • URL 格式:您可以使用以下 URL 格式來定址佇列:http://<storage account>.queue.core.windows.net/<queue>

    下列 URL 可定址圖中的佇列:

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

建立 Azure 儲存體帳戶

建立您第一個 Azure 儲存體帳戶最簡單的方法,就是使用 Azure 入口網站。 若要深入了解,請參閱 建立儲存體帳戶

您也可以使用 Azure PowerShellAzure CLI,或 Azure Storage Resource Provider for .NET 來建立 Azure 儲存體帳戶。

如果您不想此時在 Azure 中建立儲存體帳戶,也可以使用 Azure 儲存體模擬器在本機環境中執行並測試您的程式碼。 如需詳細資訊,請參閱使用 Azure 模擬器進行本機 Azure 儲存體開發

建立 PHP 應用程式

若要建立 PHP 應用程式並使其存取 Azure 佇列儲存體,唯一要求就是在您的程式碼中參考適用於 PHP 的 Azure 儲存體用戶端程式庫中的類別。 您可以使用任何開發工具來建立應用程式 (包括 [記事本])。

在本指南中,您將使用可從 PHP 應用程式內本機呼叫的佇列儲存體服務功能,或可在 Azure 中 Web 應用程式內執行的程式碼中呼叫的佇列儲存體功能。

取得 Azure 用戶端程式庫

透過編輯器安裝

  1. 在專案的根目錄中建立名為 composer.json 的檔案,並新增下列程式碼:

    {
      "require": {
        "microsoft/azure-storage-queue": "*"
      }
    }
    
  2. 在您的專案根目錄中下載 composer.phar

  3. 開啟命令提示字元,在專案根目錄中執行下列命令:

    php composer.phar install
    

或者,移至 GitHub 上的 Azure 儲存體 PHP 用戶端程式庫來複製原始程式碼。

設定您的應用程式以存取佇列儲存體

若要使用 Azure 佇列儲存體的 API,您需要:

  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 類別。 您可以使用下列其中一種方式:

  • 直接將連接字串傳遞給它。
  • 使用 Web 應用程式中的環境變數來儲存連接字串。 請參閱 Azure Web 應用程式組態設定文件來設定連接字串。

在本文的各範例中,將會直接傳遞連接字串。

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 迴圈處理每個訊息。 它也會將可見度逾時設定為每個訊息五分鐘。

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 開發人員中心