我目前正在使用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次。
我感谢任何建议,谢谢。
最佳解决方案是使您的应用程序适应预期的流量。你可以用很多方式做到这一点:
重要的是移开类似于这个的代码:
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);
}
您选择合理类型的可用池的位置。
在最后一种情况下,您还可以使用弹簧配置文件并在启动应用程序之前进行更改。