サーバーレス LAMP スタックとは何か
はじめに
「サーバーレス LAMP スタック」という聞き慣れない単語をたまたま見かけて気になったので調べてみました。
サンプルとして下記のリポジトリに一通り作ったもの置いてますので、もし気になった方はそちらをご覧ください。
サーバーレス LAMP スタックの起源
従来の LAMP スタック
まずは、サーバーレス LAMP スタックを理解するために、サクッと従来の LAMP スタックをおさらいします。「そんなのいらならから、早く結論だけ教えて!」という方は サーバーレス LAMP スタックの構成 までスキップいただいて構いません。
従来の LAMP スタックとは、動的な Web アプリケーションを構築するためのソフトウェアスタックです。Linux、Apache、MySQL(MariaDB)、PHP(Perl、Python) の頭文字を取ってできた造語です。それらはどれもオープンソースとして提供され、だれもが無料で使用できるというのが特徴です。
従来の LAMP スタックの抱える課題
スケーラビリティ
最も重要な課題です。ユーザからのリクエストは全て Web サーバが担うことになるため、アクセスの増加に伴ってサーバを水平スケールする必要があります。そのためには、複数のサーバへのリクエストをロードバランサーによって捌くようにしたり、動的にサーバを増減したりといった仕組みをあらかじめ構築する必要があります。そこまでやったとしても突発的なアクセス急増に耐え得る状態を作るのはかなりの工夫と手間が必要です。
セッション管理
セッションは、サーバごとに持つことになるためスケーリングによりサーバが増えた場合、新しいサーバにはセッションを持っていないということが起こり得ます。一般的には、Redis や Memcached といった他の DB へと保存するのが望ましいとされてます。
静的コンテンツの配信
画像や CSS、JavaScript といった静的なデータを Web サーバに配信させていては、サイズが大きすぎてパフォーマンス低下や可用性に影響を与えかねません。この問題については下記の記事に分かりやすくパターン毎まとめてありました。
ここまでで従来の LAMP スタックの持つ課題が見えてきました。そして、それらを解決するべく考え出されたのが今回のトピックである「サーバーレス LAMP スタック」です。
サーバーレス LAMP スタックとは
このソフトウェアスタックを一言で表すと、「AWS が提唱する PHP アプリケーションを AWS Lambda で構築するハイスケーラビリティなサーバーレスアーキテクチャ」です。このスタックは、 AWS のサーバーレスアプリケーションのシニアデベロッパーアドボケートの方が発表したもののようです。
LAMP のそれぞれの頭文字がどう変わったのか下記に示します。
- L:AWS Lambda
- A:Amazon API Gateway
- M:Amazon Aurora Serverless(MySQL エンジン)
- P:PHP Runtime Layer For AWS Lambda
この構成を簡単に説明すると、まず全てのリクエストは CloudFront を経由します。そして動的なリクエストは API Gateway へ、静的なリクエストは S3 バケットへルーティングされます。PHP で構築されたアプリケーションが Lambda 関数としてバックエンドで DB 層とのやりとりを担います。DB 層は、MySQL エンジンを選択した Aurora Serverless を使用します。
API Gateway, Lambda, Aurora Serverless らは、ユーザのアクセスに応じて自動でスケーリングされたり、運用管理を楽にしたりしてくれます。まさに前述したスケーラビリティの課題を解決したと言えるでしょう。
サーバーレス LAMP スタックの構成
前提
サーバーレスアプリケーションの開発には Serverless Framework を使うことが多いため今回もこちらを採用しました。(サーバーレスアプリケーションモデル 通称 SAM も有力な選択肢として入ってくるのではないでしょうか。)
ローカル環境
今回は Laravel Sail を使いました。Sail は、一瞬で Laravel アプリケーションを Docker 上で構築できる優れものです。Sail の実態としては、 cURL でダウンロードした docker-compose.yml
がローカルで動作するという仕組みです。スクリプトも用意されており、Sail コマンドより docker-compose コマンドを使うことができます。
./vendor/bin/sail up -d
# 「 docker-compose up -d 」 と同様
このように、サーバーレスアプリケーション開発におけるローカル環境は、より Lambda に近い環境を作ることができるため Docker を使うのがベターだと考えています。今回は Sail をデフォルトのまま使っていてそこまで対応できていませんが、チーム開発する場合は依存ライブラリを含めた Docker イメージを作ったりや Lambda に近い環境にカスタマイズしたりしておくのが良いでしょう。
こちらの記事が大変参考になりました。
Lambda Layer とカスタムランタイム
Lambda Layer
複数の Lambda 関数でライブラリやパッケージ共有できる仕組みです。従来までは、Lambda 関数内に含めてデプロイする必要がありましたが、Layer 化しておくことでそれぞれの関数で必要な時はその Layer を使うだけで済むようになりました。
カスタムランタイム
標準のランタイムとしてサポートされていない言語でも Lambda を実行できる仕組みです。Lambda では boostrap という実行ファイルをデプロイパッケージに含めると、それをエントリーポイントとして実行してくれます。あるいは、bootstrap をレイヤーに含めておいても良いみたいです。これにより、Python や Go、Ruby などの言語を使ったことのない開発者でも気軽に自分の得意な言語で Lambda を使うことができます。
これらの仕組みを活用することで Lambda 上で PHP を動作させることができます。
Bref
前述した方法で PHP を上で Lambda を実行できるようになりました。しかし、素の PHP ではなく Laravel などのフレームワークを利用して開発したい場合 bootstarp や Lambda Layer を一から準備するのはなかなかに手間がかかります。
そこで登場するのが、Bref というライブラリです。Bref とは、AWS Lambda 上で Laravel/Symfony などのフレームワークの構築を楽にしてくれるライブラリです。PHP Custom Runtime Layer や独自の Bref CLI を提供しています。
AWS 上の Lambda に対しても Bref CLI を通してコマンドを実行できます。下記にマイグレーションとシードする例を挙げましたが、非常に直感的に操作できます。
# migrate
$ ./vendor/bin/bref cli <lambda artisan function name> --region <your region> -- migrate
# seed
$ ./vendor/bin/bref cli <lambda artisan function name> --region <your region> -- db:seed
Aurora Serverless
最後にこちらは、オンデマンドに自動でスケールする Aurora データベースのサーバーレスモードです。下記の記事にもありましたが、言葉尻に惑わされることなく、適切な用途かどうかを見極めたいところです。
システム要件を満たすという前提で、運用における管理コストと料金を抑えられるのか吟味したいこところです。
まとめ
サーバーレス LAMP スタックについて、その起源からどういうソフトウェアコンポーネントで構成されるのか見ていきました。個人的に使ったことのないサービスが多く非常に勉強になりました。アーキテクチャには、向き不向きがあるので場合に応じて導入すべきか判断していきたいです。
それでは最後にポイントをまとめます。
- サーバーレス LAMP スタックとは
- 従来の LAMP スタックの課題を解決すべく考え出された AWS のサーバーレスアーキテクチャ。
- ハイスケーラビリティと高コスト効率を提供する
- AWS Lambda の用途が広がっている。
- カスタムランタイムが使えるようになったので PHP を動かすことができる。
- Laravel フレームワークは Bref を使うと超絶簡単。
参考にさせていただいたサイト
Discussion