🧐

Lambda + Monolithはアンチパターンなのか? マイクロサービスでなく「小さくはじめる」選択肢

2023/12/11に公開

2023年のマイクロサービス事情

雑談から入ろう。

明言されることは少ないが、「マイクロサービス」には明らかにダメな検討過程と呼ぶべきものがある。

  • ここ10年のモダンなインフラ基盤で存在感のあるAWS、Kubernetes、etc...が採用しているから、推奨しているから採用。
  • チーム、部署、所属企業の分断がまずあり、そこを境界にとした「マイクロサービス」を採用。
  • サービスの特性やロードマップを整理せずに、拡張性が高そうだから。

こういう理由で採用するのは安直だよね。とさすがに2023年末では落ち着いていて、地に足のついた真面目な議論のできる状態だと信じている。(どれが私の経験談かは聞かないでほしい)

少しずつ本題に入る。AWS Lambdaはイベントドリブンなサービスである。それもあってマイクロサービスとの相性がいい。マイクロサービスとの相性が良く、モノリスがアンチパターンなのだ。という見解が一般的だろう。ただ、そこに私はうっすら違和感があった。そんな中、あるブログに出会った。

Lambda + Monolith = Lambdalith

今年読んだAWS関連の記事で最もエキサイティングだったブログのひとつを紹介したい。

https://rehanvdm.com/blog/should-you-use-a-lambda-monolith-lambdalith-for-the-api

1行でまとめると‘サーバレスAPIについては、Lambdalith(Lambda + Monolith)から始めていいんじゃない?’という話だ。

おいおい、LambdaのMonolith運用は公式ドキュメントにも書いてあるアンチパターンだぜ。と知っている人は思うかもしれない。

https://docs.aws.amazon.com/lambda/latest/operatorguide/monolith.html

安心してほしい。そんな人ほど一度は読むべきブログである。少なくともAWS Community HEROに選ばれる著者は、当然その点を踏まえて書いている。

Blogの要点

ベストプラクティスの前提は正しいか?という点で、数々の回答を行っている。以下は抜粋なので、ぜひとも本文を読んでほしい。

  • API Gatewayの機能は、ちゃんと使いこなせているか?
    • ただのパスルーティングだけなら、Lambdaをぶつ切りにする必要はない。
  • モノリスだとPackageがデカくてCold Start?
    • 実際はp99のエッジケース。
  • MonolithだとDeploy影響を局所化しづらい?
    • 実際は共通コードまみれ。単にDeployを複雑にしただけでは

Lambdalith Serverless APIに必要なもの

モジュラーモノリス化されたLambdaでのAPI≒Lambdalith Serverless APIに必要なものは何だろう。先のブログでは触れられていた「API Gateway」に頼らないルーティングの実現には、3つの武器がある。

  1. Lambda Functions URL
  2. Lambda Web Adapter
  3. Serverless Native Framework

Lambdalithへの追い風となるこれら3つの概念を、改めて見ていこう。

1. AWS Lambda Functions URL

AWS Lambda Functions URLは2022.4から登場した、LambdaにそのままHTTPSの口を生やす機能である。

https://aws.amazon.com/jp/blogs/news/announcing-aws-lambda-function-urls-built-in-https-endpoints-for-single-function-microservices/

かなり便利な機能ではあるが、プロダクションでの不採用理由の2大巨頭として「AWS WAFがつけられない」「AWS IAM認証がサービスに向かない」がある。要はEDoSやWAF対応に不安を感じる、というやつだが、これの回避用のワークアラウンドはあって、以下の記事が参考にできる。

https://aws.amazon.com/jp/blogs/compute/protecting-an-aws-lambda-function-url-with-amazon-cloudfront-and-lambdaedge/

https://iret.media/88185

※このLambda@Edgeで署名する部分が面倒と言われるとそうなのだが……

2. Lambda Web Adapter

ルーティングをはじめとする、シンプルかつ移植性の高い記述には、やはりWeb Frameworkが必要だ。ファーストチョイスとしては、Lambda Web Adapterがある。

https://github.com/awslabs/aws-lambda-web-adapter

このアダプターはLambdaと既存のフレームワークを繋ぐために、 Lambdaで受け取ったイベントをリクエストに変換し、任意のWebフレームワークに転送する汎用アダプターである。
高いセキュリティと効率性を持つRust言語で開発されたOSSである点もよさそうだ。

コンテナ on Lambdaでは、このように1行追加で導入できる。

COPY --from=public.ecr.aws/awsguru/aws-lambda-adapter:0.7.1 /lambda-adapter /opt/extensions/lambda-adapter

気になる点として、AWS管理ランタイムではもう少しお作法があるため、導入に好みが分かれるかもしれない。私はランタイムも管理したくないので、後述のHonoを選ぶことが多い。

https://github.com/awslabs/aws-lambda-web-adapter/tree/main/examples/expressjs-zip


3. Serverless Native Framework

たいていの場合はAWS推奨である「Lambda Web Adapter」を選ぶだろうが、こちらも紹介したい。

Lambda Web Adapterに頼らずとも、標準機能としてAWSに対応するFrameworkは、実は複数ある。

  • Serverless Express
  • Hono
  • fastify
  • tRPC

出典:やまたつ氏(@yamatatsu193)
https://twitter.com/yamatatsu193/status/1726756183644746021

Hono

私がFramework「Hono」のコントリビュータとして、「AWS Lambda」「Lambda@Edge」Adaptorを中心的にメンテナンスしているというポジショントークが多分に含まれるのだが、Honoはこの用途においてて自信をもってお勧めできる。

その辺の詳細はHono Advent Calendar 2023の12/20でまとめようと思うので、乞うご期待。

使い方としては、私が書いた記事がいくつかあるので、参考にしていただければ。

https://qiita.com/watany/items/72dad3c4953238a16c9c

https://qiita.com/watany/items/b86c2304832126de76e0

https://zenn.dev/watany/articles/d8f7ed33aec139

https://zenn.dev/watany/articles/b82029522c762c

まとめ

ということで、マイクロサービス以外にもモジュラーモノリス的にAWS Lambdaを、少なくともAPI利用においては扱える可能性の話に感動したので、自分の興味関心を交えて書いてみました。この辺はオレオレの部分も多いですが、知見をアップデートしたり、従来の手法と比較してみるのも面白い分野だと思います。皆さんの意見も聞かせて欲しい!

参考資料

https://speakerdeck.com/_kensh/web-frameworks-on-lambda

https://speakerdeck.com/_kensh/monolith-first-serverless-development

Discussion