发布于 2026-01-06 2 阅读
0

停止使用本地环境开发无服务器应用程序

停止使用本地环境开发无服务器应用程序

我们开发者都希望尽早发现代码中的问题,以便在它正式成为 bug 之前进行修复。因此,我们使用各种工具来尽快在真实环境中运行代码。在本地机器上运行生产环境的副本通常是实现这一目标的最佳方案。但是,Serverless 引入了新的范式,对构建完整的本地环境的必要性提出了质疑。

太长不看

只有当代码完全准备就绪后,才能部署到云端开发环境。为了尽早发现错误代码,测试驱动开发 (TDD)是你的最佳帮手。以下技巧可以使其与 Lambda 函数结合使用,从而更加强大:

  • 使用真实 Lambda 事件的副本作为单元测试和集成测试的输入。
  • 在单元测试中模拟云提供商 SDK
  • 集成测试中,不要模拟真实服务并与之交互。

完全远程环境优化方案

全远程环境优化工作流程

本地开发环境——解决传统架构开发难题

典型的本地环境模式

注意:所有架构均使用 AWS 服务,但本文内容也适用于其他云服务提供商。我个人将其应用于 CGP 和 AWS 无服务器项目。

🤔 本地环境解决了哪些问题?

开发应用时,您需要进行测试,确保它在生产服务器上的运行情况与环境中一致。您可以直接复制生产服务器并进行开发。但如果您的团队由多名开发人员组成,则需要共享开发服务器或复制服务器。第一种方案可能会导致服务器冲突,而第二种方案成本高昂。这两种方案都不具备可扩展性。

此外,您需要良好的网络连接才能与服务器保持同步。因此,您会尝试在每位开发人员的计算机上复制生产服务器,并可能添加一些开发人员工具来提升开发体验:您创建了一些本地环境。每个本地环境都是一个完全独立的环境,其运行方式应尽可能接近生产服务器。

🔄 在本地环境下,开发工作流程是怎样的?

使用本地环境意味着需要进行首次配置。这项工作可能耗时较长,但只需完成一次。之后,您就可以在本地机器上完整地开发和验证功能,从单元测试到端到端测试(手动或自动化)。这些检查可以离线完成,无需等待。功能验证完成后,您可以将其部署到类似生产环境的服务器上进行最终检查。至此,该功能即可投入生产环境使用。

本地环境工作流程

✅️ 什么样的地方环境才能成为良好的发展环境?

一个好的开发环境必须易于所有开发人员安装。许多工具(例如 Docker)的出现是为了简化本地整个环境的安装。

一个好的开发环境也必须与生产环境类似。如果生产服务器上出现问题且无法在本地重现,您有两种选择:

  • 修复本地计算机与服务器之间的行为差​​异。
  • 盲目地根据服务器行为假设来修改代码。

两者都十分痛苦且耗时,但希望在古典建筑中很少发生。当地环境往往靠近生产区域。

开发人员时间宝贵,一个好的开发环境必须快速。本地环境通常会添加一些工具,例如热重载器,以加快开发人员的反馈循环。

每个开发人员都需要一个开发环境,而且这些环境必须成本低廉,以便能够随着团队规模的扩大而扩展。本地环境位于开发人员的计算机上,因此在为开发人员配备所需资源后,无需额外成本。

旧习惯难以改变——无服务器应用程序的本地环境效率低下

无服务器本地环境架构

如果你像大多数开发者一样,一直习惯在本地环境下工作,那么旧习惯很难改变。因此,在面对无服务器项目时,你可能会尝试在自己的机器上复现服务器环境。这样可以让你保持以往的开发工作流程。一旦环境搭建完成,你就可以进行端到端的功能开发和测试。

无服务器本地环境工作流程

💥 完全模拟整个云服务提供商是不可能的

您尝试在本地复制的服务器并非一个只有十几个程序的空 Linux 虚拟机,而是一个完整的云服务提供商。云服务提供商的服务并非设计用于安装在个人电脑上,因此您需要使用模拟服务(这些服务通常由社区维护)。

这些模拟服务本质上并非真正的服务,因此本地环境和云提供商之间存在一些行为差异。例如,serverless-offline模拟的 AWS API Gateway 在本地处理 VTL 的方式与 AWS 的处理方式不同

每次差异导致 bug 时,您都必须修复模拟代码,或者盲目地假设服务的真实行为来修复代码。由于使用了多个服务,风险远高于单体架构。

♻️🤯 基于多服务模拟的环境维护起来简直是噩梦。

此外,由于社区维护的模拟对象通常比由众多开发者开发的最新版本服务更为陈旧,风险也随之增加。一些新服务也可能无法使用

此外,每次项目中使用新服务时,都必须更新本地环境,并且每个开发人员都必须重新配置。这在通常大量使用云服务提供商服务的无服务器项目中并不罕见。

最后,为了长期维护代码库,如果您将常用的服务更新到最新版本,不仅需要确保代码仍然有效,还需要确保服务的模拟对象也已更新并按预期运行。

远程开发环境——开发反馈周期较慢,但能精确复制生产环境。

完整的云环境架构

💡 为什么要使用远程环境?

由于大多数无服务器服务都采用按需付费模式,且云服务提供商支持多种基础设施即代码 (IaC) 工具,因此现在为每个开发人员创建完整的云环境既经济又便捷。这使得开发人员能够在与生产环境完全相同的环境中验证其功能,并且不会遇到开发环境与生产环境之间的任何行为差异。

环境搭建现在已成为部署流程的一部分。您可以通过获取代码、在环境变量中输入您的姓名并进行部署来设置开发人员的环境。

🔄 在远程环境下,最简单的开发工作流程是什么?

要开发一项功能,首先需要在本地编写函数代码,然后使用你喜欢的测试框架进行测试。当你想要验证它与其他服务集成或进行端到端测试时,就需要将其部署到本地。如果出现问题,你需要修复它并重新部署。

完整的云环境工作流程

⚠️ 有什么缺点?

第一次开发就成功的情况很少见。因此,你的功能需要多次部署才能最终上线生产环境。即使与单体部署相比,无服务器部署的时间相对较短(30 秒到 5 分钟),但每天等待十次也会让人感觉时间漫长得多。由于开发人员宁愿修复 bug 也不愿等待,他们可能会选择本地环境部署。

此外,所有离线开发都是不可能的。

两全其美——混合工作流程助您一臂之力

完全远程环境优化方案

🧫 哪些方面可以优化?

比较无服务器本地环境和云环境的缺点,似乎减少等待时间比在本地机器上完美复制整个云提供商更容易。

西 一个 t n T e = n b e r f D e p o e n t s * d e p o e n t T e 等待时间 = 部署次数 * 部署时间

🚀 如何实现混合开发工作流程?

1️⃣ 部署一个空函数,用于记录所有事件

无服务器函数是由事件(例如 HTTP 调用、来自其他服务的消息等)触发的函数。第一步是配置其触发条件,而无需考虑函数本身的功能。这可以通过创建一个空函数来实现。记录函数的输入日志有助于理解事件。

您已部署一次。

2️⃣ 将所有可能的事件复制到本地

该函数本身不执行任何操作,但您可以在功能完成后,使用它应该处理的所有事件来触发它。由于您的函数部署在类似生产环境的环境中,因此您可以使用端到端方式来触发它。获取日志并将所有不同的事件复制到本地,以便稍后重放它们。

3️⃣ 通过测试驱动开发,将功能与实际服务集成

您可以重现真实事件。您可以将这些事件作为输入,用于单元测试或集成测试。这样,您就能轻松地了解每个事件对应的函数行为,从而更高效地开发函数。

你的函数在与其他服务交互时可能会产生副作用。请根据测试结果采取不同的处理方式:

  • 单元测试中:模拟所有云提供商的 SDK 或客户端接口,以检查您的代码是否按预期运行,并假设它使用的所有外部服务。

  • 集成测试中:让应用程序与真实服务交互。这些测试非常强大,因为它能以较短的反馈周期测试生产环境中的行为。

4️⃣ 部署您的功能

您的函数已进行单元测试和与外部环境集成测试。您可以放心部署,并预期端到端验证不会失败。

你只部署了两次。

如果端到端验证失败,您可以复制失败事件并将其添加到事件列表中。这样您就可以在本地重现该事件,从而更轻松地进行调试。

全远程环境优化工作流程

结论——对于无服务器应用程序,请使用混合工作流作为默认开发工作流。

现在您应该明白,开发无服务器应用程序时应该停止使用本地开发环境。您可以为每个开发人员创建一个真正的开发环境。您应该使用测试驱动开发 (TDD) 来克服远程开发环境的缺点。在部署代码之前,您应该同时使用单元测试和集成测试来确保代码能够正常工作。

你目前的开发工作流程是怎样的?有什么技巧可以改进我的工作流程吗?欢迎提出任何反馈意见。

实现集成测试是一项挑战。我专门撰写了一系列关于这个主题的文章:

去看看吧。

文章来源:https://dev.to/slsbytheodo/stop-using-a-local-environment-to-develop-serverless-applications-43a3