ForkJoinPool在生产环境中使用遇到的一个问题

这篇具有很好参考价值的文章主要介绍了ForkJoinPool在生产环境中使用遇到的一个问题。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1、背景

在我们的项目中有这么一个场景,需要消费kafka中的消息,并生成对应的工单数据。早些时候程序运行的好好的,但是有一天,我们升级了容器的配置,结果导致部分消息无法消费。而消费者的代码是使用CompletableFuture.runAsync(() -> {while (true){ ..... }}) 来实现的。
即:

  1. 需要消费Kafka topic的个数: 7个,每个线程消费一个topic
  2. 消费方式:使用线程池异步消费
  3. 消费池:默认的 ForkJoin 线程池???,并且没有做任何配置
  4. 是否会释放线程池中的核心线程: 不会释放
  5. 没出问题时容器配置: 2核4G
  6. 出问题时容器配置:4核8G,影响的结果:只有3个topic的数据可以消费。

2、容器2核4G可以正常消费

ForkJoinPool在生产环境中使用遇到的一个问题

即:此时程序会启动7个线程来进行消费。

3、容器4核8G只有部分可以消费

ForkJoinPool在生产环境中使用遇到的一个问题

即:此时程序会启动3个线程来进行消费。

4、问题原因分析

1、通过上面的背景我们可以知道,是因为升级了容器的配置,才导致我们消费kafka中的消息失败了。
2、针对kafka中的每个topic,我们都会使用一个单独的线程来消费,并且不会释放这个线程。
3、而线程的启动方式是通过CompletableFuture.runAsync()方法来启动的,那么通过这种方式启动的线程,是每个任务一个启动一个线程,还是只启动固定的线程呢?.

通过以上分析,那么问题肯定是出现在线程池身上,那么我们默认使用的是什么线程池呢?查看CompletableFuture.runAsync()的源码可知,有一定的几率是ForkJoinPool。那么我们一起看下源码。

5、源码分析

ForkJoinPool在生产环境中使用遇到的一个问题

1、确认使用什么线程池

public static CompletableFuture<Void> runAsync(Runnable runnable) {
   return asyncRunStage(asyncPool, runnable);
}
private static final Executor asyncPool = useCommonPool ?
        ForkJoinPool.commonPool() : new ThreadPerTaskExecutor();

通过上述源码可知,我们可能使用的ForkJoin线程池,也可能使用的是ThreadPerTaskExecutor线程池。

  1. ThreadPerTaskExecutor 这个是每个任务,一个线程。
  2. ForkJoinPool 那么就需要确定启动了多少个线程。

2、确认是否使用 ForkJoin 线程池

需要确定 useCommonPool 字段是如何赋值的。

private static final boolean useCommonPool =
        (ForkJoinPool.getCommonPoolParallelism() > 1);

通过上面代码可知,是否使用ForkJoin线程池,是由 ForkJoinPool.getCommonPoolParallelism()的值确定的。(即并行度是否大于1,大于则使用ForkJoin线程池)

public static int getCommonPoolParallelism() {
    return commonParallelism;
}

3、commonParallelism 的赋值

ForkJoinPool在生产环境中使用遇到的一个问题

1、从上图中可知parallelism的设置有2种方式

  • 通过Jvm的启动参数java.util.concurrent.ForkJoinPool.common.parallelism进行设置,且这个值最大为 MAX_CAP即32727。
  • 若没有通过Jvm的参数配置,则有2种情况,若cpu的核数<=1,则返回1,否则返回cpu的核数-1

2、commonParallelism的取值

common = java.security.AccessController.doPrivileged
            (new java.security.PrivilegedAction<ForkJoinPool>() {
                public ForkJoinPool run() { return makeCommonPool(); }});
int par = common.config & SMASK; // report 1 even if threads disabled
commonParallelism = par > 0 ? par : 1;

SMASK 的值是 65535。
common.config 的值就是 (parallelism & SMASK) | 0的值,即最大为65535,若parallelism的值为0,则返回0。
int par = common.config & SMASK ,即最大为 65535
commonParallelism = par > 0 ? par : 1 的值就为 parallelism的值或1

6、结论

ForkJoinPool在生产环境中使用遇到的一个问题

结论:
由上面的知识点,我们可以得出,当我们的容器是2核4G时,程序选择的线程池是ThreadPerTaskExecutor,当我们的容器是4核8G时,程序选择的线程池是ForkJoinPool文章来源地址https://www.toymoban.com/news/detail-843009.html

到了这里,关于ForkJoinPool在生产环境中使用遇到的一个问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 遇到了一个跨域问题

    我的前端运行时 所在的端口是  localhost:7000, 后端所在的端口是 localhost:8080 我想 在前端像后端发送请求,获取数据。但是浏览器报错,因为不同源。 因此,解决方案如下: 在 Vue.js 应用程序中,你可以使用代理(Proxy)来解决跨域问题。代理允许你将请求发送到另一个域名

    2024年02月08日
    浏览(25)
  • Vue项目打包问题(生产环境样式失效)

    在公司项目发布上线后,出现了部分样式失效的问题。我们引用的是vuetify第三方库,经过检查,发现是部分样式被vuetify自带的css样式给覆盖,原因是生成环境的打包模式与开发环境不同。 生产模式(env.prod) 在 生产模式 下打包,项目会被最小化,所有的css代码会被提取出

    2024年02月11日
    浏览(77)
  • JVM学习(三)--生产环境的线程问题诊断

    使用top命令 使用ps H -eo pid,tid,%cpu | grep 进程id   (可以具体定位到某个进程的某个线程的cpu占用情况) 使用jstack 进程id |grep 32e4 -A20 (这里32e4就是线程的tid的16进制,A20表示显示前20行)可以找到当前进程的所有线程的具体信息,进而具体的代码行数,但是注意这里显示出来的

    2024年02月09日
    浏览(38)
  • 【JAVA】生产环境kafka重复消费问题记录

    业务系统每周都有定时任务在跑,由于是大任务因此采用分而治之思想将其拆分为多个分片小任务采用 kafka异步队列消费 的形式来减少服务器压力,每个小任务都会调用后台的c++算法,调用完成之后便会回写数据库的成功次数。今天观测到定时任务的分片小任务存在被重复消

    2024年04月12日
    浏览(31)
  • Reactive 环境配置 遇到的问题记录

    问题: Watchman: watchman--no-pretty get-sockname returned with exit code 1 ERROR: Unknown option --no-pretty 解决方案:运行ReactNative工程watchman运行错误 解决过程就是,我的watchman 没安装好,于是卸载,重新安装 brew uninstall watchman brew link pcre (这个我一直提示错误,但是我忽略不管了) brew install

    2024年02月10日
    浏览(31)
  • k8s集群生产环境的问题处理

    2 k8s上的服务均无法访问 执行命令 kubectl get pods -ALL ,k8s集群中的服务均是running状态 1 kuboard 网页无法访问 kuboard无法通过浏览器访问,但是查看端口是被占用的

    2024年02月12日
    浏览(32)
  • 记一个有关 Vuetify 组件遇到的一些问题

    Vuetify 官网地址 所有Vuetify 组件 — Vuetify Combobox 组合框 — Vuetify   items数据使用对象数组时,默认选中的是整个对象,要对数据进行处理   variableList是一个对象数组,设置了item-value无效,需要在数据变化时实时取需要的字段值 Text field 输入框 — Vuetify 要实现下方文本框标题

    2024年01月16日
    浏览(30)
  • 部署Stable diffusion遇到的一个问题解决

    前两天自己在服务器上搞了一下stable diffusion,碰到过一个问题,当时搜了半天没找到好的方法,后来我想了下给解决了,觉得还是来记录一下,如果其他人也正巧遇到的话看到这个可以方便解决,当然,是对于linux环境下来说的,不过我觉得windows应该也一样通用 问题大概是

    2023年04月16日
    浏览(30)
  • ubuntu开发环境搭建遇到问题与解决

    ubuntu与windows可以进行复制粘贴操作: 更新源 ssh安装: samba环境搭建

    2024年02月07日
    浏览(39)
  • Net6中遇到的一个很奇葩的问题

    先来看一段代码,是控制台应用程序 执行,然后在输出窗口得到 没毛病吧。 再来看第二段代码,是winform应用程序 其中Form1为新建的窗体类。除了VS自己生成的代码以外,我一个字符都没改。 执行,然后在输出窗口得到 并且,Form1窗口也没有正常弹出。 显然在第二次调用T

    2024年02月08日
    浏览(26)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包