如何减少微服务架构开发和调试过程中的痛苦/浪费时间?


我们的项目开发了一个单体应用程序。但现在,我们的架构师决定将应用程序分成多个小型服务,称为微服务架构。为了部署服务,我们使用了 kubernetes。

也就是从这时开始,我成了其中一个服务的开发人员,开发工作成了一场噩梦......为了测试我的服务,我需要运行我的服务所依赖的所有服务。就我的服务而言,它只依赖于少数几个服务,这并不是什么大问题,尽管与单体应用程序相比,它需要额外的时间:

但我又遇到了下一个困难:我无法将调试器连接到我的服务。相反,我需要使用跟踪/日志来了解错误或服务错误行为的根本原因。如果应用程序中没有足够的跟踪记录/日志,我就需要添加它们,然后重新构建和部署。

每次修改代码后,我都需要重新部署我的服务,这需要花费一些时间,从而减慢了开发和调试的速度。

当我开发单体应用程序时,使用调试器附加程序不是问题。我可以直接从 vscode 上完成。我无需部署应用程序,只需运行 "使用调试器运行 "即可。

我完全没有浪费时间,很快就完成了任务。

还有另一种方法,那就是使用我的应用程序在开发过程中依赖的服务的模拟。但是,编写一个好的模拟并维护它并不是一件小事,需要花费一些额外的时间。有时,模拟服务的工作方式与原始服务不同,这会导致功能测试中出现额外的错误。当服务相互依赖时,编写一个好的 mock 就会变得更加困难。

看来我需要接受这样一个事实:开发和调试永远不会像单体架构那样容易。

我意识到,由于我们转向了微服务架构,我需要改变我的开发和调试流程。我想了解不依赖于编程语言的一般最佳实践(也许)。但如果编程语言很重要,我们就使用 go。

您能给我指出任何最佳实践吗?如果没有最佳实践,能否请您分享一下您的流程是如何组织的?

我更喜欢在没有任何容器(docker/k8s/minikube 等)的情况下运行我的服务,以避免部署,在这种情况下,我可以很容易地将调试器附加到我的服务上。但在这里,我需要模拟我所依赖的其他服务。这是不是一种错误的方法?

Reddit网友:
1、为什么不能在没有 docker 的情况下运行应用程序?只需正常连接调试器即可。
我知道你们是在 k8s 上运行应用程序,但这只是个开始,并不影响你们在本地运行应用程序。
我有一个在相同配置下运行的 nodejs 和 java 应用程序,它经过 docker 化并部署到了 kubernetes。但在本地,当我们进行开发时,我们在 docker 上运行所有应用程序,而正在开发的应用程序则使用普通的软件包管理器,如 nodejs 使用 yarn,java 使用 maven。

自己动手模拟依赖的微服务可能过于繁琐,只有在管理层给你足够的喘息空间的情况下,我们才会建议你这样做,因为编写和维护这样的测试,所需的时间要比建立一个简单的 docker-compose 文件来启动所有依赖的服务所需的时间长得多。

当然,可以要求邻近的团队为其服务编写模拟程序。自己动手模拟依赖的微服务可能过于繁琐,但如何让模拟变得非常简单呢?例如,他们只需在每次请求时返回成功,并以服务的格式返回我指定的数据。服务有自己的依赖关系,如 hydra、postgresql 等。因此,在这种情况下,服务的依赖关系会消耗我本地 PC 上更多的内存。我需要一个非常小而简单的程序。

2、在我领导的团队中,我们有一个共享开发集群,上面运行着telepresence,以及用于开发部署的相当酷的自动化(Makefiles,ko - https://github.com ) /ko-build/ko - 模板等)。
我们的产品相当大,因此在本地运行整个平台是不切实际的,但我们也有一些 kind/minikube 模板,它们独立运行微服务(所有依赖项和一些模拟数据已经作为配置的一部分进行设置)过程)
稍微不同的方法(我们有时也会使用)是运行启用了远程调试的容器(delve 可以让您这样做),然后将调试端口端口转发到本地计算机,并从 VS Code 将调试器附加到它。
通过这种方法,开发人员可以在环境中使用远程呈现来调试其微服务,同时在本地删除整个依赖链的复杂设置。对我们来说效果很好,所以也许你的工作中也可以有类似的东西。

假设我们有一组相互依赖的服务(注意:这对于我们的设置来说不是正确的词,因为我们倾向于在设计中避免这种依赖关系) :
我们将拥有一组封闭的这些服务(以及一些模拟/模拟数据)在 minikube/kind 集群上运行,并在本地公开调试端口。对于其他场景 - 我们可以有不同的设置。

模拟测试是处理事情的好方法:
我们系统的一部分使用了一个内部模拟器(卡夫卡生产者从磁盘读取 JSON 文件并以适当的时间间隔将它们发送到主题),它基本上尝试复制系统中的常见流量 - 所以这是一种类似的东西。如果您的服务不是事件驱动的(并且您只是使用 REST 或 gRPC 进行通信),您完全可以进行经典模拟

3、你所有的问题都可以用两个词解决:集成测试(它不等于模拟测试)
如何实施?!这取决于...取决于公司堆栈、可能的配置、公司的“愿景”等