概要
最近はAIのAPIを利用したウェブアプリのプロトタイプをサクッと作って気軽にデプロイするニーズが結構多いのではないかと思うが、Vercelなど気軽にアプリをデプロイできるサービスが多いにも関わらず、意外と使えなくてハマったので、おすすめを共有する。
結論から言うと、GCP Cloud Run最強。
背景
なるべく手間を掛けずにリモートにデプロイしたい(思考停止状態でもインフラ構築してデプロイできるレベルがいい)。かつ、安く済ませたい(無料レベルで)。
そのニーズに応えるサービスは今や多々あり、ここではVercel, AWS Amplify, AWS App Runner, Cloudflare Page, GCP Cloud Runなどの基本的にサーバレスサービスを検討した。他にも色々とあるとは思うが。
Next.jsでサクッと作ったのでコストのかからないVercelでデプロイもサクッと済ませようと思ったが、デプロイして実際にアプリを使ってみたら、下記の課題が浮き上がってきた。残念ながらプロトタイプとしても利用できないレベル。
課題
- AI APIのレスポンスが遅くて、自分のWebアプリがタイムアウトしがち
- PDFなど処理したいときに、ファイルサイズ上限でエラーになりがち
各サービスの制限の比較
上記で羅列したサーバレスサービスに関してそれらを調査してみたら下記の表のようになった。
| 項目 | Vercel | AWS Amplify Hosting | AWS App Runner | Cloudflare Pages + Workers/Functions | GCP Cloud Run |
|---|---|---|---|---|---|
| サーバ固定費用 | 基本なし(従量+プラン料金) | 基本なし(従量課金) | あり:最小インスタンスプロビジョニングで課金(vCPU/メモリ従量、最小保持) | 基本なし(Workers課金は従量) | 基本なし(インスタンス実行時間従量) |
| Free Tier | Hobby: ビルド1000回/月、1TB帯域/月など | 5GB/月 S3, 1000分/月 Lambda@Edge など非常に少なめ | 1年無料で 1 vCPU 1GB コンピュート 1TB outbound | Workers: 10万リクエスト/日 | 2M req/月、コンピュート 180,000 vCPU-sec/月 |
| リクエストタイムアウト | 10 秒 (Serverless Functions)。Edge Functions は 1 分 | 30 秒 | 60秒固定 | 50 秒(Workers) | 60 分 |
| ファイルアップロード上限(ユーザ ⇨ Web)」 | 4.5MB | 5MB程度 | 不明 | 100MB(Workers) | 32MB(同期) |
| コールドスタート時間 | 非常に小(100–300ms)だが関数数が多いと増加 | 数百 ms〜数秒(Lambda@Edge依存) | 数秒〜10秒(コンテナ起動) | 業界最速クラス:数 ms〜数十 ms | 数百 ms〜数秒(内蔵最適化あり) |
上の表にあるように、Cloud Runのリクエスト処理時間上限は桁違いに長い。AI APIの種類や使い方次第ではAPIのレスポンスが1分以上かかることは普通にある。APIコールに1分かかる可能性があるだけで、もうCloud Run以外の選択肢が消えてしまう。
非同期にすることも考えたが、Lambdaはレスポンスを返した時点で処理をやめてしまうので、Lambda関数内で呼び出していたAI APIコールもレスポンスを受け取らないまま終了してしまう。
ファイルアップロードのファイルサイズもCloud Runは大きめで、アップロードの常識の範囲内では十分だと思う。巨大なファイルをアップロードする場合はそもそも別の方法を検討すべきなので。
他のCloud Runの大きな魅力
- RDS proxyが不要
- コールドスタートが比較的速い
- 本番に組み込める柔軟性
RDS proxyが不要
RDS proxy はAWSでLambda + RDS構成を検討した人にはおなじみだと思うが、多数のLambda起動によりRDSの接続数が食いつぶされてしまうのを防ぐためにAWSではDBコネクションプールの役割も果たすRDS proxyをLambdaとRDSの間に挟むことが多い。そして、こいつが固定費(約$20/月)がかかるのだ。
せっかく使った分だけ課金のLambdaを採用しているのにRDS proxyの固定費がかかってたら台無しだ。(AWS Aurora Serverless v2だと無くても良さそうではあるが)
コールドスタートが比較的速い
Lambdaベースのサービスで良く聞くのがコールドスタートで、ユーザリクエストに対してレスポンスが悪くなることがあるということ。
Cloud Run(軽量コンテナ)
- 100ms〜300ms(軽いアプリ)
- 300ms〜1.5秒(Node/Djangoなど一般的な Web アプリ)
- 数秒(巨大イメージ・外部接続・ORM初期化などが重い場合)
AWS Lambda(同じ Node/Python アプリ)
- 200ms〜2秒(プロビジョニングなし)
- 1〜5秒(コンテナイメージ Lambda・メモリ少ない・依存大きい場合)
- Provisioned concurrency:ほぼ 0ms(だが有料)
→ 中央値では Cloud Run の方が安定して速い。
本番に組み込める柔軟性
Cloud Runは単体でVercelやAmplfyの様にシンプルに使うこともできるが、下記の柔軟性があって本番運用にも流用できるため、作り直さずに拡張するだけで良いのもありがたい。
AWSのサービスでも同じことは言えるが、Cloud Runをリージョン冗長化させてLBで統合したり、直アクセス不可にするとか、Cloud Storage (AWSで言うS3) をLBで同じドメイン化に配置したり、GCPのWAF (Cloud Armor)を追加したり、可用性・セキュリティ・拡張性など色んな面においてGCPの中で好きなようにできて、プロトタイプから大規模であったりクリティカルなサービスにも対応することができる。
まとめ
いろいろあるサーバレスなWebホスティングサービスは(AI APIを使う場合は特に)Cloud Runがタイムアウトが長く、ファイルアップロードサイズ上限が大きいので、今のところベストだと思う。
その他、Cloud Runは本番運用でも実用的で、幅広く使えるのでオススメ。
今までAWSばかり使用していたが、最近はGCPめちゃいいかもと思っている。管理画面もAWSよりわかりやすいし、コード化はCDK for Terraformとかもあるし、今後はGCPばかり使うようになるかも。