2017-05-09 46 views
3

这可能是更一般的问题,关于如何决定线程池的大小,但让我们使用Spring ThreadPoolTaskExecutor这种情况。对于池核心和最大大小以及队列容量,我有以下配置。我已经阅读了所有这些配置的含义 - 有一个很好的答案here如何决定ThreadPoolTask​​Executor池和队列大小?

@SpringBootApplication 
    @EnableAsync 
    public class MySpringBootApp { 

     public static void main(String[] args) { 
      ApplicationContext ctx = SpringApplication.run(MySpringBootApp.class, args); 
     } 

     @Bean 
     public TaskExecutor taskExecutor() { 
      ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); 
      executor.setCorePoolSize(5); 
      executor.setMaxPoolSize(10); 
      executor.setQueueCapacity(25); 
      return executor; 
     } 

    } 

上述数字对我来说是随机的,我想了解如何根据我的环境正确设置它们。我将概述如下约束,我有:

  1. 应用程序将在双核CPU箱
  2. 执行人将在这通常需要大约1-2 秒完成任务的工作运行。
  3. 通常我想到800/min的任务提交给我的遗嘱执行人,在2500 /分钟
  4. 任务将构建一些对象,使一个HTTP调用谷歌发布订阅扣球。

理想情况下,我想了解我需要考虑,并根据他们什么将是我的游泳池和队列大小进行合理的配置还有什么其他的限制。

+0

您预计在任何特定时刻您会排队提交多少任务?即提交到您的游泳池的任务的速度是多少?无论如何,我会建议你阅读https://www.infoq.com/articles/Java-Thread-Pool-Performance-Tinging – Sneh

+0

@Sneh通常约800 /分钟,但在高峰时间可能会达到2500 /分钟! –

+0

可能需要补充说明的是,应用程序有两个应用程序可以处理这个负载,这两个应用程序都在2核CPU的机器上运行。 –

回答

4

它可能不是最准确的答案,但我会尝试:

一个简单的方法就是要了解你的2核CPU将在两个线程在同一时间只工作。

如果你有比较现代英特尔 CPU,你有超线程(又名。HT(TM),HTT(TM),SMT)开启(通过在BIOS中设置),您的操作系统会将可用内核的数量看作是CPU内物理内核数量的两倍。

无论哪种方式,从Java到检测多少个核心(或同时不-抢占对方线程),你可以工作,只是叫int cores = Runtime.getRuntime().availableProcessors();

如果你尝试看看你的应用程序作为车间(一实际的):

  • 处理器将由雇员代表。这是能够为产品增值的物理单位。
  • 一项任务将是一块原材料(加上一些说明列表)
  • 您的线程是员工可以将任务投入工作的桌子。
  • 队列大小是将原材料带到桌面上的传送带的长度。

因此,你的问题就变成了“如何选择多少书桌和多久能我的输送带是我厂里面,给员工一个不变的数?”。

对于有多少课桌(主题)部分:

雇员可以在一个办公桌只能工作在一个时间,你只能有每个桌子一个员工。因此,基本的设置将有至少尽可能多的座位,你的员工(以避免遗漏而导致无法正常工作的任何员工(处理器)。

,这取决于你的活动,你可能提供每名员工更书桌:

如果你的员工都有望出台邮件里面enveloppes不断,需要充分注意的操作(在编程:分类收集,创建对象,增加柜台),有更多的课桌止跌”牛逼的帮助,甚至可能是有害的,因为你的员工将不得不 有时变化服务台(切换合作NTEXT,这需要一些时间),从而留下他们工作的一个,以使在其他工作的进展情况。

但是,如果你的任务是制作陶器,并且依赖于你的员工等待粘土在烤箱中烹饪(了解获得访问外部资源,如文件系统,网络服务等),您的员工可以承担在另一张桌子上放置模型粘土并在稍后返回到第一个桌面。

因此,只要您的任务具有足够大的活动工作/等待比率(运行/等待),您就可以为每位员工支付更多的办公桌。而办公桌的数量是您的员工在等待期间可以完成多少任务。

对于传送带(队列)尺寸部分:

队列大小代表您允许多少项目开始拒绝任何更多的任务(通过抛出异常)之前进行排队,从而处于你开始说“OK,我已供不应求,并不会永远能够遵守”

一是门槛,我会说你的传送带需要适应车间内。这意味着集合应该足够小以防止内存不足错误(显然)。

之后,它是根据你公司的政策。让我们假设一个任务添加到皮带每一个客户端发出的命令(另一个服务调用你的API)时间。如果打电话的人不关心你在执行时花了多少时间来遵守和信任你,那么限制腰带的尺寸就没有意义。

但是,如果你可以预期你的客户在等待他们的陶器一个月后会感到恼火,并且让你同时或重新订购另一个陶器,假设第一个订单丢失了并且不会被打扰检查是否第一个订单完成......这一级是白做了,你不会得到所许的,如果您的客户端发出,只要你遵守太慢了另一份订单,你会因为每一个新的反馈环路进入秩序会放慢整个过程。

因此,在这种情况下,您应该为您的客户贴上一个标语,“对不起,我们超额预订了,您现在不应该做任何新订单,因为我们无法在可接受的时间内遵守范围”。

然后,队列大小将为:可接受的时间范围/时间完成任务

具体示例:如果客户端服务期望它提交的任务必须在不到100秒内完成,并且知道每个任务需要1-2秒,则应该将队列限制为50-100个任务,因为一旦有100个任务在队列中等待,你很确定下一个任务不会在不到100秒内完成,因此拒绝任务以防止服务等待。

+0

嗨,杰里米,谢谢你的回答。该任务将根据请求构建一些对象并致电Google pubsub。 –

+0

API调用是一个等待操作,因此您可以在理论上支付两个以上的线程,但如果没有基准测试,我无法给出适当的数字。我建议使用任意数量的任务运行测试,同时逐步增加池大小(从2开始),直到您无法再观察性能改进。 –

相关问题