【技术杂谈】关于线程池在生产环境中的使用

欢迎关注公众号(通过文章导读关注:【11来了】),及时收到 AI 前沿项目工具及新技术的推送!

在我后台回复 「资料」 可领取编程高频电子书
在我后台回复「面试」可领取硬核面试笔记

文章导读地址:点击查看文章导读!

感谢你的关注!

技术杂谈

在这里插入图片描述

关于线程池在生产环境中的使用

这里整理了一些线程池在生产环境中使用的建议来帮助我们更好的在项目中使用线程池

一个项目使用一个线程池还是多个线程池?

一般建议是不同的业务使用不同的线程池,从而避免非核心业务对于核心业务的影响

如果所有的业务使用同一个线程池,非核心业务可能执行速度很慢,从而占用了很多线程迟迟不归还,导致核心业务在任务队列中等待,拿不到线程执行

并且还可能造成 死锁问题 ,当父子任务使用同一个线程池时,父任务如果将核心线程全部占用之后,等待子任务完成,由于核心线程没有空闲的,导致子任务进入到任务队列中等待线程资源,导致父子任务之间互相等待

线程池在 RocketMQ 中的使用

在 MQ 中使用了很多线程池,这里说一下在发送消息时使用的线程池:

1、任务队列:创建了 异步发送者线程池任务队列 使用长度为 50000 的阻塞队列

2、线程数:核心线程数最大线程数 相同,为 CPU 核数

3、存活时间:非核心线程存活时间 60s

4、线程名称:重写了线程工厂,主要是 为了线程的命名规范 ,这样在查询日志时,只要做好业务之间的隔离,就可以很容易的根据线程名称来定位到对应的业务,便于分析线上问题

private final ExecutorService defaultAsyncSenderExecutor;private final BlockingQueue<Runnable> asyncSenderThreadPoolQueue;this.asyncSenderThreadPoolQueue = new LinkedBlockingQueue<Runnable>(50000);this.defaultAsyncSenderExecutor = new ThreadPoolExecutor(Runtime.getRuntime().availableProcessors(),Runtime.getRuntime().availableProcessors(),1000 * 60,TimeUnit.MILLISECONDS,this.asyncSenderThreadPoolQueue,new ThreadFactory() {private AtomicInteger threadIndex = new AtomicInteger(0);@Overridepublic Thread newThread(Runnable r) {return new Thread(r, "AsyncSenderExecutor_" + this.threadIndex.incrementAndGet());}});

那么我们在自己的项目中使用的线程池就可以参考 MQ 中的用法,更加规范的使用线程池

至于为什么要这样设置核心线程数,一方面是参考了设置核心线程数的经验(CPU 密集型的任务令线程数等于 CPU 核心数,减少了线程之间的上下文切换,速度比较快),另一方面 RocketMQ 肯定内部经过性能测试,发现这样设置性能比较好一些

关于线程数量的设置

这里参考了美团技术团队中的《Java线程池实现原理及其在美团业务中的实践》

对于线程池的线程数量配置,不同场景下的需求不同,因此对应的数量配置也不同

一般使用线程池的场景无非就两种:

  • 及时性任务 :需要迅速完成,降低用户等待时间
  • 非及时性任务 :批量完成任务,一般是后台任务

那么对于 及时性任务 来说,需要尽可能快的完成任务,因此要 尽可能增大可执行任务的线程数量 ,来尽可能快的完成任务,不要设置任务队列 ,因为只有任务队列满了之后,才会去创建非核心线程执行

对于 非及时性任务 来说,这类人物并不面向用户,特征是任务量很大,需要批量处理,不需要很低的延迟,因此需要设置合适线程数量, 利用有限的资源去尽可能快的执行任务 ,并且设置任务队列去缓冲任务,但是尽量不要使用无界的任务队列,无界队列任务堆积过多会造成 OOM

因此可以发现,在不同场景下,我们可以对参数的配置有一个大概的方向,但是具体配置多少还没有一个通用的公式 ,因此美团技术团队设计了 动态化线程池 ,提供了对线程池的监控以及参数动态调整,这样在调整参数之后,通过监控可以看到整个线程池的负载情况,可以选出比较合适的参数方案

线程池负载的定义

线程池的负载可以根据活跃的线程数和最大线程数的比值来反映

线程池活跃度 = activeCount/maximumPoolSize ,当活跃度升高,代表着线程池负载在逐步上升

还可以 从任务队列中等待的任务数量 或者 发生拒绝策略的次数 来反映

自定义拒绝策略

在线程池中可以 自己去定义拒绝策略 ,如果线程池无法处理更多的任务了,可以在自定义的拒绝策略中,将拒绝的任务 异步持久化 到磁盘中去,之后再通过一个后台线程去定时扫描这些被拒绝的任务,慢慢执行

保证严格的任务不丢失:如果线上机器突然宕机,线程池的阻塞队列中的请求怎么办?

如果宕机,重启之后,线程池阻塞队列中的任务就会全部丢失

如果想要解决这种情况的话,有这么一个 解决方案 :在将任务提交到线程池中去的时候,先把任务在数据库中存储一份,并记录任务执行的状态:未提交、已提交、已完成,执行完之后的话,将任务状态标记为 已完成,如果宕机后,导致任务丢失,就可以去数据库中扫描任务,重新提交给线程池执行

阿里手册中的线程池规范

在使用线程池的时候,需要注意一些规范,以免出现不必要的问题,可以参考阿里巴巴 Java 开发手册,如下:

线程池名称命名规范:

1707126835124

线程池创建规范:

1707126826497

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2815541.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

快讯|Tubi 更新内容库重新定义自己

在每月一期的 Tubi 快讯中&#xff0c;你将全面及时地获取 Tubi 最新发展动态&#xff0c;欢迎&#x1f31f;星标关注【比图科技】&#xff0c;一起成长变强&#xff01; Tubi 更新内容库&#xff0c;重新定义自己 Tubi 近日宣布为数千万用户免费提供备受观众喜爱、获奖无数的…

Python多线程编程:深入理解threading模块及代码实战【第99篇—Multiprocessing模块】

Python多线程编程&#xff1a;深入理解threading模块及代码实战 在Python编程中&#xff0c;多线程是一种常用的并发编程方式&#xff0c;它可以有效地提高程序的执行效率&#xff0c;特别是在处理I/O密集型任务时。Python提供了threading模块&#xff0c;使得多线程编程变得相…

林曦老师的新年礼物,送你三个学习锦囊

暄桐是一间传统美学教育教室&#xff0c;创办于2011年&#xff0c;林曦是创办人和授课老师&#xff0c;教授以书法为主的传统文化和技艺&#xff0c;皆在以书法为起点&#xff0c;亲近中国传统之美&#xff0c;以实践和所得&#xff0c;滋养当下生活。    在暄桐六阶读书课…

每日一题 2673使二叉树所有路径值相等的最小代价

2673. 使二叉树所有路径值相等的最小代价 题目描述&#xff1a; 给你一个整数 n 表示一棵 满二叉树 里面节点的数目&#xff0c;节点编号从 1 到 n 。根节点编号为 1 &#xff0c;树中每个非叶子节点 i 都有两个孩子&#xff0c;分别是左孩子 2 * i 和右孩子 2 * i 1 。 树…

K8S部署postgresql

&#xff08;作者&#xff1a;陈玓玏&#xff09; 一、前置条件 已部署k8s&#xff0c;服务端版本为1.21.14 二、部署postgresql 拉取镜像&#xff0c;docker pull postgres&#xff0c;不指定版本&#xff0c;自动从docker hub拉取最新版本&#xff1b;配置configmap&…

jetson nano——编译安装PySide2

目录 1.打开我提供的文件or官网自己下载&#xff08;需对应PyQt5的版本&#xff09;2.解压文件3.进入目录4.安装clang5. 编译安装6.报错: error: ‘NPY_ARRAY_UPDATEIFCOPY’ was not declared in this scope7.又报错&#xff1a;error: ‘NPY_ARRAY_UPDATEIFCOPY’ was not de…

4-Bean的循环依赖

Bean的循环依赖 循环依赖指的是依赖闭环的问题 解决 首先我们来实例化A&#xff0c;实例化A时并没有处理依赖注入&#xff0c;因此会得到半成品A。有了半成品A&#xff0c;它会被封装成一个ObjectFactory&#xff0c;并且把它放入第三个缓存区singletonFactories中。 接下来要…

Coursera吴恩达机器学习专项课程02:Advanced Learning Algorithms 笔记 Week02

Week 02 of Advanced Learning Algorithms 笔者在2022年7月份取得这门课的证书&#xff0c;现在&#xff08;2024年2月25日&#xff09;才想起来将笔记发布到博客上。 Website: https://www.coursera.org/learn/advanced-learning-algorithms?specializationmachine-learnin…

Dledger部署RocketMQ高可用集群(9节点集群)

文章目录 &#x1f50a;博主介绍&#x1f964;本文内容规划集群准备工作节点0配置&#xff08;ip地址为192.168.80.101的机器&#xff09;节点1配置&#xff08;ip地址为192.168.80.102的机器&#xff09;节点2配置&#xff08;ip地址为192.168.80.103的机器&#xff09;在所有…

动态规划之解码方法【LeetCode】

动态规划之解码方法 91. 解码方法解法1解法2 91. 解码方法 91. 解码方法 解法1 状态表示&#xff08;这是最重要的&#xff09;&#xff1a;dp[i]表示以第i个字符为结尾&#xff0c;解码方法的总数。 状态转移方程&#xff08;最难的&#xff09;&#xff1a;根据最近的一步来…

大模型(LLM)的token学习记录-I

文章目录 基本概念什么是token?如何理解token的长度&#xff1f;使用openai tokenizer 观察token的相关信息open ai的模型 token的特点token如何映射到数值&#xff1f;token级操作&#xff1a;精确地操作文本token 设计的局限性 tokenizationtoken 数量对LLM 的影响训练模型参…

134.乐理基础-音程名字的简写

内容参考于&#xff1a;三分钟音乐社 上一个内容&#xff1a;133.乐理基础-超过八度的音程判断单音程、复音程-CSDN博客 上一个内容里练习的答案&#xff1a; 音程的简写&#xff0c;然后有些练习无限判断隐藏的app&#xff0c;它给的不是大二度、增四度、小六度等等这样的中…

【MySQL】学习多表查询和笛卡尔积 - 副本

](https://img-blog.csdnimg.cn/21dd41dce63a4f2da07b9d879ad0120b.png#pic_center) ??个人主页: ??热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ??个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-N8PeTKG6uLu4bJuM {font-family:“trebuchet ms”,…

同源不同页面之间的通信,SharedWorker使用

同源不同页面之间的通信&#xff0c;SharedWorker使用 描述实现结果 描述 同源不同页面之间的通信&#xff0c;使用SharedWorker&#xff0c;或者使用全局方法通信&#xff0c;这里使用SharedWorker来实现 mdn地址&#xff1a;https://developer.mozilla.org/zh-CN/docs/Web/A…

AUTOMATION 自动化控制

Ansible介绍: 部署ansible:yum -y install ansible 批量管理服务器的工具2015年被红帽公司收购使用Python语言编写的基于ssh进行管理&#xff0c;所以不需要在被管端安装任何软件 ansible在管理远程主机的时候&#xff0c;主要是通过各种模块进行操作的 配置ansible管理环境: …

模型预测控制MPC算法的讲解-案例(C语言代码)

目录 一、模型预测控制MPC的基本原理 1.1 建立模型 1.2 设定目标和约束条件 1.3 求解优化问题 1.4 应用控制输入 1.5 重复优化 二、模型预测控制MPC的特点 三、应用场景 四、应用案例 一个MPC算法的简化版框架&#xff1a; 4.1 案例系统模型 4.2 控制目标和当前状态…

Java中使用Jsoup实现网页内容爬取与Html内容解析并使用EasyExcel实现导出为Excel文件

场景 Pythont通过request以及BeautifulSoup爬取几千条情话&#xff1a; Pythont通过request以及BeautifulSoup爬取几千条情话_爬取情话-CSDN博客 Node-RED中使用html节点爬取HTML网页资料之爬取Node-RED的最新版本&#xff1a; Node-RED中使用html节点爬取HTML网页资料之爬…

链表之“带头双向循环链表”

目录 ​编辑 1.链表的分类 2.带头双向循环链表的实现 1.创建结构体 2.创建返回链表的头节点 3.双向链表销毁 4.双向链表打印 5.双向链表尾插 6.双向链表尾删 7.双向链表头插 8.双向链表头删 9.双向链表查找 10.双向链表在pos的前面进行插入 11.双向链表删除pos位…

蓝桥杯前端Web赛道-课程列表

蓝桥杯前端Web赛道-课程列表 题目链接&#xff1a;0课程列表 - 蓝桥云课 (lanqiao.cn) 题目要求如下&#xff1a; 分析题目我们发现其实就是需要我们手写一个分页的功能&#xff0c;根据题目的要求&#xff0c;分析如下 需要通过axios获取数据每页显示5条数据&#xff0c;默…

【深度学习笔记】深度卷积神经网络——NiN

网络中的网络&#xff08;NiN&#xff09; LeNet、AlexNet和VGG都有一个共同的设计模式&#xff1a;通过一系列的卷积层与汇聚层来提取空间结构特征&#xff1b;然后通过全连接层对特征的表征进行处理。 AlexNet和VGG对LeNet的改进主要在于如何扩大和加深这两个模块。 或者&am…