连接到云,第 2 部分: 实现混合云模型

将 JMS 队列数据推向 Amazon SQS 队列

“连接到云” 系列教程共三个部分,这是第 2 部分。为了确定创建混合云应用程序的最佳解决方案,连接到云,第 1 部分:在应用程序中使用云 探讨了一些主要的云平台供应商的产品。本文是该系列的第 2 部分,您将实现混合云应用程序,该应用程序将组合本地应用程序组件和云计算。应用程序利用本地的 JMS 队列以及云中的 SQS 队列,将这两者组合到一个混合应用程序中。

Mark O'Neill, CTO, Vordel

Mark O'Neill 是 Vordel 的 CTO,这是一家 XML 网络公司。他还是 “Web Services Security” 一书的作者,另外也参与了 “Hardening Network Security” 一书的写作,两本书均由 McGraw-Hill/Osborne Media 出版。Mark 负责监督 Vordel 的产品开发路线图,并建议 Global 2000 公司和各国政府战略性地采用 XML、Web 服务和 SOA 技术。他具有 Trinity College Dublin 的数学与心理学的学位,并从牛津大学获得了神经网络编程的硕士学位。Mark 现生活在马萨诸塞州的波士顿。



2009 年 6 月 08 日

混合模型

在本文中,我将集中介绍如何向一个云提供商 Amazon 创建混合云应用程序。示例应用程序名为 HybridCloud,它将从 JMS 队列中取出数据并将数据传送到寄存在 Amazon 云中的 Amazon SQS 队列。进入 Amazon SQS 队列之后,可以使用有权访问该队列的应用程序拉取数据。

具体情况请看示例。假设一家医疗组织需要通过图片处理应用程序处理 X 射线图。该组织安全地将 X 射线图写入 Amazon SQS 队列,射线图临时存储在该位置。即使 X 射线图的文件非常大,这对于云计算提供商而言也不是什么问题。同时,图片处理应用程序占用队列,在 X 射线图进入后进行读取。图片处理应用程序需要大量处理能力,因此它最好部署在虚拟环境中(私有云),在这个环境中可以快速添加硬件功能。经过图片处理应用程序的处理之后,X 射线图将返回到另一个队列,可通过医疗应用程序接收。尽管 X 射线图是该示例的主要问题,实际上这适用于任何数据。很明显,X 射线图涉及到较高的隐私和安全问题。本文的第 3 部分将探讨云的安全性和治理。

云计算空间

您是否希望随时获取最新的云计算消息?是否想得到云计算相关的技术知识?developerWorks 云计算空间就是这样一个云计算信息资源的门户,在这里您可以了解来自 IBM 和业界其他媒体的最新信息,并且得到如何在云环境中使用 IBM 软件的入门知识。

IBM 在 Amazon EC2 云计算环境中提供了 DB2、Informix、Lotus、WebSphere 等方面的 AMI 镜像资源。您只需按使用量支付少量费用,就可以使用到云上的数据、门户、Web 内容管理、情景应用等服务。欢迎您随时访问 云计算空间,获取更多信息。

该架构的好处包括:

  • 该系统不需要队列写入程序(医疗应用程序)或队列读取程序(图片处理应用程序)同时在线。如果文件只是在两个应用程序之间通过 FTP 传输,系统会在任何一方脱机时崩溃。通过使用 Amazon SQS 队列,系统变得更加灵活。
  • 可以向解决方案的任何一方添加功能,不会影响系统的工作。例如,您可以增加图片处理应用程序端的计算能力,这可以加倍图片处理速度。这种变化对于医疗应用程序是透明的,它会继续将 X 射线图写入 Amazon SQS 队列,不会造成影响。
  • 该混合模型非常适合于考虑使用云计算的架构师。全有或全无解决方案要么将所有内容都放到云计算平台,要么完全避开云计算,更好的选择是选择云计算中有用的功能并战略性地使用该功能。在本地应用程序端,虚拟化(私有云)使得动态添加功能变得更加容易,这对于处理器密集型应用程序(如图片处理)而言是很重要的。在云端,Amazon SQS 服务提供应用程序之间的队列服务,即使它们没有连接网络。

向 Amazon SQS 云服务确认身份

常用缩略词

  • FTP:文件传输协议(File Transfer Protocol)
  • API:应用程序编程接口(application programming interface)
  • HTTP:超文本传输协议(Hypertext Transfer Protocol)
  • JMS:Java™ 消息服务(Java™ Message Service)
  • JNDI:Java 命名和目录接口(Java Naming and Directory Interface)
  • REST:具象状态传输(Representational State Transfer)
  • SQS:简单队列服务(Simple Queue Service)
  • URL:统一资源定位符(Uniform Resource Locator)
  • XML:可扩展标记语言(Extensible Markup Language)

您的 HybridCloud Java 应用程序使用 Amazon SQS(下载 应用程序源代码)。HybridCloud 应用程序与 Amazon SQS 云之间的连接使用经过验证的 Web 服务。执行这种验证出于两个原因:首先,Amazon 要收取 Amazon SQS 的使用费,因此必须跟踪每个人的使用;其次,对每个队列的访问必须受到控制。在我们的 HybridCloud 应用程序中,很明显第三方不适合访问包含私有 X 射线图片的 Amazon SQS 队列。

使用 Amazon SQS 队列的第一步是成为 Amazon Web Services (AWS) 的用户,这需要登录 Amazon.com。登录 Amazon.com 没有什么不同之处 — 任何在 Amazon.com 站点买过书的用户都已经有了一个 Amazon.com 帐户。但是,Amazon.com 登录还只是第一步。AWS 需要使用 “访问密匙 ID” 以及相关的密钥。

Amazon Web Services 模型中的 Secret Access Key 可以视为在 Amazon.com 和连接到 Amazon Web 服务的开发人员之间的一个共享密匙。相反,Access Key ID 并不私密,因为它用于识别而不是验证。在第 3 部分中,我们将讨论这两个密匙的更多细节,以及其他云计算提供商使用的其他验证模型。

开发人员登录 Amazon Web Services 并获取了他们的 Access Key ID 以及 Secret Access Key 之后,他们就可以订阅特定的服务。在本例中,我们将订阅 Amazon.com SQS 服务。开发人员必须使用 Amazon Web Services 注册信用卡才能使用 SQS 之类的服务。信用卡详情必须存储在 Amazon 中,在有未付帐单时无法进入 — 它是现收现付模型。如果尝试未注册就访问 SQS 服务,您将看到 “The AWS Access Key Id needs a subscription for the service” 异常。


设计混合应用程序

正如开头所述,混合应用程序在本地处理数据并使用 Amazon SQS 云服务。因此,它有一个本地组件和一个云组件。在该应用程序设计中,通过本地从 JMS 队列接收数据(也许是从主机应用程序接收),然后使用 HTTP GET 和 POST 将数据发送到 Amazon SQS 队列。您将使用 Java 作为应用程序的语言。

应用程序有三个主要部分:

  1. 创建 Amazon SQS 队列。
  2. 读取本地数据(从 JMS 队列)并将其放入 Amazon SQS 队列。
  3. 从 Amazon SQS 队列检索响应数据。

使用 Amazon SQS 应用程序代码片段中,注意处理本地 JMS 队列连接和 Amazon SQS 队列连接之间的相似之处。


使用 Amazon SQS

在 HybridCloud Java 应用程序中,首先放入 Amazon SQS 类(见清单 1)。

清单 1. 导入 Amazon SQS 类
Import com.amazonaws.queue.*;

HybridCloud 应用程序使用 Amazon SQS 将数据写入队列,然后从队列读回数据。与 Amazon SQS 的连接建立在通过验证的 Web 服务连接之上,客户端使用 Amazon Access Key ID 识别,使用 Amazon Secret Key ID 进行验证。要通过 Java 代码使用 Amazon SQS,首先将 Amazon Access Key ID 和 Amazon Secret Key ID 放入代码中(见清单 2)。

清单 2. 设置 Amazon 键
String accessKeyId = "12345678901234567890";
String secretAccessKey = "abcdefghijklmnopqrstuvwxyz";

接下来,实例化 Amazon SQS 的 HTTP Client 实现,传入 Access Key ID 和 Secret Access key 作为变量(见清单 3)。

清单 3. 实例化 Amazon SQS http 客户端
AmazonSQS service = new AmazonSQSClient(accessKeyId, secretAccessKey);

现在,您已经实例化了 Amazon SQS 客户端对象,但是还没有通过 Internet 连接到 Amazon SQS 服务。这是下一步要做的工作,您将在 Amazon SQS 云服务上创建队列。


创建 Amazon SQS 队列

该应用程序使用队列存储 X 射线图文件。在使用 Amazon SQS 队列之前,必须先创建一个队列。该队列必须有一个名称,在本例中为 “imageQueue”。这是 HybridCloud 应用程序放置 X 射线图文件的地方(见清单 4)。

清单 4. 创建 Amazon 队列
CreateQueueRequest request = new CreateQueueRequest();
request.setQueueName("imageQueue");

现在运行名为 createQueue 的 Amazon SQS 服务对象方法,该方法创建对 Amazon Web Services 的 HTTP GET (REST-style) 请求以创建队列(见清单 5)。

清单 5. 创建 Amazon 队列
CreateQueueResponse response = service.createQueue(request);

这将在 Amazon SQS 上创建一个 REST 风格的 Web 服务。当您运行代码创建 Amazon SQS 队列时,检测发送给 Amazon SQS 的 REST 风格的 URL 会很有趣。在此 URL 中,您可以清楚地看到 Access Key ID、签名(使用 Secret Key ID)和实际的 SQS 队列,创建的队列名为 imageQueue。当然,实际的 Secret Key ID 是不会发送的。消息的签名组件(见清单 6)提供拥有 Secret Key ID 的证明。只有密钥持有者才能创建签名组件。

清单 6. 将 REST 风格的 Web 服务请求发送到 Amazon Web 服务
queue.amazonaws.com?Action=CreateQueue&SignatureMethod=HmacSHA256&AWSAccessKeyId
=12345678901234567890&QueueName=imageQueue&SignatureVersion=2&Version
=2008-01-01&Signature=U859J2Hoi5qBqlQx1R18dKPgSgrgjlOiJIDD8ug9FPI%3D&Timestamp
=2009-04-01T03%3A25%3A13.575Z

创建签名不仅要使用 QueueName,还使用时间戳。这确保了对 Amazon SQS 的请求无法被攻击者捕获并回放以模拟有效用户。如果攻击者重新向 Amazon SQS 服务发送请求,则重复的签名表示该请求属于捕获重放攻击,Amazon Web 服务将会阻塞它。

现在,您已经创建了 imageQueue 队列,您可以将图像数据加载到其中。现在可以从本地 JMS 队列中获取该数据。本地队列本身可以来自虚拟环境(本地云)。


从本地 JMS 队列检索数据

现在已经创建了 Amazon SQS 队列,接下来将注意力转移到该混合应用程序的本地端。在将数据提供给 Amazon SQS 队列之前,您必须从本地队列中读取数据。比较本地队列使用的步骤与连接 Amazon 的 SQS 队列所需的步骤将会很有用。

需要导入 Java 库,首先是所有的 JMS jar,然后是 JNDI jar。这些文件允许 Java 应用程序使用 JMS(见清单 7)。

清单 7. 导入 JMS 类
import javax.jms.ConnectionFactory;
import javax.jms.Connection;
import javax.jms.Session;
import javax.jms.MessageProducer;
import javax.jms.MessageConsumer;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.Message;
import javax.jms.TextMessage;
//Required for JNDI.
import javax.naming.*;

您使用 JNDI 设置 JMS 连接的上下文。例如,如果从文件系统读取数据,您可以使用清单 8 中的代码。

清单 8. 从本地队列读取文件
ConnectionFactory myConnFactory;
Queue myQueue;
Hashtable env;
Context ctx = null; 
env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.fscontext.RefFSContextFactory");
env.put(Context.PROVIDER_URL, "file:///C:/Images");	
ctx = new InitialContext(env);

现在创建队列和连接工厂(见清单 9):

清单 9. 创建队列和连接工厂
String MYCONNECTIONFACTORY = "MyConnectionFactory";
String MYQUEUE = "MyQueue";
myConnFactory = (javax.jms.ConnectionFactory) ctx.lookup(MYCONNECTIONFACTORY);
myQueue = (javax.jms.Queue)ctx.lookup(MYQUEUE);

接下来,创建一个连接,然后创建连接中的会话(见清单 10)。

清单 10. 创建一个本地 JMS 队列的连接
Connection myConn = myConnFactory.createConnection();
Session mySess = myConn.createSession(false, Session.AUTO_ACKNOWLEDGE);

要从队列中读取消息(在本例中最终涉及到从文件系统中读取数据,因为我们使用文件系统的 JNDI 标识符),使用清单 11 中的代码。

清单 11. 从本地 JMS 队列中读取
MessageConsumer myMsgConsumer = mySess.createConsumer(myQueue);
myConn.start();
Message msg = myMsgConsumer.receive();

现在检查从本地检索的消息中的内容(见清单 12)。

清单 12. 检查本地检索消息的内容
if (msg instanceof TextMessage) {
                TextMessage txtMsg = (TextMessage) msg;
                String inputText = txtMsg.getText());
}

最后,关闭 JMS 队列的连接(见清单 13)。

清单 13. 关闭本地 JMS 队列的连接
mySess.close();
myConn.close();

现在,您已经将希望写入 Amazon SQS 队列的数据放到了名为 inputText 的字符串中。这是接下来要写入 Amazon SQS 队列的内容。


写入到 Amazon SQS 队列

传入到 Amazon SQS 队列的数据以字符串形式发送。尽管数据是图片,但它仍然以字符串形式发送到 Amazon SQS。可以看到,它在 SendMessageRequest 对象中设置,以将消息发送到 Amazon SQS 队列(见清单 14)。

清单 14. 向 Amazon SQS 队列发送消息
SendMessageRequest sendRequest = new SendMessageRequest();
sendRequest.setMessageBody(inputText);

您必须设置相应的队列名称,这与您之前创建的队列名称相同(见清单 15)。

清单 15. 设置 Amazon SQS 上的队列名称
sendRequest.setQueueName("imageQueue");

现在通过使用 Amazon SQS 对象的 sendMessage 方法将消息发送到 Amazon SQS 队列(见清单 16)。

清单 16. 将我们的数据发送到 Amazon SQS 队列
SendMessageResponse response = service.sendMessage(sendRequest);

读取 Amazon SQS 响应

接下来从 Amazon SQS 队列读取响应。首先创建 ReceiveMessageRequest 对象(见清单 17)。

清单 17. 创建 ReceiveMessageObject 从 Amazon SQS 队列中检索数据
receiveRequest = new ReceiveMessageRequest();

接下来,设置队列名称(见清单 18)。

清单 18. 设置队列名称
receiveRequest.setQueueName("imageQueue");

现在使用 receiveMessage 方法尝试从 Amazon SQS 队列中检索消息(见清单 19)。

清单 19. 从 Amazon SQS 队列中检索响应
ReceiveMessageResponse response = service.receiveMessage(receiveRequest);

要检测结果,包括从云中检索到的消息 ID 和消息正文(见清单 20),请将其传递到标准输出。

清单 20. 检查 Amazon SQS 队列中的响应
if (response.isSetReceiveMessageResult()) {
ReceiveMessageResult  receiveMessageResult = response.getReceiveMessageResult();
java.util.List<Message> messageList = receiveMessageResult.getMessage();
for (Message message : messageList) {
if (message.isSetMessageId()) {
                        System.out.print("            MessageId");
                        System.out.print("                " + message.getMessageId());
                        System.out.println();
                    }
                    if (message.isSetBody()) {
                        System.out.print("            Body");
                        System.out.println();
                        System.out.print("                " + message.getBody());
                        System.out.println();
                    }
}

使用 XML 网关连接本地应用程序和云

在本文中,使用 Java 代码连接本地应用程序和云计算环境。这是开发人员的理想解决方案,但作为应用程序的一部分,到 Amazon 云计算服务的连接不在网络运营团队的控制之下,网络运营团队监控使用、通信和可用性。此外,任何到云计算连接的更改都涉及到代码更改。尽管这超出了本文的范围,但可以使用网络基础结构在本地 JMS 队列和 Amazon SQS 云服务之间实现相同的连接,从而将连接置于网络运营团队的控制之下。

要将一个本地应用程序组件(比如 JMS 队列)连接到云,需要一个包含云计算连接器的 XML 网关(见参考资料中此类网关的示例)。将 JMS 队列连接到 Amazon SQS 队列的任务涉及到拖放连接筛选器,从而将数据从 JMS 队列中拉出然后传递到 Amazon 云服务。

这与我们熟悉的有线电视机顶盒很类似。电视机顶盒连接本地基础设施(电视机)和云(有线电视操作员)。XML 网关提供本地有线电视机顶盒的功能。除了提供到云服务的连接之外,它还提供对该连接的监控和安全性。


结束语

您了解了 Java 应用程序如何将本地 JMS 队列和 Amazon SQS 云连接起来。您的 HybridCloud 应用程序使用本地资源(JMS 队列)和基于云的资源(Amazon SQS)执行示例图片共享任务。使用比较类似的方法连接本地队列和 Amazon SQS 队列,但是在网络级别上,到 Amazon SQS 的连接通过 HTTP GET 和 PUT(包含 URL 中传递的参数)发送。

在第 3 部分,即本系列的最后一部分,您将了解云计算中的治理和安全问题。您将看到各种云提供商使用的验证模型,并将讨论在隐私性、法规遵从性方面出现的问题和针对拒绝服务威胁提供的保护。


下载

描述名字大小
混合云示例应用程序HybridCloud.zip3KB

参考资料

学习

获得产品和技术

讨论

条评论

developerWorks: 登录

标有星(*)号的字段是必填字段。


需要一个 IBM ID?
忘记 IBM ID?


忘记密码?
更改您的密码

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件

 


在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。

所有提交的信息确保安全。

选择您的昵称



当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

标有星(*)号的字段是必填字段。

(昵称长度在 3 至 31 个字符之间)

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

 


所有提交的信息确保安全。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=XML, SOA and web services
ArticleID=395272
ArticleTitle=连接到云,第 2 部分: 实现混合云模型
publish-date=06082009