phpzendframework:使用 PHP 实现云计算 第 3 部分: 通过 Zend Framework 使用 Amazon SQS

  Amazon SQS 提供了消息排队系统基本功能虽然 SQS 不是设计用来取代企业级别消息系统但它确具有诸多有用特性本文着眼于 Zend Framework 内些能够简化 SQS 内消息处理思路方法

  立即开始

  在本文中您将看到如何使用 Simple Queue Service 完成几个重要任务和本系列其他文章如果能在开始的前安装好 Zend Framework 将会让您能够从我们给出这些举例中获益最多如果尚未安装可先从 Zend.com下载并安装整个包Zend Framework、PHP 和 Apache Web 服务器就会并安装好安装完成后访问 http://localhost/ZendServer/相关细节请参考 Zend Framework 安装文档若能登录到这个 ZendServer 控制台那介绍说明准备就绪

  此外可能还需要设立个 Amazon帐户

  本文中这些例子使用 使用 PHP 实现云计算第 1 部分:结合使用 Amazon S3 和 Zend Framework 内创建 PHP Credentials 类该类负责管理您 Amazon 帐号凭证这些凭证均存储于 .ini 文件内:

清单 1. 在 PHP .ini 文件内存储凭证

; Configuration file to hold secret keys, account numbers and other useful 
; s for Amazon and other cloud accounts. 
 
[amazon] 
accessKey=0123456789ABCDEFGHIJ 
secretKey=0123456789abcdefghiABCDEFGHI1234567890AB 
ownerId=123456789012 


  SQS 只使用您访问钥和密钥您无需知道您自己 ID但是您自己 ID 在您创建消息队列时会成为队列部分

  有关举例应用

  本文中举例应用包含个单 PHP 页面(sqs.php)它可执行多个功能:

  列出个帐户内所有消息队列包括每个队列中消息数量

  创建个消息队列

  创建个消息并将其放入个队列

  从个给定队列接收条消息

  删除个己接收消息

  删除个消息队列以及其内所有消息

  为了立即开始先来创建个 Zend_Service_Amazon_Sqs 对象

清单 2. 创建个 Zend_Service_Amazon_Sqs 对象

require_once 'Zend/Service/Amazon/Sqs.php'; 
require_once 'Credentials.php'; 
 
$creds =  Credentials; 
$sqs =  Zend_Service_Amazon_Sqs($creds->getCredential('amazon', 
 'accessKey'), $creds->getCredential('amazon', 'secretKey')); 


  这个对象让您能够处理和您帐户相关联队列Zend_Service_Amazon_Sqs->getQueues 思路方法会返回由属于您帐户所有队列名组成这个 PHP 页以表形式显示了这些队列名:

图 1. 列出 SQS 队列




  消息队列名中包括您帐户所有者 ID在本例中这些队列属于所有者 ID 为 123456789012在访问个队列或消息时必须使用完全限定队列名(http://queue.amazonaws.com/ownerId/queueName)这里表可见部分还包括了每个队列中可见消息数量PHP 代码如下所示:

清单 3. 获得队列列表及每个队列内所含消息数量

$queues = $sqs->getQueues; 
foreach ($queues as $queue) { 
 try { 
 $messageCount = $sqs->count($queue); 
  echo "<tr>"; 
  echo "<td>".$queue."</td>"; 
  echo "<td style='text-align: center;'>".$messageCount."</td>"; 


  上述代码使用 count 思路方法来获得每个队列内所含消息数量(更准确地说是消息大致数量;稍后对此会详细介绍)如果队列中至少有个消息PHP 就会创建个按钮来接收文本消息;否则此单元格为空(参见图 2)

清单 4. 创建个按钮来接收文本消息

echo "<td>"; 
 ($messageCount) { 
 echo "<form action='".$_SERVER['PHP_SELF']."' method='post'>"; 
 echo "<input type='hidden' name='getNextMessage' value='1'>"; 
 echo "<input type='hidden' name='queueToUse' value='$queue'/>"; 
 echo "<input type='submit' value='Receive Next Message'>"; 
 echo "</form>"; 
} 
 
 echo "&nbsp;"; 
 echo "</td>"; 


  表每行最后个单元格会创建个按钮用来删除此队列及其内所含消息完整队列表如图 2 所示

图 2. 完整队列表




  在这个屏幕截图中有 3个队列其中包含消息两个队列显示了 “Receive Next Message” 按钮每行都具有个 “Delete Queue” 按钮用以删除某个队列

  创建个队列

  创建个队列非常简单只需获得队列名并 Zend_Service_Amazon_Sqs->create 思路方法PHP 页包含了个简单表单用以输入个队列名:

图 3. 创建个队列




  创建个新队列代码也很直观

清单 5. 创建个队列

try { 
 $responseCode = $sqs->create($_POST['queueToCreate']); 
  ($responseCode) 
  echo "The queue ".$_POST['queueToCreate']." was created successfully."; 
 . . . 
} 
catch (Zend_Service_Amazon_SQS_Exception $sqse) { 
 echo "The queue could not be created. The error message from Amazon is:"; 
 echo "<br/><br/><i>".$sqse->getMessage."</i>"; 
} 


  Zend 没有为 create 思路方法提供任何特殊处理所以若发生任何代码只会简单地将异常详细信息写至页面若试图创建个具有非法名称(比如 queue#3)队列会返回异常 InvalidParameterValue若试图创建个具有重复名称队列则会返回 QueueAlreadyExists当队列成功创建后页面就会显示个成功消息

清单 4. 队列创建成功


  创建个消息

  这个 PHP 页面还包含了个简短表单用以创建消息

图 5. 创建个消息




  请注意这个下拉列表已经被您帐户内队列名填充

图 6. 列出您帐户内所有队列




  构建这个下拉列表 PHP 代码如清单 6 所示

清单 6. 创建个用来选择队列下拉列表

<p>Select a queue:</p> 
<select name="queueForNewMessage"> 
<?php 
 foreach ($queues as $queue) { 
 echo "<option>".$queue."</option>"; 
 } 
?> 
</select> 
</code> 


  创建个新队列代码中使用了 send 思路方法

清单 7. 将个消息发送到个队列

try { 
 $response = $sqs->send($_POST['queueForNewMessage'], $_POST['Message']); 
  ($response) { 
  echo "The  message was successfully created in queue "; 
  echo $_POST['queueForNewMessage']; 
  echo ".<br/>The message ID is ".$response."."; 
 } 
  { 
  echo "The  message could not be created in queue "; 
  echo $_POST['queueForNewMessage']; 
  echo "."; 
 } 
} 
catch (Zend_Service_Amazon_SQS_Exception $sqse) { 
 echo "The message could not be created. The error message from Amazon is:"; 
 echo "<br/><br/><i>".$sqse->getMessage."</i>"; 
} 


  上述代码向 Amazon 发送了个请求如果在创建消息时发生任何问题页面就会显示异常在大多数情况下页面都会显示被成功创建消息 ID

图 7. 成功创建消息




  成功消息包括新消息 ID在接收消息时还会再次看到这个消息 ID

  有关传播延迟

  在像 SQS 这样分布系统内存在个问题是传播延迟出于性能和可靠性考虑多数云提供商会将您信息多个副本分散到他们网络这种设计积极面是如果某个机器宕机信息仍存在于网络其他地方这种方式消极面是要想将对您信息更改贯彻到整个网络需要花费大量时间这种延迟被称为传播延迟若您安装了本文中开发这个举例应用就会注意到传播延迟效果

  在创建个队列时若 PHP 页面显示个成功消息表明此队列被成功创建页面上还会显示个表列出您帐户内所有队列由 SQS 返回这个队列列表通常包含您刚刚创建这个队列但是如果您创建个消息几乎可以完全肯定这个队列表不会显示消息准确数量消息创建还没有反映到这个队列例如个具有 3个消息队列若在其中再创建个新消息由 SQS 返回数据将会告诉您消息被成功创建并且队列中只有 3个消息

  为了处理这种延迟页面包含了个用来刷新队列列表按钮

图 8. 刷新队列列表




  如果单击这个按钮来刷新队列此表将会包含消息准确数量(这个刷新按钮允许用户更新此表而无需重新提交创建消息请求)对于这里这个举例应用在删除个队列时传播延迟就可能成为个问题虽然 SQS 会报告它成功删除了队列但是其名称还经常会显示在列表内若此时询问 SQS 该队列内消息数量将会获得个异常出于这个原因用来生成队列列表代码使用了个 try 块来获得队列内消息数量如果对 count 思路方法失败代码将简单忽略这个异常

  为了有效使用 SQS需要牢记传播延迟这原因点也适用于很多其他云服务

  接收个消息

  对队列内消息处理般需要两个步骤:接收和删除接收到消息后Amazon SQS 会将该消息标为不可见消息应由您来处理所以能访问此队列任何人都不会看到该消息在接收到消息后段时间内删除这个消息也应由您负责每个队列都应该定义个可见性超时;如果您没有在该时间内删除此消息此消息会再次成为可见并可由任何人处理目前队列默认可见性超时般是 30 秒

  在创建队列时Amazon 允许为所有被处理消息定义可见性超时Zend Framework 支持 Zend_Service_Amazon_Sqs->create 思路方法第 2个参数以便定义可见性超时

清单 8. 为个队列定义可见性超时

$responseCode = $sqs->create($_POST['queueToCreate'], 120); 

  在本例中可见性超时是 2 分钟

  从个队列接收消息是由 Zend_Service_Amazon_Sqs->receive 思路方法完成消息队列名称从表单传递进来由于消息最多可以有 8K 个因此它被显示在个 HTML <textarea> Control控件内接收到消息具有 4个部分:

  body:消息本身文本

  消息体 md5 摘要

  message_id:消息标识符

  handle:从队列删除消息必须使用标识符

  用以上给出可以访问消息这 4个部分例如可以使用 $message[0]['body'] 来获得消息主体用 $message[0]['handle'] 返回消息句柄请注意虽然 Amazon SQS 允许次请求多个消息Zend Framework 却不允许对 Zend_Service_Amazon_Sqs->receive 每次均返回单个消息这个单个消息是以形式返回不过必须使用 $message[0][...] 来访问消息这些部分

  注意:某些消息系统允许无需接收消息即可查看它这种操作常被称为窥视(peeking)Amazon SQS 却不再允许对消息进行窥视查看消息思路方法是先接收它

  单击 “Receive Next Message” 按钮后结果应如图 9 所示

图 9. 个接收到消息




  可见性超时用来生成这样个句子 “It will go back o the queue in 30 seconds.”稍后就会详细介绍队列属性

图 10. 消息句柄和可见性超时




  正如的前提到$message[0]['handle'] 返回消息句柄使用 getAttribute 思路方法可以返回可见性超时

清单 9. 找到队列可见性超时

$visibilityTimeout = 
 $sqs->getAttribute($_POST['queueToUse'], 'VisibilityTimeout'); 


  可见性超时用来生成句子 “It will go back o the queue in 30 seconds.”getAttribute 让您可以找到队列各种详细信息;稍后会详细介绍队列属性

  显示所接收消息这个表单是由如下代码生成

清单 10. 为所接收消息生成表单

echo "<form action='".$_SERVER['PHP_SELF']."' method='post'>"; 
 
// Display the message itself in a <textarea> 
echo "The message from the queue is: <br/><br/>"; 
echo "<textarea cols='80' rows='8'>"; 
echo $message[0]['body']; 
echo "</textarea><br/><br/>"; 
 
// The message handle and queue name are hidden fields 
echo "<input type='hidden' name='deleteMessage' value='1'/>"; 
echo "<input type='hidden' name='messageHandle' "; 
echo "value='".$message[0]['handle']."'>"; 
echo "<input type='hidden' name='queueToUse' "; 
echo "value='".$_POST['queueToUse']."'>"; 
 
// The submit button deletes the message 
echo "To delete this message, click here: "; 
echo "<input type='submit' value='Delete Message'><br/><br/>"; 
 
// Display the message handle  the user wants to delete it later 
echo "If you want to delete this message "; 
echo "later, use this message handle: <br/><br/>"; 
echo "<textarea cols='80' rows='3'>"; 
echo $message[0]['handle']."</textarea><br/><br/>"; 
 
// For information, display the visibility timeout of the queue 
echo "If you do not delete this message, it will "; 
echo "go back o the queue in ".$visibilityTimeout." seconds."; 
echo "</form>"; 


  删除个消息

  正如在的前节中所提到显示所接收消息表单还包含了个用来删除消息按钮若要 Zend_Service_Amazon_Sqs->deleteMessage 思路方法需要队列名和消息句柄

清单 11. 从个队列删除消息

try { 
 $response = $sqs->deleteMessage($_POST['queueToUse'], 
   $_POST['messageHandle']); 
 echo "The message was deleted successfully."; 
} 
catch (Zend_Service_Amazon_SQS_Exception $sqse) { 
 echo "The message could not be deleted. The error message from Amazon is:"; 
 echo "<br/><br/><i>".$sqse->getMessage."</i>"; 
} 


  如果消息被成功删除页面就会显示条消息

图 11. 消息成功删除




  如果发生任何问题此代码就会显示个异常(创建个表单来让用户通过传递消息句柄和队列名删除消息操作留给读者自己练习)

  获得队列属性

  正如的前提到在接收消息时PHP 页面会显示可见性超时这是通过 getAttribute 完成getAttribute 个属性是队列名对于第 2个参数Amazon 目前支持如下属性名并且大小写敏感:

  VisibilityTimeout — 接收自此队列消息可见性超时

  ApproximateNumberOfMessages — 目前队列内消息大致数量这不包含已接收到任何消息

Tags:  zendframework教程 zendframework zendframework使用 phpzendframework

延伸阅读

最新评论

发表评论