专业支持:(0512) 63016160 / 销售热线:(0512)63016068
当前在线: 288 今日上线: 1384 今日新增: 3

连接到云,第2部分: 实现混合云模型--将 JMS 队列数据推向 Amazon SQS 队列

文章来源:  中国云计算 发布时间: 2010年02月26日   浏览: 1374   作者:中国云计算

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

混合模型

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

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

该架构的好处包括:

  • 该系统不需要队列写入程序(医疗应用程序)或队列读取程序(图片处理应用程序)同时在线。如果文件只是在两个应用程序之间通过 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 部分,即本系列的最后一部分,您将了解云计算中的治理和安全问题。您将看到各种云提供商使用的验证模型,并将讨论在隐私性、法规遵从性方面出现的问题和针对拒绝服务威胁提供的保护。


一键分享:

在线客服