每条路线有 1 个 Lambda 函数会更好吗?或 1 个处理子路由的 Lambda?

Is it better to have 1 Lambda function per route? or 1 Lambda that handles child routes?

如果我有一个 API 具有以下路线

POST /slack
POST /slack/hook
POST /slack/another-hook
POST /slack/hook/nested

在 API 网关中有 4 个独立的 Lambda 函数和 4 个路由是否更好?或者为根路由设置 1 个 Lambda 并让 Lambda 从那里处理路由?

示例 1

POST /slack --> lambda1
POST /slack/hook --> lambda2
POST /slack/another-hook --> lambda3
POST /slack/hook/nested --> lambda4

示例 2

POST /slack --> lambda1
POST /slack/hook --> lambda1
POST /slack/another-hook --> lambda1
POST /slack/hook/nested --> lambda1

有这方面的最佳实践吗?如果是,为什么?

如果有人说有正确和错误的答案,我会感到惊讶。

我在不同的项目中都做过,我想这归结为 CICD 偏好、体系结构、时间限制。

从理论上讲,拥有一个 lambda 可以简化您的架构,但实际上您正在构建一个具有适用于该架构的所有缺点的单体应用程序,但是,如果您是单个开发人员,它会显着减少构建、测试和部署过程,因此您不必担心 lambda 之间的依赖关系,并且拥有一个可部署的工件。

另一方面,多个 lambda 函数为您提供类似于微服务的灵活性,但它需要您拥有单独的管道,并且整个 CICD 生态系统变得更加复杂和耗时。

将所有代码都放在一个 lambda 函数中时要注意的另一件事是大小限制和潜在的依赖地狱,具体取决于您的语言。

不知道你的 organisation/project 和时间限制,我可能会从一个 lambda 开始,然后如果需要将它拆分成多个 lambda 函数...

此博客 post here 解释了各种无服务器模式的优缺点。以下是一些需要注意的事项:

每个路由一个 Lambda,也就是微服务模式:

优点

  • 更容易调试,因为每个 lambda 都有一个非常具体的函数,并且 cloudwatch 日志分开得很好。
  • 更容易测试,因为每个 lambda 处理一个单独的事件。
  • 部署更精细。更新功能只能影响特定功能,因此您可以分离关注点。

缺点

  • lambda 的冷启动可能更多,因为其中一些可能不经常访问。

  • 您可能最终需要管理很多 lambda 函数。

  • 部署速度较慢,因为要部署多个功能。
  • 您可能很快就会 运行 进入单个堆栈的 cloudformation 资源限制(即 200 个资源)。我个人 运行 对此感兴趣。

一个具有多个路由的 Lambda 也称为 service/monolith 模式,具体取决于路由的分组方式:

优点

  • 较少的冷 starts/better 性能,因为 lambda 会被频繁调用并保持温暖。
  • 需要管理的 lambda 函数更少。
  • 部署速度更快,因为要部署的功能更少。

缺点

  • 更难调试和分析 cloudwatch 日志,函数处理多种类型的事件。
  • 你需要编写和维护一个路由器。
  • 更大的函数大小,因此您可以达到部署大小限制。
  • 更新功能可能会导致回归并破坏其他一些功能。

如您所见,每种方法都各有利弊,没有唯一正确的做事方式。另外,正如其他答案所建议的,您还需要考虑 CICD、项目和时间限制等问题。

我一直在争论这个问题,并为每个服务选择了单独的 git 存储库,例如 personaccount 等,每个都有自己的 lamba 函数。

这允许我将每个 repo/serverless 项目视为其自己的微服务,并且我使用控制器的 MVC 模式和服务以及每个微服务一个 DAO。

我的管道构建和测试单个存储库,部署然后 运行 对单个存储库进行系统集成测试。

我不喜欢路由器模式的地方是:

  • 功能记录,单个日志流

  • 单点故障

  • 每次更改都会回归

  • 我更喜欢离散的关注点分离

  • 可测试性

  • 你现在需要满足你最饥饿的 lambda,例如它需要 1024mb ram,一个简单的 GET 就可以满足 128mb 或者现在你需要开始 打破你的模式并重构,因为你需要移动函数

  • 我读了几篇文章,它们证明 return 冷启动实际上只适用于未充分利用端点的情况

我使用无服务器插件来预热 lambda,因为路由器模式的唯一真正好处 (imo) 是较少的冷启动。