首页 > 解决方案 > 在 queueCapacity 为 0 的情况下,Spring 引导线程池执行程序休息模板行为正在降低休息 apis 应用程序的性能

问题描述

我遇到了一个奇怪的问题,无法找出其根本原因。这是我的休息模板线程池执行器:

  connectionRequestTimeout: 60000
  connectTimeout: 60000
  socketTimeout: 60000
  responseTimeout: 60000
  connectionpoolmax: 900
  defaultMaxPerRoute: 20
  corePoolSize: 10
  maxPoolSize: 300
  queueCapacity: 0
  keepAliveSeconds: 1
  allowCoreThreadTimeOut: true

1) 我知道 queueCapacity 为 0 线程池执行程序将创建 SynchronusQueue。第一个问题是如果我给它的值正整数值,比如 50,应用程序性能正在下降。根据我的理解,我们应该只在极少数情况下使用 SynchronouseQueue,而不是像我这样的基于 Spring Boot Rest API 的应用程序。

2)第二件事是,我想了解 SynchronousQueue 在部署在服务器(tomcat)上的 Spring Boot Rest API 应用程序中是如何工作的。我知道 SynchronousQueue 的容量为零,因此生产者阻塞,直到消费者可用或创建线程。但是在这种情况下,谁是消费者和生产者,因为所有请求都由 Web 或应用程序服务器提供服务。SynchronousQueue 在这种情况下将如何工作?

我通过在我的机器上运行 JMeter 脚本来检查性能。这个脚本可以处理更多 queueCapacity 为 0 而不是 some > 0 的情况。

我真的很感激任何见解。

标签: spring-bootresttemplatejava.util.concurrentthreadpoolexecutorblockingqueue

解决方案


1)不要显式设置 queueCapacity ,否则势必会降低性能。由于我们限制了可以驻留在队列中的传入请求,并且一旦其中一个线程从固定线程池中可用,它将被占用。

ThreadPoolTask​​Executor 的核心池大小默认配置为 1,最大池大小无限制,队列容量无限制。

https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/scheduling/concurrent/ThreadPoolTask​​Executor.html

2) 在 SynchronousQueue 中,插入和删除操作对总是同时发生,因此队列实际上从不包含任何内容。它将数据同步传递给其他线程,它等待对方取数据而不是仅仅放入数据并返回。

阅读更多:

  1. https://javarevisited.blogspot.com/2014/06/synchronousqueue-example-in-java.html#ixzz6PFz4Akom
  2. https://www.baeldung.com/thread-pool-java-and-guava

我希望我的回答能以一种方式帮助你。


推荐阅读