レベル: 中級 Mark O'Neill, CTO, Vordel
2009年 4月 28日 この記事はクラウドへの接続に関する 3 回からなるシリーズの第 2 回です。「第 1 回」では、ハイブリッド・クラウド・アプリケーションを作成する上での最善のソリューションを決定するために、クラウド・プラットフォームの主要なベンダーが提供するいくつかのサービスについて調べました。この記事ではシリーズの第 2 回として、ローカル・アプリケーションのコンポーネントとクラウド・コンピューティングとを組み合わせたハイブリッド・クラウド・アプリケーションを実装します。このアプリケーションはローカルの JMS キューとクラウドの SQS キューを利用し、この 2 つを組み合わせて 1 つのハイブリッド・アプリケーションにします。
ハイブリッド・モデル
この記事では、ハイブリッド・クラウド・アプリケーションを作成するためのクラウド・プロバイダーを Amazon のみに絞りました。HybridCloud というサンプル・アプリケーションは JMS キューからデータを取得し、そのデータを Amazon のクラウドでホストされる Amazon の SQS キューに渡します。Amazon の SQS キューに入れられたデータは、そのキューへのアクセス権を持つ別のアプリケーションから取得することができます。
これを実際の状況にあてはめた 1 つの例を見てみましょう。ある医療機関が、画像処理アプリケーションを使って X 線画像を処理する必要があるとします。この医療機関は Amazon の SQS キューに X 線画像をセキュアに書き込み、画像は一時的に SQS キューに保存されます。各 X 線画像のファイル・サイズが非常に大きいとしても、それはクラウド・コンピューティング・プロバイダーにとっては問題になりません。一方で、画像処理アプリケーションは SQS キューにアクセスし、そこに保存されている X 線画像を読み取ります。この画像処理アプリケーションは大きな処理能力を必要とするため、ハードウェア容量を素早く容易に追加できる仮想環境 (プライベート・クラウド) にデプロイするのが最適です。画像処理アプリケーションが X 線画像を処理すると、それらの X 線画像は別のキューに置かれ、医療アプリケーションはそれらを受けとります。この例では X 線画像のデータを取り上げますが、どんなデータを使用することもできます。当然のことですが、X 線画像を扱う際にはプライバシーやセキュリティーに関する重要な問題が伴います。このシリーズの第 3 回ではクラウドのセキュリティーとガバナンスについて検証する予定です。
 |
頻繁に使用する頭字語
- FTP: File Transfer Protocol
- API: application programming interface
- HTTP: Hypertext Transfer Protocol
- JMS: Java™ Message Service
- JNDI: Java Naming and Directory Interface
- REST: Representational State Transfer
- SQS: Simple Queue Service
- URL: Uniform Resource Locator
- XML: Extensible Markup Language
|
|
このアーキテクチャーを利用するメリットは以下のとおりです。
- このシステムでは、キューの書き込み側 (医療アプリケーション) とキューの読み取り側 (画像処理アプリケーション) が同時にオンラインである必要がありませんが、2 つのアプリケーション間で FTP プロトコルを使って直接ファイルが交換される場合には、いずれか一方がオフラインになるとシステムが動作しなくなります。Amazon SQS キューを使うことで、システムの耐障害性が向上します。
- このソリューションのどちらの側にも容量を追加することができ、それによってシステム全体の動作に悪い影響を与えることがありません。例えば、画像処理アプリケーション側のコンピューティング容量を増加すると、画像の処理速度を 2 倍にできるかもしれません。そのように変更しても医療アプリケーションは影響を受けず、医療アプリケーションは Amazon SQS キューへの X 線画像ファイルの書き込みを続けることができます。
- このハイブリッド・モデルは、クラウド・コンピューティングの使い方を検討しているアーキテクトが広く推奨している方法です。すべてをクラウド・コンピューティング・プラットフォームに配置する、あるいはクラウド・コンピューティングを完全に避ける、というオール・オア・ナッシングのソリューションではなく、クラウド・コンピューティングを利用するのが適した部分にはクラウド・コンピューティングを利用するといった、戦略的な使い方をするのが賢明です。ローカル・アプリケーション側では、仮想化 (プライベート・クラウド) によって容量の追加が比較的に容易になりますが、これは画像処理などプロセッサー負荷が重いアプリケーションにとって重要です。一方クラウド側では、Amazon SQS サービスが (アプリケーションがネットワークに接続されていない場合にも) 2 つのアプリケーションの間にキューイング・サービスを提供します。
Amazon SQS クラウド・サービスでの ID
この HybridCloud という Java アプリケーションは Amazon SQS を使います (「ダウンロード」セクションからこのアプリケーションのソース・コードをダウンロードすることができます)。HybridCloud アプリケーションから Amazon SQS クラウドへの接続には、認証 Web サービスを使います。この認証が必要とされる大きな理由としては、次の 2 つがあります。第 1 に、Amazon は Amazon SQS を使用することに対して課金を行います。そのため Amazon は各ユーザーの使用状況を追跡する必要があります。第 2 に、各キューへのアクセスを制御する必要があります。HybridCloud アプリケーションの場合、プライベートな X 線画像を含む Amazon SQS キューに第三者がアクセスすることが適切でないことは明らかです。
Amazon SQS キューを使用するための第 1 のステップは、Amazon Web サービス (AWS) のユーザーになることです。そのためには Amazon.com にログインする必要があります。Amazon.com にログインするための ID を持っていることは特別なことではありません。Amazon.com のサイトで本を注文したことがある人ならば、誰でも Amazon.com へのログイン用 ID を持っています。しかし Amazon.com へのログイン用 ID は最初のステップにすぎません。AWS では、「アクセス・キー ID」と、その ID に関連する秘密鍵を使う必要があるのです。
AWS モデルでの「シークレット・アクセス・キー」は、Amazon.com と AWS に接続する開発者との間で共有される秘密鍵と考えることができます。それとは対照的に、アクセス・キー ID は識別のために使われ、認証に使われるわけではないため、秘密ではありません。第 3 回では、この 2 つのキーについて詳細に調べ、また他のクラウド・コンピューティング・プロバイダーで使用されている別の認証モデルについても調べます。
AWS にサインアップし、アクセス・キー ID とシークレット・アクセス・キーを取得すると、特定のサービスに登録できるようになります。この記事の場合には Amazon.com の SQS サービスに登録します。SQS などのサービスを利用するためには、クレジット・カードの情報を AWS に登録する必要があります。請求が来たときにカードの詳細を入力すればよいというわけではなく、クレジット・カードの詳細情報を Amazon に提供しておかなければなりません。AWS は使用量に応じて料金が引き落とされるモデルなのです。事前に登録せずに SQS サービスにアクセスしようとすると、「The AWS Access Key Id needs a subscription for the service (AWS のアクセス・キー ID でサービスに登録する必要があります)」という例外が発生します。
ハイブリッド・アプリケーションを設計する
最初に説明したとおり、このハイブリッド・アプリケーションはローカルでデータを処理してから Amazon SQS クラウド・サービスを利用します。従って、このアプリケーションにはローカルのコンポーネントとクラウドのコンポーネントがあります。このアプリケーションの設計では、データを (例えばメインフレーム・アプリケーションの) JMS キューからローカルで取得し、HTTP の GET と POST を使って Amazon SQS キューへ送信します。このアプリケーションでは言語として Java を使用します。
このアプリケーションには以下の 3 つの部分があります。
- Amazon SQS キューを作成する部分
- ローカル・データを (JMS キューから) 読み取り、Amazon SQS キューに入れる部分
- 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 アクセス・キー ID を使って識別され、Amazon シークレット・アクセス・キーを使って認証されます。Java コードから Amazon SQS を使うためには、まず Amazon Access Key ID と Amazon シークレット・アクセス・キーをコードに入力します (リスト 2)。
リスト 2. Amazon のキーを設定する
String accessKeyId = "12345678901234567890";
String secretAccessKey = "abcdefghijklmnopqrstuvwxyz";
|
次に、Amazon SQS の HTTP クライアント実装をインスタンス化し、アクセス・キー ID とシークレット・アクセス・キーを変数として渡します (リスト 3)。
リスト 3. Amazon SQS の HTTP クライアントをインスタンス化する
AmazonSQS service = new AmazonSQSClient(accessKeyId, secretAccessKey);
|
この時点で Amazon SQS のクライアント・オブジェクトをインスタンス化したことになりますが、まだインターネットを介しての Amazon SQS サービスへの接続は行われていません。それは次のステップです。次のステップでは Amazon SQS クラウド・サービス上にキューを作成します。
Amazon SQS キューを作成する
このアプリケーションはキューを使って X 線画像ファイルを保存します。Amazon SQS キューを使用する前に、このキューを作成する必要があります。このキューには名前を付ける必要があり、ここでは imageQueue という名前にします。HybridCloud アプリケーションは、このキューに X 線画像ファイルを入れます (リスト 4)。
リスト 4. Amazon のキューを作成する
CreateQueueRequest request = new CreateQueueRequest();
request.setQueueName("imageQueue");
|
ここで Amazon SQS サービス・オブジェクトの createQueue というメソッドを実行すると、キューを作成するための、AWS への (REST スタイルの) HTTP GET リクエストが作成されます (リスト 5)。
リスト 5. Amazon のキューを作成する
CreateQueueResponse response = service.createQueue(request);
|
これによって、Amazon SQS 上の Web サービスへの REST スタイルの呼び出しが作成されます。このコードを実行して Amazon SQS キューを作成する際、Amazon SQS に送信される REST スタイルの URL を調べてみると、興味深いことがわかります。この URL の中には、平文のアクセス・キー ID、(シークレット・アクセス・キーを利用した) 署名、そして作成された imageQueue という実際の SQS キューの情報が含まれています。もちろん、実際のシークレット・アクセス・キーは送信されません。メッセージに署名の部分 (リスト 6) があることで、シークレット・アクセス・キーを所持していることが証明されます。キーを所持している者のみが署名を作成できるからです。
リスト 6. AWS に送信される REST スタイルの 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 サービスにリクエストを送信した場合、同じ署名が送信されることになり、それによって、そのリクエストが「キャプチャーして再現した攻撃」であることがわかります。すると AWS はそのリクエストをブロックします。
この時点で、画像データのロード先となる 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.*;
|
JMS に接続するためのコンテキストを JNDI を使って設定します。例えばファイルシステムからデータを読み取る場合にはリスト 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 に送信されます。この設定の様子は、Amazon SQS キューにメッセージを送信するための下記の SendMessageRequest オブジェクトを見るとわかります (リスト 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. Amazon SQS キューからデータを取得するための ReceiveMessageObject オブジェクトを作成する
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 クラウド・コンピューティング・サービスへの接続をアプリケーションの一部として制御することはできません。また、クラウド・コンピューティングへの接続に関して少しでも変更があると、コードを変更しなければなりません。この記事では説明しませんが、ネットワークのインフラを利用すれば、Java コードを使った場合と同様の接続をローカルの 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 回では、最終回として、クラウド・コンピューティングに伴うガバナンスとセキュリティーの問題を検証します。さまざまなクラウド・プロバイダーに使用されている認証モデルを調べ、プライバシー、法規制の遵守、DoS (サービス拒否) 攻撃からの保護などに関する課題を検証します。
ダウンロード | 内容 | ファイル名 | サイズ | ダウンロード形式 |
|---|
| Hybrid Cloud Sample App | HybridCloud.zip | 3KB | HTTP |
|---|
参考文献 学ぶために
製品や技術を入手するために
議論するために
著者について  | |  | Mark O'Neill は XML ネットワーキング企業である Vordel の最高技術責任者です。彼は『Web Services Security』の著者でもあり、『Hardening Network Security』の共著者でもあります (どちらもMcGraw-Hill/Osborne Media から出版されています)。彼は Vordel の製品開発ロードマップの責任者であり、フォーブス誌の Global 2000 に選定された全世界の企業や政府機関に対して、XML、Web サービス、SOA 技術を戦術的かつ戦略的に採用するための助言を行っています。彼は Trinity College Dublin で数学と心理学の学位を取得しており、またオックスフォード大学でのニューラル・ネットワーク・プログラミングの卒業資格を持っています。彼はマサチューセッツ州ボストンに住んでいます。 |
記事の評価
|