暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

一个jar实例下多队列多consumer场景下(consumer数量异常)

梧书桐信 2020-12-23
878

背景

1. springboot为:2.1.2.RELEASE

2. 在max-busi-consumer服务的jar包实例下有多个队列的消费者(center-unload-persist、site-send、...)每个队列对应的消费者数有大于1个以上消费者(concurrency > 1)

现象

  • 部分队列的消费者数量未匹配到指定的消费者concurrency值

  • 多次重启后发现缺失消费者数量的总为固定的几个队列的消费者

  • 获取到托管到spring中的bean列表发现,缺失消费者的bean在所有队列消费者最后托管

 定位

1. 查阅资料知道;多个queue的consumer会共用taskExecutor的线程池数量,如果线程池数量不足,consumer无法创建.

2. 观察日志知道在启动jar实例时会打印日志,初始化

org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor|Initializing ExecutorService 'applicationTaskExecutor'

3. 通过查看代码发现

 @Lazy
@Bean(
name = {"applicationTaskExecutor"}
)
@ConditionalOnMissingBean({Executor.class})
public ThreadPoolTaskExecutor applicationTaskExecutor(TaskExecutorBuilder builder) {
return builder.build();
}

ThreadPoolTaskExecutor的bean对象'applicationTaskExecutor'是懒加载到spring中去的;

    3.1 当我们消费者启动生成线程但applicationTaskExecutor未开始工作时,消费者线程池会使用SimpleAsyncTaskExecutor当消费者数量超过SimpleAsyncTaskExecutor限定值则不会创建后托管到spring中的消费者

    3.2 当我们定义的applicationTaskExecutor的poolSize比较小,不能生产出足够多的线程则同样不能创建后托管到spring中的消费者

实践

  1. 在消费者定义中显式指定执行的线程池

  2. 线程池应有富裕的空间满足实例中的线程创建

附录

spring task executor 配置参数:

spring:
task:
execution:
pool:
allow-core-thread-timeout: true #是否允许回收空闲的线程,默认为true
core-size: 8 # 核心线程数,默认为8
keep-alive: 60 #空闲的线程可以保留多少秒,默认为60。如果超过这个时间没有任务调度,则线程会被回收
max-size: 2147483647 # 最大线程数,默认为2147483647
queue-capacity: 2147483647 # 队列容量,默认为2147483647
thread-name-prefix: task- # 线程名前缀,默认为thread-


文章转载自梧书桐信,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论