Slide 1

Slide 1 text

Serverless or Not 選択やリプレイスに悩まないために

Slide 2

Slide 2 text

⾃⼰紹介 2024/11/25 #TechTrain #MOSH @KentarouTakeda / 武⽥ 憲太郎 Webアプリケーションエンジニア • PHP • 🚀 Laravel • ❤ Symfony • TypeScript • 🚀 React, Next.js • ❤ Angular, NestJS • AWS • 🚀 EC2, ECS, CloudFront • ❤ Lambda, SQS, DynamoDB, CDK Serverless or Not: 選択やリプレイスに悩まないために 1

Slide 3

Slide 3 text

アジェンダ 2024/11/25 #TechTrain #MOSH Serverless or Not: 選択やリプレイスに悩まないために 2 • 技術選定を通じ私達は何を採⽤しているのか? • 事例: Laravel + モジュラモノリス + Serverlss • 選択やリプレイスに悩まない設計

Slide 4

Slide 4 text

技術選定を通じ 私達は何を採⽤しているのか? 2024/11/25 #TechTrain #MOSH Serverless or Not: 選択やリプレイスに悩まないために 3

Slide 5

Slide 5 text

2024/11/25 #TechTrain #MOSH Serverless or Not: 選択やリプレイスに悩まないために 4

Slide 6

Slide 6 text

2024/11/25 #TechTrain #MOSH Serverless or Not: 選択やリプレイスに悩まないために 5

Slide 7

Slide 7 text

2024/11/25 #TechTrain #MOSH Serverless or Not: 選択やリプレイスに悩まないために 6

Slide 8

Slide 8 text

アーキテクトのデザイン 2024/11/25 #TechTrain #MOSH Serverless or Not: 選択やリプレイスに悩まないために • サーバレスとイベント駆動による • ⾼可⽤で冗⻑性の⾼いアーキテクチャ • CloudFormationによる • コントロールされたインフラストラクチャ • CodePipelineによる • 継続的なインテグレーションとデリバリ 7

Slide 9

Slide 9 text

現場の開発 2024/11/25 #TechTrain #MOSH Serverless or Not: 選択やリプレイスに悩まないために • 分散された⼤きな泥団⼦ • Lambda関数URLのタイムアウト • ⼀部の処理を別の関数に切り出し⾮同期実⾏ • HTTPの責務がバッチ処理に混ざり込む • 追跡困難な依存‧複雑化する設計 • 前任者の残した、秘伝のCloudFormation • 環境と密結合した、スケールできないCI/CD • フレイキーテスト、フレイキーデリバリ 8

Slide 10

Slide 10 text

AWS Lambda 2024/11/25 #TechTrain #MOSH Serverless or Not: 選択やリプレイスに悩まないために • 価値に対する⽀払い • ネットワークN+1による無意味な⽀払い • スケール性能 • RDSがボトルネックでスロットリング • Undifferentiated Heavy Lifting • Undifferentiated Heavy IaC Maintenance • 管理不要 • 設計が不要とは⾔ってない 9

Slide 11

Slide 11 text

マイクロサービスアーキテクチャの壁 2024/11/25 #TechTrain #MOSH Serverless or Not: 選択やリプレイスに悩まないために • サイロ型アーキテクチャ • コンウェイの法則と分散された⼤きな泥団⼦ • 少⼈数スタートアップは⽴ち向かえるか? • 少⼈数スタートアップには関係ない話では? 10

Slide 12

Slide 12 text

The Litmus Test for Serverless 2024/11/25 #TechTrain #MOSH Serverless or Not: 選択やリプレイスに悩まないために • サーバレスを採⽤すれば、 サービスは原則を満たす とは限らない • サーバを導⼊すると サービスは原則を満たさない とは限らない • 初期の技術選定で 全てを想定できる はずがない 原則 \ 選択 Serverless Server-Based 満たす ⭐ 🚀 満たさない 🔥 🧨 11

Slide 13

Slide 13 text

Serverless or Not 結論: どちらにも転べる設計 2024/11/25 #TechTrain #MOSH Serverless or Not: 選択やリプレイスに悩まないために 12

Slide 14

Slide 14 text

事例: Laravel + モジュラモノリス + サーバレス 2024/11/25 #TechTrain #MOSH Serverless or Not: 選択やリプレイスに悩まないために 13

Slide 15

Slide 15 text

Laravel Framework • 交換可能なドライバ • ストレージ、メール、データベース • キュー、キャッシュ、認証 • フルスタックフレームワーク • Laravel単独で⼀通りのアプリは構築可能 • モノリシック設計が暗黙の前提 2024/11/25 #TechTrain #MOSH Serverless or Not: 選択やリプレイスに悩まないために 14

Slide 16

Slide 16 text

Bref, Bref Laravel Bridge 2024/11/25 #TechTrain #MOSH Serverless or Not: 選択やリプレイスに悩まないために Bref • AWS LambdaでPHPを実⾏するカスタムランタイム • Serverless Framework Plugin, CDK Construct Bref Laravel Bridge • LaravelアプリをBrefで実⾏するグルーコード 15

Slide 17

Slide 17 text

Laravel: イベント発⽕とサブスクライブ 2024/11/25 #TechTrain #MOSH Serverless or Not: 選択やリプレイスに悩まないために /** イベントクラス */ class PostCommented { public function __construct( public readonly Comment $comment, ) { } } /** サブスクライバクラス */ class PostCommentedNotifyAuthor implements ShouldQueue { public function handle(PostCommented $event) { $author = $event->comment->post->author; /* 投稿者 `$author` に通知を送る処理 */ } } $event = new PostCommented($comment); event($event); // ディスパッチ { "displayName": "App¥¥Listeners¥¥PostCommentedNotifyAuthor", "data": { "command": "... s:18:¥"App¥¥Models¥¥Comment¥";s:2:¥"id¥";i:42 ..." } } シリアライズ 発⽕先クラス 発⽕パラメータ 発⽕ 16

Slide 18

Slide 18 text

Bref Laravel Bridge: SQSオブザーバ 2024/11/25 #TechTrain #MOSH Serverless or Not: 選択やリプレイスに悩まないために public function handle($event, Context $context) { $this->handleSqs(new SqsEvent($event), $context); // 省略 } // SQSバッチオペレーションからLaravelジョブを復元 foreach ($event->getRecords() as $sqsRecord) { // Laravel内部のジョブ処理を直接起動 $worker->runSqsJob( $job = $this->marshalJob($sqsRecord), $this->connection, $this->gatherWorkerOptions($timeout), ); // 省略 } 17

Slide 19

Slide 19 text

アーキテクチャ‧アプリケーション構成 2024/11/25 #TechTrain #MOSH Serverless or Not: 選択やリプレイスに悩まないために APIリクエスト / SQSプロバイダ SQSコンシューマ HTTP HTTP 同⼀のLaravelアプリケーション プロバイダとコンシューマが 同⼀アプリケーションであることが前提 18 参考: Laravel Queue Workerの構築から学ぶBrefとAWS Lambda

Slide 20

Slide 20 text

Lambda関数の責務は⼩さく保つべきでは? 2024/11/25 #TechTrain #MOSH Serverless or Not: 選択やリプレイスに悩まないために • 「サイズが⼤きい = 責務が⼤きい」ではない • 責務境界はアプリケーション内でもコントロールできる • コントロールできていない分散泥団⼦の⽅が⾟い • モジュラモノリスアーキテクチャ • Serverless / Server-Based 両⽅で動くアプリケーション • Docker Image Functionがゲームチェンジャー • 10GBまでの任意のDockerイメージを関数化可能 19

Slide 21

Slide 21 text

モジュラモノリスによる 「どちらにも転べる設計」 2024/11/25 #TechTrain #MOSH Serverless or Not: 選択やリプレイスに悩まないために 20

Slide 22

Slide 22 text

HTTPリクエスト • 全てのエンドポイントを単⼀の関数に束ねることで: • ルーティングの責務はアプリケーション側に移動する • 任意のWebアプリケーションフレームワークを導⼊可能 • Serverless Express, AWS Lambda Web Adapter • Express, Apollo Server, NestJS • アプリケーション側でのクリーンな設計が鍵 • Express: ビジネスロジックをリクエスト処理から分離 • Apollo: ビジネスロジックをミューテーションから分離 • NestJS: ⾮ビジネスロジックをデコレータで隔離 2024/11/25 #TechTrain #MOSH Serverless or Not: 選択やリプレイスに悩まないために 21

Slide 23

Slide 23 text

キューコンシューマ 2024/11/25 #TechTrain #MOSH Serverless or Not: 選択やリプレイスに悩まないために • HTTPリクエスト処理と同じアプリケーション • エントリポイントとタイムアウト設定のみ異なる • 1つの関数、1つのSQSキュー • 処理の冒頭でキューを「ルーティング」 • ペイロードの型定義や型ガードをモノリス内で契約として使う • 「優先度」に応じた複数のキューと関数を⽤意しても良い • 通常キュー: スロットリングされた関数へ配送 • 優先キュー: スロットリングしない関数へ配送 • アプリケーション側でのクリーンな設計が鍵 • ビジネスロジックをハンドラやルーティングから分離する 22

Slide 24

Slide 24 text

その他のサーバレス技術 2024/11/25 #TechTrain #MOSH Serverless or Not: 選択やリプレイスに悩まないために • Amazon API Gateway, Amazon Cognito • フレームワークの「ミドルウェア層」で吸収 • ミドルウェア層からCognito APIなどをコール • 各ミドルウェアは単⼀責務 • 責務が⼩さければそれをサーバレス技術に置き換えるのは容易 • その他のLambdaイベントソース • 「HTTPリクエストの処理」「キューの処理」と同じ考え⽅ • 各処理に対応したCLIコマンドを作成すると良い • Server-Basedではこのコマンドをバッチとして使う 23

Slide 25

Slide 25 text

その他のサーバレス技術 2024/11/25 #TechTrain #MOSH Serverless or Not: 選択やリプレイスに悩まないために • ログ‧モニタリング • モノリスに統合せず単独のLambda関数としても良い • 監視の責務はビジネス要件と直交するはず • ログライブラリの提供するフォーマットが契約 • AWS Step Functions, AWS CloudFormation • 「Serverless or Not」を決断するタイミング 24

Slide 26

Slide 26 text

まとめ 2024/11/25 #TechTrain #MOSH Serverless or Not: 選択やリプレイスに悩まないために • アーキテクチャ選定は 課題解決を助けるが成功を保証しない • 決断が必要な時はいずれ来る それまでは「どちらにも転べる」設計を • モジュラモノリスとグルーコード 鍵を握るのは「クリーンな設計」 25