使用调度程序时 Tomcat 和 RxJava 之间的线程问题

Enr*_*ina 5 multithreading threadpool rx-java tomcat8 spring-boot

我有一个 Web 应用程序,它只是充当前端控制器,使用 Spring Boot 调用其他远程 REST 服务,我将 Spring 的 DeferredResult 与在 Scheduler.computation() 上订阅的 Observables 结合起来。

我们还使用 JMeter 对 Web 应用程序进行了压力测试,我们注意到当 JMeter 中调度的并发线程数从 25 增加时,请求开始失败,状态为 500,没有响应数据,也没有任何日志,这显然是一个Tomcat 非常“易于管理”的数字。

深入研究使用 VisualVM 来分析线程是如何创建和使用的问题,我们意识到使用 rx.Scheduler 以某种方式影响了 Tomcat NIO 创建的线程数量。让我根据使用的 rx.Scheduler 和 JMeter 中具有 100 个用户(线程)的测试来总结我们的测试:

  1. 调度程序.计算()

当我们使用 Schedulers.computation() 并且我的本地机器有 4 个可用处理器时,那么 4 个 EventLoop 线程池由 RxJava(名为 RxComputationThreadPool-XXX)和仅 10 个 Tomcat(名为 http-nio-8080-exec- XXX),根据 VisualVM:

http://screencast.com/t/7C9La6K4Kt6

  1. SCHEDULERS.IO() / SCHEDULERS.NEWTHREAD()

这个调度器似乎基本上充当了 Scheduler.newThread(),因此在需要时总是会创建一个新线程。同样,我们可以看到许多由 RxJava 创建的线程(名为 RxNewThreadScheduler-XXX),但对于 Tomcat(名为 http-nio-8080-exec-XXX)只有 10 个,根据 VisualVM:

http://screencast.com/t/K7VWhkxci09o

  1. 调度程序.立即()/无调度程序

如果我们禁止在 RxJava 中创建新线程,通过设置 Schedulers.immediate() 或将其从 Observable 中删除,那么我们会看到 Tomcat 线程的预期行为,即 100 http-nio-8080-exec 对应的数字为 JMeter 测试定义的用户数:

http://screencast.com/t/n9TLVZGJ

因此,根据我们的测试,我们很清楚 RxJava 与调度程序和 Tomcat 8 的组合以某种方式限制了 Tomcat 创建的线程数量......我们不知道为什么或如何发生这种情况。

任何帮助将不胜感激,因为到目前为止这阻碍了我们的发展。

提前致谢。