使用多个线程池和连接池

问题描述 投票:1回答:1

我目前正在使用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次。

我感谢任何建议,谢谢。

java threadpool connection-pooling
1个回答
0
投票

最佳解决方案是使您的应用程序适应预期的流量。你可以用很多方式做到这一点:

  • 使用微服务架构进行设计,让协调器处理流量峰值
  • 设计应用程序即时读取线程池大小的参数(来自文件中的数据库,来自配置服务器...),以便您可以在需要时更改值
  • 如果您只需要调整应用程序但不需要动态更改值,则将配置放在文件(或数据库)中。检查不同的配置,找到最适合您需求的配置

重要的是移开类似于这个的代码:

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);  
}

您选择合理类型的可用池的位置。

在最后一种情况下,您还可以使用弹簧配置文件并在启动应用程序之前进行更改。

© www.soinside.com 2019 - 2024. All rights reserved.