如何对 Reactive Web API 进行压力测试?

问题描述

我们已将我们的一项微服务从每线程请求模型(同步)迁移/重构为响应式(异步)。开发完成并开始对反应式服务进行压力测试。我们正在寻找有关如何为响应式 API 执行活动的帮助

我们做了什么?

我们的服务对外部服务进行 HTTP 调用。在我们的压力测试中,我们模拟了外部服务调用。我们没有进行网络调用,而是使用 Thread.sleep() 方法引入了延迟,并在我们的服务组件中返回模拟响应(我们在其中对外部服务进行实际 HTTP 调用)。

通过这种方法,我们发现我们的反应式服务在请求量非常小的情况下崩溃。补充一点,我们在测试其他同步服务(每个线程模型的请求)时也遵循类似的方法

接下来我们可以尝试什么?

解决方法

为了让基础设施更接近实时环境,我建议运行单独的模拟服务器,最好在单独的机器上运行,这样它就不会从您的服务中窃取资源。

您可以使用 wiremock 轻松完成 - 请参阅 running as standalone 页面。

当您将 wiremock 作为代理运行时,您可以记录和回放来自您的服务的真实请求。

为了使这个模拟更加真实,您可以add delay for mock responses - 它会模拟外部服务“处理时间”。

,

反应式服务有一个非常小的线程池,经过优化可以达到 100% 的利用率。

如果你引入了像 Thread.sleep() 这样的阻塞,你基本上就是在移除这个能力。什么使反应式,“反应式”是它在阻塞时切换执行线程的能力。

Thread.sleep() 将线程保持在它所在的位置,它无法切换到做其他事情,基本上削弱了它的整个功能。

您永远不应该在反应式应用程序中Thread.sleep(),除非您使用 OnSubscribe 并将每个调用置于单独的调度程序上,这反过来会使您的反应式应用程序“非反应式”,而是回退到默认的标准 servlet 应用程序行为。