探索在桌面上构建和调试服务的挑战。了解如何在基于微服务的应用程序中测试服务的 5 个选项。
服务很棒。它们允许您使用大型开发团队创建大型、复杂的应用程序,而每个团队成员都不需要了解整个应用程序的复杂性。每个开发人员必须只了解他们最终负责的服务。
然而,由于构建基于微服务的生产服务的所有优势,人们很少关注如何测试微服务的复杂性。虽然有很多选择,但在大多数情况下,一种选择很突出。
考虑以下情况:您拥有一个包含 500 个微服务的系统中的微服务 #37。您的服务从一组微服务中获取输入,执行一些操作,并在此过程中使用其他一些微服务。您的服务位于复杂错综复杂的微服务网络中间,如图 1 所示。
图 1. 一个复杂的微服务应用程序
另外,您调用的服务呢?您依靠这些“输出”服务来允许您的服务运行。但是你如何让这些服务发挥作用呢?哦,顺便说一句,这些服务还需要一组其他服务才能运行。你如何让那些工作?
您是否真的必须让所有 500 个微服务在您的笔记本电脑上运行才能验证您的一个微服务是否确实有效?你甚至有可能做到这一点吗?它们都适合您的单台笔记本电脑吗?它们应该适合您的笔记本电脑吗?另外,其他公司提供的外部服务,例如 SaaS 服务呢?您当然不能在您的笔记本电脑上放置另一个 SaaS 服务!
好吧,你有几个选择。哪个选项适合您,这取决于您的服务的规模和复杂性,以及整个应用程序的规模和复杂性,以及您可以使用的工具和服务。这是选项。
选项 #1:将所有服务放在您的笔记本电脑上
第一种选择是采用构成整个应用程序的所有服务并将它们放在您的笔记本电脑上。这可能适用于较小的应用程序,但如果您的应用程序很大或具有大量服务,则此解决方案不会很好地工作。想象一下,必须在您的笔记本电脑上的开发环境中安装、更新和管理 500、1,000 或 5,000 个服务。当其中一项服务发生更改时,您如何对其进行更新?您应该多久更新一次?对于成百上千的服务,您可能必须应用成百上千的更新,以确保这次您正在运行每个服务的生产版本。
这并没有说明所需的资源。你需要多少内存?对 CPU 的要求是什么?大型微服务应用程序可能设计为跨数百台服务器运行。它甚至可以装在一台笔记本电脑上吗?或者您是否会耗尽资源,例如图 2 中显示的可怜用户?
图 2. 在笔记本电脑上测试整个应用程序
选项 #2:开发人员特定的云实例
第二个选项解决了其中一些问题。想象一下,能够单击一个按钮并将应用程序的私有版本部署在只有您可以访问的基于云的沙箱中。此沙盒旨在与您的生产环境完全一样。希望它甚至可以使用相同的 Terraform 配置来创建基础设施并将其全部连接起来,但它将使用更小的云实例和更少的实例,因此运行成本不会那么高。然后,您可以将笔记本电脑上运行的服务链接到此开发人员特定的云设置,并使其看起来像是在生产环境中运行。每个开发人员都有自己的应用程序实例,他们可以将其用于测试目的。如图 3 所示。
图 3. 在开发人员特定的云实例中进行测试
通过适当的自动化和工具,该模型可以避免与设置数千个服务相关的许多复杂性和版本问题。假设您的应用程序运营团队使用自动化的类似 Terraform 的基础架构配置来启动您的生产环境(它确实这样做了,不是吗?),可以将其用作启动生产环境的较小开发克隆的基础为您的开发团队。由于云的魔力,这些类似伪生产的开发环境可以在需要时启动,在不再需要时销毁。您可以根据需要运行尽可能多或尽可能少的这些环境,以促进所有开发人员正在进行的开发和测试操作。这个模型提供了一个很好的,
然而,它仍然不完美。毕竟,虽然您可以自动设置其他服务,但毫无疑问,您必须执行维护以保持其他服务运行。您可能仍会花费更多时间来确保这个庞大的测试工具正在运行,而不是花时间实际测试您的服务。
这种模型确实有很多优点,但它并没有降低在大型微服务应用程序中进行测试所涉及的测试复杂性。
选项 #3:连接到预生产环境
这是与前一个选项非常相似的模型。您在云中设置的类似生产的环境中进行测试。此模型的不同之处在于,所有开发人员都使用一个预生产环境来测试他们的所有服务:它是一个共享环境。这如图 4 所示。
图 4. 使用预生产环境
这种模型降低了测试的复杂性,因为开发人员只需要了解他们的服务是如何工作的。他们不必知道如何保持所有其他服务的运行。
但是,在使用此模型时很有可能测试碰撞。想象一下,如果您正在测试一个服务,而其他人正在测试一个相邻的服务。您可以在测试中做一些影响相邻服务正常运行的事情。您的测试可能会破坏他们的测试。使用此预生产环境的协调变得至关重要、复杂且可能存在问题。
正是由于这个原因,预生产环境主要用于最终集成测试,而不是单独的开发人员测试。仅当您将允许执行的活动类型限制为不影响环境其他用户的活动时,让单个开发人员使用它们进行测试才能有效地工作。当这不可能时,您必须使用不同的选项。
此外,预生产环境还存在数据短缺问题。保持一个充满数据和模拟客户交互的预生产环境,使其看起来和行为都像生产环境,这可能是一项艰巨的任务。由于这些原因,预生产环境通常无法为开发人员测试提供良好的测试平台。
选项 #4:连接到生产环境
这将我们引向下一个选项:将您的服务连接到生产环境以查看它是如何工作的。这似乎具有预生产选项的所有优点,而没有模拟流量的问题。您正在使用真实的实时客户流量在真实的工作生产环境中测试您的服务。
生产测试对于健康的应用程序来说非常重要,因此,在生产环境中进行测试本身并没有错。
但是,将开发人员在其笔记本电脑上运行的未经测试的服务连接到生产应用程序可能非常困难且非常危险。即使他们很小心并确保他们不会执行在生产环境中执行起来太危险的任务,生产的风险仍然很高。此外,促进将笔记本电脑连接到生产环境所需的安全漏洞对于几乎所有现代生产环境来说都是不可接受的安全漏洞。它肯定违反了许多安全最佳实践。
不,将您的笔记本电脑连接到生产环境不是一个好的选择。
选项 #5:使用服务模拟
最后一个选项是使用服务模拟。如果您想在笔记本电脑上测试您的服务,而不是将其连接到服务依赖项的真实副本,请将其连接到这些服务的模拟版本。
对于呼叫您的服务,您创建模拟服务来模拟真实服务将对您进行的相同呼叫。对于您调用的服务,您创建的模拟服务的响应方式与这些服务的响应方式相同。这如图 5 所示。
图 5. 使用服务模拟
请注意,您只需要模拟直接连接到您的服务的服务。环境中不需要包含其他服务。这意味着当您在笔记本电脑上进行开发和测试时,您不需要连接到任何其他外部服务。您所需要的只是模拟与这些服务的连接的服务模拟。这需要更少的资源,因此可以轻松地在您的笔记本电脑开发环境中运行。
此选项具有为第三方服务(例如 SaaS 服务)工作的额外优势。您可以使用 Stripe 服务的模拟版本轻松模拟 Stripe 如何响应信用卡交易,然后您可以直接调用 Stripe 服务。
这也使得测试故障条件变得更加容易。教一个服务模拟发送一个错误的响应比教一个真实的服务生成一个错误的响应要容易得多。
使用服务模拟,您甚至可以模拟负载测试,允许您进行一些有限的负载和扩展测试,甚至在开发环境中进行一些模拟的可用性测试。这意味着您通常可以更好地验证服务的操作。
当然,问题在于创建和维护模拟。服务之间可能有复杂的交互,编写模拟的服务事务有时可能与您尝试模拟的服务本身一样复杂。此外,当其他服务更新和更改其 API 时,您必须不断更新您的模拟以适合您。最后,针对 mock 的测试可以让您针对服务依赖项的响应方式进行测试。它可能会或可能不会以与您期望的方式一致的方式响应。这可能会创建无效的测试场景。
一种解决方案是使用可以为您创建模拟的工具。这样做的一个常见模型是检查真实生产环境中服务之间的流量,然后使用流量作为模板,创建一个模拟相同数据的创建和/或消费的模拟。这允许您使用您的服务,夹在这些自动模拟之间,并验证您的服务是否按预期工作。如果依赖服务更改其 API,您可以简单地重新检查生产服务并创建新模板,更新模拟以匹配。这种方法还增加了服务模拟以与生产服务相同的方式执行的可能性,因为模拟是通过观察生产服务创建的。
这个模型确实需要工具来创建这些模拟。虽然有一些公共领域工具可以为模拟创建提供部分解决方案,但 Speedscale 等工具可以捕获生产流量并将其转化为有用的模拟以用于测试目的。
没有一个正确的答案
不幸的是,对于如何在基于微服务的应用程序中测试服务,没有一个正确的答案。对于小型应用程序,将整个应用程序放在开发笔记本电脑上会更容易。然而,随着应用程序的规模和复杂性的增长,这很快就会变得不合理。根据您的应用程序,这些答案中的任何一个都可能运行良好,也可能根本不起作用。
使用服务模拟似乎具有最好的功能和最少的缺点。如果您可以使用工具——并且获得有用的工具变得越来越容易——从该选项开始,因为它会给你最大的成功可能性。这肯定比针对您的预生产或更糟的是针对您的生产环境进行测试是一个更好的选择。
最后,有兴趣想要学习相关资料的朋友点赞三连+关注后点进我的主页右上角私信(555)即可领取免费资料