Appknoxアーキテクチャ – AWSからGoogle Cloudへの切り替え
この記事はAppknox社のフルスタック&DevOpsエンジニアであるdhilipsiva氏による寄稿です。
Appknox はモバイルアプリケーションのセキュリティホールの検知に役立っています。ストアのリンクを送信するだけで、アプリの安全性を確保できます。リンクを受け取ると、弊社は対象アプリをアップロードし、セキュリティ脆弱性をスキャンして結果を報告します。
(※訳注:Appknoxとは..モバイルアプリを定期的に自動でスキャン・分析し、脆弱性が発見された場合に警告を出してくれる全自動のセキュリティ監視ツール『appknox』を提供しているインドで注目されているスタートアップの一つです。)
弊社のスタックの特徴を以下に示します。
- モジュール化設計。フロントエンドとバックエンドを切り離すため、モジュール化を進めました。このアーキテクチャの多くの利点についてはこの記事の後半でお話しします。
- AWSからGoogle Cloudへの移行。コードをベンダー非依存にしたので、AWSからGoogle Cloudへの切り替えが簡単に実行できました。
主要言語
- バックエンドにはPythonおよびShell
- フロントエンドにはCoffeeScriptおよびLESS
スタック
- Django
- Postgres(MySQLから移行)
- RabbitMQ
- Celery
- Redis
- Memcached
- Varnish
- Nginx
- Ember
- Google Compute
- 11. Google Cloud Storage
アーキテクチャ
動作の仕組みは?
バックエンドアーキテクチャはクライアント、データおよびワーカーの3つのサブシステムで構成されています。
クライアントサブシステム
クライアントサブシステムは、2つの異なる負荷分散された自動スケーリングのアプリ&ソケットサーバで構成されています。ここでユーザとの相互作用が実行されます。遅延(レイテンシ)をできる限り低減するために、ブロッキング・コールがないよう細心の注意を払いました。
アプリサーバ:各アプリサーバはNginxおよびDjango-gunicornサーバがロードされた単独の計算ユニットで、supervisordにより管理されています。ユーザからの要求はここで処理されます。ユーザがアプリのURLを送信すると、それをRabbitMQdownloadのキューに送信して、ただちにURLが送信されたことをユーザに通知します。アプリをアップロードする場合は、サーバから署名付きのURLが取得されます。ブラウザはこの署名付きURLと共にデータをS3へ直接アップロードして、完了するとアプリサーバにそれを通知します。
ソケットサーバ:各ソケットサーバはNginxおよびノード(socket-io)サーバがロードされた単独の計算ユニットです。このサーバはアダプタとしてRedisを使用します。そしてもちろん、このサーバはリアルタイム更新のために使用されます。
データサブシステム
このシステムはデータ格納、キューイングおよびPub-Subに使用されます。また、分離アーキテクチャも担当します。
データベースクラスタ:Postgresを使っています。ご存知の通り、書き込み性能重視のマスターと数個の読み込み性能重視のレプリカで構成されています。
RabbitMQ:celeryワーカーのブローカーです。異なるワーカーには異なる待ち行列があります。
主に download、validate、upload、analyse、report、mailおよびbotです。ウェブサーバはデータを待ち行列に置き、celeryワーカーはそれを拾って実行します。
Redis:これはsocket-ioサーバのアダプタとして動作します。ユーザにワーカーからの更新を通知したいときは、Redisに送信すると、Socket.IOを通してすべてのユーザに通知されます。
ワーカーサブシステム
ここですべての力仕事が行われます。すべてのワーカーはRabbitMQからタスクを受け取り、Redisを介してユーザ宛に発行された更新を受け取ります。
静的スキャナ:これは自動スケーリングの計算ユニットグループです。各ユニットは4から5のceleryワーカーで構成されています。各celeryワーカーは一度に1つのアプリをスキャンします。
その他のタスク:これは自動スケーリングの計算ユニットグループです。各ユニットは、ストアからアプリのダウンロード、レポートのPDF生成、レポートPDFのアップロード、メールの送信など多様なタスクを実行する4から5のceleryワーカーで構成されています。
動的スキャン:これはプラットフォーム固有になります。各Android向け動的スキャナはオンデマンドの計算インスタンスであり、Androidエミュレータ(SDK付き)とデータをキャプチャするスクリプトを備えています。このエミュレータはユーザが使用するためにブラウザのキャンバス上に表示されます。各iOSスキャナは管理されたMac-Miniファームであり、iOSプラットフォームをサポートするスクリプトとシミュレータを備えています。
スタックの選択理由
Pythonは、アプリをスキャンするために使用している主要ライブラリがpythonであるという理由で選びました。それに、知っている言語の中でpythonが一番大好きだからです。
Djangoはモジュール方式を採用しているので選びました。
Ember – 世に出ているフロントエンドフレームワークの中で最高のものだと思っています。確かに学習の道は険しいですが、急勾配の山を一度登頂すると、誰でもemberを愛さずにはいられなくなるのです。その規約に忠実でいれば、最小限のコーディングで最大の効果が得られます。
Postgres – 元々は、業界標準だったMySQLを選びました。OracleがSun Microsystems(MySQLの親会社)を買収した後、MySQLは停滞してしまいました。皆そうなるのではないかと予想していたとは思いますが。このため、コミュニティにより保守されていたMariaDB(MySQLの派生)を使い始めました。その後、必要としていた持続性のあるKey-ValueストアがPostgresによってそのまま使用できる形で提供されていることがわかりました。これはPythonとも相性が良いです。私たちはPostgresのネイティブデータ型であるUUID をプライマリーキーとして使用しています。また、uuis-osspモジュールは、よりコストのかかるアプリケーションレベルでの作成ではなく、データベースレベルでUUIDを生成および操作する機能を提供していました。これらの理由により、弊社はPostgresに切り替えました。
その他については業界標準のものを選びました。タスクのキューイングにはRabbitMQ。タスク管理にはCelery。Pub-SubにはRedis。キャッシュにはMemcached および Varnish。
想定通りに運ばなかった事柄
想定通りに運ばなかった事柄の一つとしてソケットのスケーリングがあります。 開始当時はDjango-socket.ioを使用していました。その後、これでは複数サーバにスケーリングできないことに気付きました。そこで、個別のnodeモジュールとしてコーディングしました。Redisアダプタをサポートしているnodeのsocket-ioライブラリを使用しました。クライアントはnodeのソケットサーバに接続されています。このため現在ではpythonコードからRedisに発行します。nodeはただクライアントに通知をプッシュ送信します。これで、クライアントにとってJSONエンドポイントの役割を担うアプリサーバに依存せずにスケーリングすることができます。
スタックの特徴
モジュール方式の設計が大好きです。 フロントエンドとバックエンドを切り離すために、これまでの要素はモジュラー化してきました。そうです、読み間違いではありません。すべてのHTML、CoffeeScript、LESSコードがバックエンドに依存せずに開発されました。フロントエンド開発はサーバが稼働していなくても可能です。開発中のダミーデータとして、フロントエンドのテストデータ設定ファイルに頼っています。
バックエンドをシャーロックと名付けました。私たちはモバイルアプリケーションのセキュリティ脆弱性を検出します。この名前がぴったりだと思いました。シャーロックは賢いですから。
そして、フロントエンドをアイリーンと名付けました。アイリーン・アドラーを覚えていますか?彼女は美しく、華やかで私たちのユーザに問題点を伝えます。
最後に、管理系をハドソンと名付けました。シャーロックの大家さん、ハドソン夫人を覚えていますか?考えてみれば、かわいそうなワトソン博士にも何か役をあげればよかったですね。将来的にはそうするかもしれません。
つまり、シャーロックはHTML/CSS/JSファイルを処理しません。繰り返しますが、バックエンドは静的ファイル/ HTMLファイルを1つも処理しません。 シャーロックとアイリーンは両名とも個別に開発されました。両名とも個別の展開プロセスを備えています。両名ともに独自のテストケースがあります。シャーロックをインスタンス計算のために展開し、アイリーンはGoogle Cloud への格納のために展開します。
このようなアーキテクチャの利点を以下に示します。
- フロントエンドチームとバックエンドチームがお互いの邪魔をせずに独立して作業できます。
- サーバ上でのページのレンダリングなどの重労働からサーバを解放できます。
- フロントエンドのコードをオープンソース化できます。フロントエンドのための人員を雇うのが簡単になります。repoツールに上がっているバグを修正しておいて、と依頼するだけで雇うことができます。オープンソース化しなくても、結局フロントエンドコードは誰でも読める状態になりますよね?
展開プロセス
コードは master ブランチから自動展開されます。 Vincent Driessen氏の Git ブランチモデルを採用しています。Jenkinsによるビルドは develop ブランチに注力します。それが成功すれば、念のためもう一度マニュアルテストを実行した後 masterブランチにマージすると、コードが自動的に展開されます。
初めはAWSを使用。3つの理由でGoogle Cloudの使用を決めました。
- 様々なアプリケーションのリソース管理に対する「プロジェクト」ベースのアプローチが気に入りました。これは、インフラへのアクセスをより実用的にします。さらに、弊社の「動的スキャン」機能の複雑性のためにインスタンスの識別が容易になりました。
- 素晴らしいドキュメンテーションが備えられていて、困ったときにはGoogleエンジニアから個別の1対1サポートが受けられました。
- いくつかの有益なGoogle 特典を付与され、初期段階からコストを削減する助けになりました。
今まで弊社では、IaaSプロバイダの特殊なサービスは避けるようにしてきました。例えばAmazon RDSやSQSは使用しませんでした。また、独自のDBサーバ、RabbitMQおよびRedisインスタンスを構成しました。その理由としては、それらのサービスは比較的遅く(そしてコストが高く)、自社の製品がベンダー依存になってしまうことが挙げられます。これらすべてをベンダー非依存にするために抽象化しました。しかし、ストレージを抽象化することを忘れていました。
これまで弊社はS3を直接使っていました。これは、Google Cloudに移行しようとしたときの小さな改善点になりました。さらにGoogle Storageへの移行を決めたときは、ストレージレイヤを抽象化してGoogleのストレージ移行ドキュメントに従いました。そしてすべてがうまく行きました。これで、コードベースはGoogle CloudとAWSの両方でコードの変更なしにホストできるようになりました。もちろん、構成を変える必要は出てきますが、コードはそのままで使えます。
原文:http://highscalability.com/blog/2015/5/25/appknox-architecture-making-the-switch-from-aws-to-the-googl.html(2015-5-25)
※元記事の筆者には直接翻訳の許可を頂いて、翻訳・公開しております。
関連記事
-
-
実は午前中は仕事してない?!エンジニアあるある
どの職業にも「あるある」はあると思いますが、今回は普通の人にはなかなかわかってもらえないであろう、エ
-
-
WEBエンジニアの祭典!LL系カンファレンスの歴史
例年夏から秋にかけて開催されているLL(lightweight language, 軽量プログラミン
-
-
【FAworks】エイプリルフールにお付き合いいただきありがとうございました。
こんにちは。FAworksです。 昨日は『業界初!デスマーチ検索ができる案件情報サイトFAworks
-
-
あなたも聞いてる?テック系ポッドキャスト3選
最近、エンジニアの間でにわかに話題になっているのが「ポッドキャスト配信」です。エンジニア自身が時事的
-
-
これでもうコーディングに集中できる!デスクで暑さ対策グッツ7選
あっという間に夏も後半ですが、まだまだ暑い日が続きますね。 コーディングに集中したくてもなかなか暑く
-
-
『エンジニアのためのアドテク勉強会 vol.1』を開催します!
今回の勉強会は、株式会社ヒトクセの濁沼様にもご講義いただけることになりました! これからも定期的に開
-
-
【エンジニアのためのアドテク案件入門講座】を開催します!
勉強会の開催が決定しました! 久しぶりの勉強会開催となりますが、今回はアドテク案件に参画するために必
-
-
エンジニア的ワクワクコンピュータ映画7選
こんにちは!皆さん、映画観てますか?今回は人よりちょっぴり多く映画を観ていると勝手に自負している僕が
-
-
生まれてから100種以上に騎乗してきた僕が選ぶ本命ワーキングチェア。
どーも!こんにちは! 最近よく目にする「iPadのCM」の最後に出てくる都市、ベトナムはホーチミンで
-
-
営業マンからエンジニアへ~Part 3~
すっかり涼しくなってきて、秋めいてきましたね。 海、お祭り、花火大会など、アクティブな夏も楽しかった