Servicesクラウドみなさん、こんにちは!フリューでモバイルサイト開発を行っている鷲見といいます。現在、あるソーシャルプラットフォーム上のアプリケーションを構築するプロジェクトでの、クラウド環境の導入の進行状況をそのまま記事にしています。Servicesを利用することを決定し、データベースにはSimpleDBを利用するところまで決定しました。今回のテーマはアーキテクチャ設計です。AWSを利用したアプリケーションの全体的なアーキテクチャを検討していきたいと思います。今回構築するシステムに求められる要件とアーキテクチャ設計手法について、比較検討しながら最終的な構成を決定していきます。Japanのエバンジェリスト・玉川憲さんらがWebで行われたセミナーの資料があるので、私が紹介するまでもなく、そちらを参考にするのがよいでしょう。ベストプラクティスAWSを用いた耐障害性の高いアプリケーションの設計このWebセミナーを実は社内でヘッドフォンしてノートPCを凝視しながら受講していました。周りの視線が痛かったというのは多分気のせいです。上記Webセミナーを受講して、私が特に印象に残ったのは以下の2点です。トレードオフよくよく考えれば当たり前のことなのですが、クラウドで環境構築をしたからといって止まらないシステムになるわけではありません。『残念ながらAWSを含むクラウドは銀の弾丸ではありません。』とうぜんながらクラウドでも耐障害性の強い環境を構築するのにはお金がかかります。そのあたりの要件とお金のすり合わせの重要性というところはクラウドでも変わらないという点を再認識できたという点で印象に残りました。『全てが故障する前提で設計する。』なんかとても深い言葉です。いままでの耐故障性をあげるために故障を起きないようにしていたのに、故障はするから故障に備えて設計するようにというのはとても印象的でした。AWSでのアーキテクチャ設計はなんといってもここに尽きるんじゃないだろうかと思います。各コンポーネントを疎結合にしておく(サーバ台数が減っても動くように)故障が発生するような高負荷状態が発生した場合、負荷を分散できるようにする高負荷状態のモニタリングオートスケール各コンポーネントを疎結合にしておく(サーバ台数が増えても動くように)という対応がとれるのだと思います。どちらのアプローチをとるのであっても、各コンポーネントを疎結合にしておき、コンポーネントを構成する要素が減っても、増えても稼働することというのは、耐障害性の高いアプリケーションを構築すうる上で重要なところだと思います。今回のアプリケーションの要件としては、ソーシャルアプリケーションなので、サービスのダウンタイムが売上減に直結するので、出来る限りサービスを落としたくありません。要件としてはSPOFは作らないWeb/APサーバはスケールアウトし負荷分散できることWeb/APサーバは全Web/APサーバがダウンしない限りサービスを提供し続けられることなどが挙げられます。上記の要件と設計手法を考慮した結果、以下のようにアーキテクチャ設計を行いました。日本国内向けのサービスのため、Regionは東京リージョンとする。Web/APサーバは単一でも複数でも稼動可能な構成とし、サーバ数の増加で負荷分散できるようにする。AvailabilityZone(AZ)全体の障害に備えて、複数のAZにEC2のインスタンスを配置する。ELBを利用してロードバランシングする。障害に備えEBSのスナップショットをS3に保存する。Route53を利用する。データを自動的に複数AZにコピーし、負荷分散・スケーリングも自動で行うSimpleDBを利用する。この設計結果の構成を図にするとこのようになります。※この図はCacooを使って作成しています。実際のアーキテクチャ設計を行いました。大事な点は『全てが故障する前提で設計する。SimpleDBの詳細について紹介していきたいとおもいます。frameworkこんにちは。モバイル事業部の九岡です。frameworkのWebSocketサポートをご紹介します。WebSocketWebSocketとは、WebブラウザとWebサーバ間でリアルタイムに双方向通信を行うための通信方法です。ブラウザ-サーバ間のリアルタイムな双方向通信は、これまでもFlashやAppletでソケット通信を使えばできましたが、JavaScriptから直接アクセスできないWebの範囲外であるが故にWebフレームワークが対応しておらず、サーバ側の実装も面倒くさいという難点がありました。そこでWebSocketです。双方向通信の仕様がWebSocketとしてブラウザに取り込まれる事で、実装の敷居が下がりました。frameworkですが、バージョン1.2からWebSocketをサポートしています。frameworkはMVCアーキテクチャに基づいたWebフレームワークですが、C層にWebSocketControllerというものが追加されました。これを実装するだけで、既存のWebアプリケーションをさくさくっとWebSocketに対応させることができます。これまで利用してきたHTTPベースのWebアプリケーションを同居させることができたり、同じModelをWebSocketControllerからも利用することができるなど、相互運用性が高いところもポイントです。イメージが湧くように、WebSocketを利用してWebベースのechoサーバを実装してみます。仕様は以下のようにします。テストページから、サーバにメッセージを送信できる送信されたメッセージが、サーバからそのまま返送される返送されたメッセージがページ内に表示されるViewまず、Viewを作成します。/></div></div>id=whatのinput要素にメッセージを入力して、id=sayのボタンをクリックするとメッセージをWebSocket経由でサーバに送信します。id=messagesのdiv要素に、全メッセージが表示されます。}となっている部分は、WebSocketの接続先の指定です。WebSocket("ws://localhost:9000/echo");のように置換えられます。JavaScriptws.send("hi");1ws.send("hi");は、sendの引数に渡した文字列をWebSocket経由で送信します。}は、WebSocket経由でサーバからメッセージを受け取る度に実行されます。JavaScriptevent.data1event.dataがサーバから送信されたメッセージです。Test仕様1〜3のテキトウなテストを書きます。TestをPlayのSeleniumテストケースを使います。先ほど作成したViewを見ながら、test/Application.test.htmlに以下の内容を追記してください。error')input(id=what,'Hello!')click(id=say)pause(1000)assertTextPresent('Hello!')#{/selenium}このテストケースでは、/echoを開いた時に、エラーが発生していないことinput要素にメッセージを入力して送信ボタンをクリックすると、しばらく後にメッセージがページ内に表示されることを検証しています。2つめのテストでは、メッセージがWebSocketを経由してサーバに送信され、サーバがそれを送り返してページに表示される、ということを期待しています。作成したテストケースは、XHTMLhttp://localhost:9000/@tests1http://localhost:9000/@testsから実行できます。WebSocketControllerテストページの表示と、WebSocketでのメッセージのやり取りのためのコントローラを実装します。クライアントから送られるメッセージを、継続を使って非同期で待ちます。メッセージがテキストであればfor内が実行されます。パターンマッチにfor文を使うのは珍しいですね。クライアントにメッセージを返送します。このように、HTTP用のControllerから利用していたModelをWebSocketControllerからも普通に利用することができます。クライアントから送られるメッセージを、継続を使って非同期で待ちます。メッセージがテキストであればfor内が実行されます。パターンマッチにfor文を使うのは珍しいですね。クライアントにメッセージを返送します。このように、HTTP用のControllerから利用していたModelをWebSocketControllerからも普通に利用することができます。LoggedMessage(message).save();}}}}}Echo.demoがテストページを表示するメソッドです。render()により描画されるViewは、先ほど作成したapp/views/Echo/demo.htmlです。Echo.WebSocketEcho.listenがWebSocket経由のメッセージのやり取りを行うメソッドです。1コネクションあたり1回呼び出され、接続終了までループでメッセージを待ち続けます。HTTP用のコントローラとは全く実装方法が違いますね。WebSocket用コントローラへのパスを登録します。後者はws://localhost:9000/echoのようなURLへのWebSocket接続をEcho.WebSocketEcho.listenへルーティングします。実行例では早速実行してみましょう。testブラウザで以下のURLにアクセスすると、デモページが表示されます。XHTMLhttp://localhost:9876/echo1http://localhost:9876/echoポート番号はconf/application.confで設定したものです。]1テストページこのように、送信したメッセージがWebSocket経由でechoされてページに表示されます。XHTMLhttp://localhost:9876/@tests1http://localhost:9876/@testsから、作成したSeleniumテストケースを実行することができます。]2Seleniumテストの実行例このように、ブラウザのWebSocket実装を通したテストもブラウザ上で実行できます。frameworkのWebSocketサポートについて説明しました。WebSocketはWebブラウザとWebサーバの双方向通信のための規格です。frameworkでは、WebSocketControllerを実装するだけで既存のWebアプリに双方向通信機能を後づけできます。