用Amazon Web Services进行云计算,第4部分:用SQS进行可靠的消息传递

日期: 2009-05-30 作者:Prabhakar Chaganti 来源:TechTarget中国 英文

  学习基本的Amazon SimpleDB(SDB)概念,研究boto(一个用于与SDB交互的开放源码Python库)提供的一些功能。在这个“用Amazon Web Services进行云计算”系列中,学习如何使用Amazon Web Services进行云计算。了解这些服务如何为设计和构建可伸缩、可靠的应用程序提供一种可选方案。在本文中,了解Amazon Simple Queue Service(SQS)提供的可靠且可伸缩的消息传递服务。

  Amazon SQS

  Amazon Simple Queue Service(SQS)是一个可伸缩且可靠的消息传递框架,可以使用它简便地创建、存储和获取文本消息。可以使用它构建基于Amazon Web Services的应用程序。使用SQS是构建松散耦合的Web应用程序的好方法。只需根据使用量为消息付费。整个队列框架在Amazon数据中心的安全环境中运行。

  SQS提供以下特性:

  可靠性
  SQS能够跨多个数据中心冗余地存储消息,保证它们随时可用。

  简单性
  访问和使用SQS的编程模型非常简单,而且可以通过多种编程语言使用SQS。

  安全性
  SQS提供很高的安全水平。只允许授权的用户访问消息。

  可伸缩性
  可以用SQS创建基于队列的应用程序,这些程序可以读写数量不限的消息。

  低成本
  SQS以非常低廉的费率满足您的消息传递需求。

  下面讨论支撑SQS框架的概念。

  消息

  消息包含不超过8 KB的文本数据。每个消息一直存储到被应用程序接收为止。当接收消息的应用程序从队列中读取一个消息时,指定可见性超时值(以秒为单位)。它的作用就像是锁:

  ·确保在指定的时间段内队列的其他消费者看不到已被接收的消息。
  ·只有当超时周期过期时,而且读取消息的应用程序没有删除它,消息才会重新出现在队列中。

  SQS会自动删除在队列中超过四天的消息。SQS采用“最终一致性(eventual consistency)”模型,这意味着您可以向队列发送消息,但是队列的消费者不一定能够在特定的时间段内看到它。消息最终会投递,但是一定要考虑您的应用程序是否在意消息的次序。

  消息由表1所示的几个部分组成。

          

  表1. 消息的组成部分

  队列

  队列 是消息的容器。每个消息必须指定将容纳它的队列。发送给队列的消息保留在队列中,直到显式地删除它们。队列采用“先进先出”次序,但是并不保证次序。每个队列的默认可见性超时值是30秒。可以为整个队列修改这个值,也可以在获取消息时单独为每个消息设置。队列或消息可见性超时值的最大值是两小时(7,200秒)。如果队列中连续30天没有活动,SQS保留自动删除它们的权力。

  设计考虑因素

  SQS与常见的队列框架有点儿不一样。在设计基于SQS的应用程序之前,您必须考虑三个问题:

  ·SQS不保证队列中消息的次序。
  消息在队列中的次序是宽松的;它们实际上并不按照在队列中添加消息的次序存储。SQS会尝试保持消息的次序,但是不保证接收消息的次序与发送它们的次序完全相同。如果消息的次序对于您的应用程序很重要,就需要在每个消息中添加序列数据。

  ·SQS不保证删除队列中的消息。
  在设计应用程序时,必须保证多次处理同一消息不会对程序产生影响。SQS把每个消息存储在多台服务器上,从而提供冗余和高可用性。如果在删除一个消息时其中一个服务器不可用,那么在以后接收消息时有可能再次获取此消息的拷贝(尽管这种情况很少出现)。

  ·SQS不保证在查询时返回队列中的所有消息。
  SQS使用基于加权随机分布的消息取样,在查询消息时,它只从取样的一部分服务器返回消息。尽管一次查询请求可能不会返回队列中的所有消息,但是如果一直从队列中获取消息,最终会取样所有服务器,您就会得到所有消息。

  API版本

  有两个SQS版本:最初版本(2007-05-01)和2008-01-01版本。API的版本号通常采用发布日期。2007-05-01 API将于2009年5月6日废止,在此之后只支持API的最新版本。强烈建议用户:

  ·尽快开始迁移使用老API版本的应用程序。
  ·为了尽可能减少麻烦,在用SQS创建新应用程序时,应该使用API的最新版本。

  2008-01-01版本更新了定价,这降低了大多数用户的SQS使用费用,还包含更多特性和改进。但是,它也引入了与老API不兼容的更改。用老版本构建的所有库和工具都需要修改。关于版本之间的差异的详细信息可以在SQS网站上找到。

  Amazon Web Services和SQS入门

  要想开始使用SQS,首先需要注册一个Amazon Web Services账户。本系列的第2部分详细介绍了如何注册Amazon Web Services账户。

  创建账户之后,必须为账户启用Amazon SQS服务:

  ·注册Amazon Web Services账户。
  ·导航到SQS主页。
  ·单击页面右边的Sign Up For Amazon SQS。
  ·提供必需的信息并完成注册过程。

  与任何Amazon Web Services的所有通信都要通过SOAP接口或查询/REST接口。在本文中,使用一个第三方库的查询接口与SQS通信。

  需要获得自己的访问键,可以通过在Web Services Account information页面上选择View Access Key Identifiers获得访问键。现在设置了Amazon Web Services并为账户启用了SQS服务。

  与SQS交互

  这个示例使用第三方Python库boto,通过在Python shell中运行代码来熟悉如何使用SQS。

  安装boto并设置环境

  下载boto的最新版本,撰写本文时的最新版本是1.4c。把存档文件解压到您选择的目录中。进入此目录并运行setup.py把boto安装到本地Python环境中,见清单1。

  清单1. 安装boto
$ cd directory_where_you_unzipped_boto

$ python setup.py install
 
  设置一些环境变量,引用Amazon Web Services访问键。可以从Web Services Account information页面获得访问键。

  清单2. 设置环境变量
# Export variables with your AWS access keys
$ export AWS_ACCESS_KEY_ID=Your_AWS_Access_Key_ID
$ export AWS_SECRET_ACCESS_KEY=Your_AWS_Secret_Access_Key
 
  启动Python shell并导入boto库,从而确认所有设置都是正确的,见清单3。

  清单3. 检查设置
$ python
Python 2.4.5 (#1, Apr 12 2008, 02:18:19)
[GCC 4.0.1 (Apple Computer, Inc. build 5367)] on darwin
Type “help”, “copyright”, “credits” or “license” for more information.
>>> import boto
>>>
 
  用boto体验SQS

  SQSConnection类提供与SQS交互的主要接口。使用boto的中介是Python控制台。示例调用SQSConnection对象上的不同方法,然后查看SQS返回的响应,这有助于熟悉API和体验SQS概念。

  第一步是使用前面导出到环境中的Amazon Web Services访问键,创建一个连接到SQS的连接对象。boto库总是先检查是否设置了这些环境变量。如果设置了这些变量,boto在创建连接时自动地使用它们。

  清单4. 创建到SQS的连接
>>> import boto
>>> sqs_conn = boto.connect_sqs()
>>>
 
  然后,可以使用sqs_conn对象与SQS交互。可以通过指定队列名称和可选的可见性超时值创建队列。如果没有指定超时值,boto将用SQS提供的默认值(30秒)创建队列。

  清单5. 创建队列
>>> q1 = sqs_conn.create_queue(‘devworks-sqs-1’)
>>>
>>> q1.get_timeout()
30
>>> q2 = sqs_conn.create_queue(‘devworks-sqs-2’, 60)
>>>
>>> q2.get_timeout()
60
>>>
 
  获取所有队列的列表,这返回一个结果集对象,它实际上是一个Python列表,见清单6。可以循环遍历这个列表并访问每个队列的所有相关信息。

  清单6. 列出所有队列
>>> all_queues = sqs_conn.get_all_queues()
>>>
>>> len(all_queues)
2
>>>
>>> for q in all_queues:
…     print q.id
…     print q.count()
…     print q.get_timeout()
…     print q.url

/devworks-sqs-1
0
30
http://queue.amazonaws.com/devworks-sqs-1

/devworks-sqs-2
0
60
http://queue.amazonaws.com/devworks-sqs-2
   
  在删除队列之前,必须删除队列中的所有消息。可以使用boto中的clear()方法删除队列中的所有消息。

  清单7. 清空并删除队列
>>> q2.clear()
0
>>> sqs_conn.delete_queue(q2)
True
>>>
 
  可以向队列发送大小不超过8 KB的文本消息。使用boto Message类创建新消息,见清单8。

  清单8. 发送消息
>>> from boto.sqs.message import Message
>>>
>>> m1 = Message()
>>>
>>> m1.set_body(‘Hi there devworks!’)
>>>
>>> status = q1.write(m1)
>>>
>>> print status
True
>>>
 
  获取队列中的消息会返回一个结果集对象,它是一个包含消息对象的Python列表。每个消息对象有相关联的惟一ID和收件句柄。在从队列中读取消息之后,队列的其他所有消费者就看不到这个消息,直到可见性超时周期过期为止。过期之后,消息再次出现在队列中,让其他消费者有机会获取和处理它。但是,如果在可见性超时周期过期之前从队列中删除了消息,消息就永远消失了,不会再次出现在队列中。

  清单9. 获取消息
>>> msgs = q1.get_messages()
>>>
>>> len(msgs)
1
>>>
>>> for msg in msgs:
…     print “Message ID: “,msg.id
…     print “Message Handle: “,msg.receipt_handle
…     print “Queue ID: “, msg.queue.id
…     print “Message Body: “, msg.get_body()

Message ID:  9a930aaf-87de-48ad-894d-b22dd0b1cd1b

Message Handle:  Prl0vft3nRjgDDT33svtLnzyPQGWFpRusXdn2v3Lwq+TDtD3hk3aBKbSH1mGc4hzO/VZO
IC0RFyAd7MhbJKPGHn3x35CTz9dAQeNoKYAHiwERXc/xrYXBLGngyuJI+kGmbjvIKqA/wpfQpqzPk2bVA==

Queue ID:  /devworks-sqs-1

Message Body:  Hi there devworks!
>>>
 
  可以通过指定消息数量获取多个消息。boto中的默认设置是返回一个消息。我们在队列中添加另一个消息,然后获取所有消息,见清单10。请记住,新添加的消息出现在队列中可能要花费一分钟左右。

  清单10. 获取多个消息
>>> m2 = Message()
>>>
>>> m2.set_body(‘Still there?’)
>>>
>>> status = q1.write(m2)
>>>
>>> print status
True
>>>
>>> msgs = q1.get_messages(10)
>>>
>>> len(msgs)
2
>>>
>>> for msg in msgs:
…     print “Message ID: “,msg.id
…     print “Message Handle: “,msg.receipt_handle
…     print “Queue ID: “, msg.queue.id
…     print “Message Body: “, msg.get_body()
…     print “*”*80

Message ID:  9a930aaf-87de-48ad-894d-b22dd0b1cd1b

Message Handle:  Prl0vft3nRjgDDT33svtLnzyPQGWFpRusXdn2v3Lwq+TDtD3hk3aBKbSH1mGc4hzO/VZOIC0R
FyAd7MhbJKPGHn3x35CTz9dAQeNoKYAHiwERXc/xrYXBLGngyuJI+kGmbjvIKqA/wpfQpqzPk2bVA==

Queue ID:  /devworks-sqs-1

Message Body:  Hi there devworks!

Message ID:  ce1632b3-0a6e-4ee2-a5b0-b2e9821d150f

Message Handle:  Prl0vft3nRiRunVNVvjOQEc7Tm+uSBQpW4bZcpFMbzWTDtD3hk3aBKbSH1mGc4hzO/VZOIC0R
FxbhtlykUxvNbRQNWJqrMXrxj5m6GwhA7iX0Nu9mqjo+9/hnda8Ou0df+LQ3dOMfXSybzbhed128w==

Queue ID:  /devworks-sqs-1

Message Body:  Still there?
>>>
 
  可以通过调用delete_message()从队列中删除消息。请记住,在删除队列之前,必须删除队列中的所有消息。

  清单11. 删除消息
>>> msgs = q1.get_messages()
>>>
>>> len(msgs)
1
>>> print msgs[0].get_body()
Hi there devworks!
>>>
>>> q1.delete_message(msgs[0])
True
>>>
 
  结束语

  本文介绍了Amazon的SQS服务。学习了一些基本概念和boto(一个用于与SQS交互的开放源码Python库)提供的一些功能。强烈建议您通过Amazon SQS开发人员指南了解更多信息。

  这个“用Amazon Web Services进行云计算”系列的第5部分讨论如何用Amazon SimpleDB在云中处理数据集。

我们一直都在努力坚持原创.......请不要一声不吭,就悄悄拿走。

我原创,你原创,我们的内容世界才会更加精彩!

【所有原创内容版权均属TechTarget,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用。】

微信公众号

TechTarget微信公众号二维码

TechTarget

官方微博

TechTarget中国官方微博二维码

TechTarget中国

相关推荐

  • 云计算专家Mark Szynaka访谈录

    这些日子以来,云计算专家Mark Szynaka一直在努力为他的咨询集成公司CloudBroker开发和部署虚拟数据中心,这是一家使用Amazon Marketplace商品服务从事复杂应用程序快速部署业务的公司。

  • 检阅云计算工具

    虽然市场上有着数以百计的云计算解决方案供应商,但是作为用户的我们应当如何雾里看花找到真正满足我们需求的云计算产品与供应商?对云计算供应商进行分类对于更好地了解诸如应用程序迁移、自动化与监控等关键领域的领先厂商似乎并无裨益。

  • 云计算应用程序管理的任务清单

    把应用程序迁往云计算并不是最后的大功告成。有时候会发生一些迫使你不得不重新设计应用程序的突发事件,合规性需求可能会带来发展障碍,而如果你的云计算供应商不支持诸如组播的低层次网络服务,那么就可能带来带宽问题。

  • Google、IBM、Oracle意图分羹云计算大数据市场

    少数公共云计算服务供应商(如Google、IBM、微软以及Oracle)正从Amazon网络服务(AWS)中得到启示,并已涉足“大数据”分析领域和多方面的开源项目Hadoop/MapReduce。