尝试理解在转移到OkHttpClient时我可以定义的最佳Java ThreadPoolTaskExecutor,延迟明智。目前我们的定义如下:
<property name="corePoolSize" value="#{ T(java.lang.Math).max(32,numCpu) * 2 }" />
<property name="maxPoolSize" value="#{ T(java.lang.Math).max(32,numCpu) * 8 }" />
<property name="queueCapacity" value="200"/>
即最大队列容量(将打开新线程)为200,最小线程数为 max(32,numCpu)* 2 ,最大线程数为 max(32 ,numCpu)* 8 。在我们的例子中, numCpu 可能在16到24之间变化(但如果考虑超线程,那么乘以那个数字* 2,对吧?)。 但是当你考虑它时 - 我不确定这里的线程数应该以某种方式连接到CPU数量。那些是发送/接收HTTP客户端的线程,而不是BusinessLogic线程。因此,CPU数量可能不是偶数因素。
任何意见/建议?
答案 0 :(得分:1)
在我看来,您的线程池正在被用于同时进行大量HTTP连接,这意味着您的性能不受CPU使用率的限制,而是受I / O(以及可能的内存)的限制。 &#34;最佳&#34;线程数将受到许多其他因素的限制......
<强> 1。客户端和端点之间的链接速度。
假设您的客户端已连接到1Gbps链路,但在某个地方,您的所有端点都只能以1Mbps的速度为您提供数据。要最大化本地带宽,您需要同时运行1000个连接以充分利用1Gbps链接,这意味着您的线程池需要运行1000个线程。但是,由于另一个问题,这也可能有问题...
<强> 2。即使他们没有做任何密集的事情,每线程的内存使用量也不为零。
分配给Java的默认堆栈空间量因供应商而异,但大约为1MB。这听起来并不是很多,但是如果你需要运行数千个线程来保持一次活动的客户端连接数,那么你需要为堆栈空间单独分配几千兆字节的RAM。您可以使用-Xss[size]
VM参数调整每个线程分配的堆栈空间,但这对VM来说是全局的,因此缩小堆栈大小可能会导致程序其他区域出现问题,具体取决于您正在执行的操作。 / p>
第3。平均HTTP请求大小。
有时,它会归结为您希望每次POST / GET调用传输多少数据。回想一下,在发送任何数据之前,每个TCP连接都需要初始握手。如果您希望在HTTP调用的整个生命周期内传输的数据量非常小,则可能无法同时运行数千个连接,即使您有数千个线程可供使用。如果金额非常大,则可能只需要几个并发连接即可最大化客户端可用的总带宽。
最后......
如果您的所有端点都在网络上运行,您可能无法预测每个连接的链接速度。我认为您可以做的最好的事情是对不同配置的性能进行基准测试,同时考虑这些因素,并选择似乎在典型操作环境中提供最佳性能的配置。它可能介于N和1000之间,其中N是您运行的核心数,但将该数字固定为特定的数据将需要一点点肘部油脂:)