我目前正在使用5个线程池,我希望找到这些池的最佳大小。这是某种先验分析。池按用法划分:用于处理命令(cmdPool)、处理库存事务(invPool)、用于数据库事务的池(dbPool)、用于只需运行异步(如I/O (fastPool) )和调度任务(timerPool)的常见事物的池。我还没有任何可以用来解决问题的统计数据。
对于数据库查询,我使用的是带有默认值的HikariCP。稍后,我将尝试更改最大连接和最小空闲连接的计数,以找到最佳性能。但就目前而言,当使用Hikari池时,将始终从其中一个池调用它,以不影响主线程。通常的数据库查询是在dbPool下调用的,但只有在代码块不是已运行的子线程池的一部分时才调用。
实际的设置看起来,它只在应用程序中工作。所以我的问题是:
1.)当我决定停止使用cachedThreadPool并使用一些最小空闲线程(如timerPool )或我应该坚持缓存的池时,性能和资源会受到什么影响?
2.)是正确的解决方案,设置一个最大的池大小,以防止尖峰时,像100个客户端将加入在较短的时间内,让他们继续等待一些时间,而其他任务将完成。
3.)是否有更好的解决方案,如何管理各种任务?
cmdPool = Executors.newFixedThreadPool(3);
invPool = Executors.newFixedThreadPool(2);
dbPool = Executors.newCachedThreadPool();
fastPool = Executors.newCachedThreadPool();
timerPool = new ScheduledThreadPoolExecutor(5);
timerPool.allowCoreThreadTimeOut(true);
timerPool.setKeepAliveTime(3, TimeUnit.MINUTES); 所以首先,每个动作都取决于连接了多少个客户端,让我们假设5-25个客户端的值。池的设计应该是为了维护甚至极端的情况,比如100个客户机,而不是在很短的时间内产生太多的线程。
预期的用途可能会有所不同,而且每秒钟都不一样,甚至可能发生,根本就不会有任何任务来运行。cmdPool的预期使用量相当于每秒3-8次使用(轻量级任务)。对于invPool来说,使用几乎与cmdPool相同,每秒使用2-6次(也是轻量级任务)。至于dbPool,这比所有其他任务都更不可预测,但仍然预期的使用量是每秒5-20次(轻量级和中等重量的任务),这也取决于网络的繁忙程度。计时器和快速池被设计成可以接受任何类型的任务,只需完成它,预计每秒使用20-50次。
我感谢你的建议,谢谢。
发布于 2019-02-13 13:41:54
最好的解决方案是使应用程序适应预期的通信量。你可以通过多种方式做到这一点:
重要的是移除与此类似的代码:
cmdPool = Executors.newFixedThreadPool(3);并将其替换为类似于此的代码
@Value("${cmdPoolSize}")
private int cmdPoolSize;
...
cmdPool = Executors.newFixedThreadPool(cmdPoolSize);在中,池的大小不是从代码中获取的,而是从外部配置获取的。
另一种更好的方法是定义具有参数的池类型:
@Value("${cmdPoolType}")
private String cmtPoolType;
@Value("${cmdPoolSize}")
private int cmdPoolSize;
...
if (cmdPoolType.equals("cached")) {
cmdPool = Executors.newCachedThreadPool();
} else if (cmdPoolType.equals("fixed")) {
cmdPool = Executors.newFixedThreadPool(cmdPoolSize);
}选择合理类型的可用池。
在最后一种情况下,您还可以使用spring配置文件,并在启动应用程序之前对其进行更改。
https://stackoverflow.com/questions/54671188
复制相似问题