Google App EngineとManaged Serviceだけでプロダクトのインフラを構成してみた
はじめに
初めまして、トライバルメディア ハウスで新規プロダクトのテックリードをしている松田と申します。今回新規プロダクト用にGoogle Cloud Platform(以下、GCP)でインフラ構成を組んでみたので、その一部を紹介します。
目次
- はじめに
- 目次
- 本記事を書いた理由
- 構成について
- Google App Engine(以下、App Engine)を選択した4つの理由
- 今回気づいた懸念点
- まとめ
- 今後について
- 余談
- 参考: サービスの説明
本記事を書いた理由
弊社トライバルメディアハウスは様々な事業ドメインで新規プロダクト開発しています。その過程でインフラ設計やアーキテクチャ設計をしており、それらの取り組みや過程を外部の方にも知っていただきたく、その一部である1プロダクトのインフラ選定について本記事でまとめてみました。
構成について
下記の構成で組んでみました。各サービスの詳細が気になる方は記事の最後に簡単な説明やリンクを貼っておきましたのでそちらを参照ください。
簡易構成図
Google App Engine(以下、App Engine)を選択した4つの理由
StorageやDatabaseはそもそもあまり選択肢はないと思うので、今回PaaSであるApp Engine(スタンダード環境)を選んだ経緯と理由を書いていきます。
1. サーバの運用に稼働がかからない
新規事業開発においてはユーザ体験などをいち早く検証することが大切であり、それが開発の成果にもつながります。
サーバの監視や運用などにエンジニアの稼働が取られるのは事業のフェーズ上あまり価値にならず、できる限り運用不要な構成にしたいと考えました。その観点でPaaSであるApp Engineは非常に良いと思いました。
加えて、新規事業が複数あるため、専任のインフラ担当者をアサインしづいという状況の中で、App Engineであればインフラの知識や経験がなくても環境構築が可能です。
2. 自動でスケールアウトする
App Engineは、自動スケーリングを指定した場合、受信リクエストに応じたインスタンスのスケーリングおよびロードバランシングを実施してくれます。
また下記のような状況で今回インフラ選定をする必要がありました。
- 初期からインフラのスケーラビリティを正しく設計するのが難しい
- といいつつ、スケールの問題でサービス自体を止めるという状態も避けたい
スケーラビリティの設計が不要であり、スケールが担保されているという点で、App Engineは今回の状況に適していると判断しました。
3. 標準のランタイム(特にGo)が動く
App Engineは多言語のメジャーなランタイムをサポートしており、環境に依存しない形でアプリケーションを実装できます。つまり、万が一アプリケーションを他インフラに移行する際も環境にロックされるリスクがほとんどないです。
現状、将来を踏まえたインフラを選定することが難しいため、環境にロックされないことが非常に重要だと判断しました。
今回バックエンドはGoで実装していますが、去年リリースしたGo1.12も動作が保証(公式ドキュメント上はGo1.12+と記載)されているので、今後の開発でGoの実行環境で開発が困ることはなさそうです。
4. 簡単な環境構築
YAMLファイルで設定を定義した後、ワンラインのSDKコマンドでデプロイが可能です。ロードバランシングなどを自前で設定する必要はありません。個人的には他のクラウドサービスのPaaSとApp Engineの一番の違いはここじゃないかなと思っています。
また副次的効果ではありますが、CD(Continuous Delivery)のpipelineを作るのもワンラインで済むので非常に楽です。
事業的にフィードバックループのスピードが重要で当然CDも重要なため、このように便利なSDKがあるのもApp Engine(というよりGCP)を選択した理由のひとつです。
今回気づいた懸念点
結果的にいま開発しているプロダクトでは問題になっていないのですが、少し気になったところをまとめてみました。
クローズドな通信の実現が難しい
App Engine自体がインターネットアクセスを前提としているので、サービス間のクローズドな通信を実現しようとすると途端に難しくなります。
当然ネットワークではなく自分たちのアプリケーション側の認証でアクセス制限することもできますが、可能な限りネットワークレイヤーで制限したい場合には向かないかなと思いました。
Cloud IAP などでApp Engine手前で認証を入れることもできる気もしますが、OAuthなど実装が難しそうです。
重い処理には向いてなさそう
自動スケーリングの場合、リクエストのタイムアウト時間があり、それより長くかかる処理はタイムアウトし実行が終了してしまいます。
重いバッチ処理などを実行させたい場合は手動スケーリングでインスタンスを常時立ち上げるか、フレキシブル環境で実現すれば良いのですが、それはそれでPaaSの良さを無くしてしまう可能性もあります......
まとめ
App Engineは、多少制約はあるものの使いどころを間違わなければ非常に強力だと感じました。下記の場合、利用に向いているのではないかと思います。
- アプリケーションエンジニアが中心のチーム
- 事前のスケーラビリティ設計が難しいプロダクト
- リクエスト数に比例する課金体系が事業的にマッチしているプロダクト
- リクエストが急激に跳ね上げる可能性があるプロダクト(Webメディアなど)
- クローズなサービス間通信の必要がないプロダクト
今後について
このようにGCPの力も借りつつ、新規プロダクトをいち早く正式リリースできるように今後も頑張っていきたいと思います。正式リリース後に具体的なサービスの中身や機能についても記事にする予定です。
余談
「Cloud Runを選択肢に挙げなかったのは何故?」という疑問があるかと思いますが、「選定時期より後にGAになったため選びたくても選べない状態だった」というのが答えになります。ただし今後のために素振りはしておきたいと思っています。
参考: サービスの説明
他サービスも含めた簡単な説明と利用用途、リンクを記載しています。興味のある方は参考にして頂ければ
利用サービス
- App Engine
- Cloud CDN
- Cloud Storage
- Cloud Memorystore
- Cloud SQL
- 他、Cloud DNSなどネットワークサービス
利用方法・用途
App Engine
App Engineは主に二つの用途で使っています。
フロントエンド に必要なリソース(HTML/CSS/JS)を返すクライアント向けのアセット配布的な役割とServerside Renderingなどに使用しています。(React/Next)
バックエンド側はビジネスロジックを実装し、APIサーバとして稼働させています。合わせてDatabaseへの参照や書き込みも実装しています。
App Engineはサービスという単位で管理体系を分けられて、事前に定義したdispatch.yamlファイルに従いリクエストを各サービスへルーティングさせることができます。Source IPで通信を制限できる簡易的なFirewallも備えています。
Cloud CDN/Storage
画像など静的ファイルをCloud Storageに格納して、適切なキャッシュ設計をしCDNにキャッシュさせます。この辺は特に目新しい事はしていません。
Cloud SQL
主要なデータを主に格納する SQL Databaseです。App Engineからの接続方法もそれほど難しくありません。方法については下記を参照ください。
Cloud Memorystore for Redis
App Engineには元々memchachedというメモリキャッシュサービスがあったのですが、最近のApp Engineのランタイムでは非推奨となっていたので、今回Memorystoreを使う事にしました。接続には最近GAになった Serverless VPC Accessを使っています。詳細は下記を参照ください。