读完 RocketMQ 源码,我学会了如何优雅的创建线程

RocketMQ中的线程池是如何创建的? 大家好,我是小郭,今天主要来和大家聊一聊RocketMQ中的线程池是如何创建的,如何设置线程池数量,同时也可以从中去学习到一些线程池的实践和需要注意的一些细节。 阅读详情

RocketMQ 是一款开源的分布式消息系统,基于高可用分布式集群技术,提供低延时、高可靠的消息发布与订阅服务。

这篇文章,笔者整理了 RocketMQ 源码中创建线程的几点技巧,希望大家读完之后,能够有所收获。

1 创建单线程

首先我们先温习下常用的创建单线程的两种方式:

  • 实现 Runnable 接口
  • 继承 Thread 类

▍一、实现 Runnable 接口

图中,MyRunnable 类实现了 Runnable 接口的 run 方法,run 方法中定义具体的任务代码或处理逻辑,而 Runnable 对象是作为线程构造函数的参数。

▍二、 继承 Thread 类

线程实现类直接继承 Thread ,本质上也是实现 Runnable 接口的 run 方法。

2 单线程抽象类

创建单线程的两种方式都很简单,但每次创建线程代码显得有点冗余,于是 RocketMQ 里实现了一个抽象类 ServiceThread 。

我们可以看到抽象类中包含了如下核心方法:

  1. 定义线程名;
  2. 启动线程;
  3. 关闭线程。

下图展示了 RocketMQ 众多的单线程实现类。

实现类的编程模版类似 :

我们仅仅需要继承抽象类,并实现 getServiceName 和 run 方法即可。启动的时候,调用 start 方法 , 关闭的时候调用 shutdown 方法。

3 线程池原理

线程池是一种基于池化思想管理线程的工具,线程池维护着多个线程,等待着监督管理者分配可并发执行的任务。这避免了在处理短时间任务时创建与销毁线程的代价。线程池不仅能够保证内核的充分利用,还能防止过分调度。

JDK 中提供的 ThreadPoolExecutor 类,是我们最常使用的线程池类。

参数名作用
corePoolSize队列没满时,线程最大并发数
maximumPoolSizes队列满后线程能够达到的最大并发数
keepAliveTime空闲线程过多久被回收的时间限制
unitkeepAliveTime 的时间单位
workQueue阻塞的队列类型
threadPoolFactory改变线程的名称、线程组、优先级、守护进程状态
RejectedExecutionHandler超出 maximumPoolSizes + workQueue 时,任务会交给 RejectedExecutionHandler 来处理

任务的调度通过执行 execute 方法完成,方法的核心流程如下:

  1. 如果 workerCount < corePoolSize,创建并启动一个线程来执行新提交的任务。
  2. 如果 workerCount >= corePoolSize,且线程池内的阻塞队列未满,则将任务添加到该阻塞队列中。
  3. 如果 workerCount >= corePoolSize && workerCount < maximumPoolSize,且线程池内的阻塞队列已满,则创建并启动一个线程来执行新提交的任务。
  4. 如果 workerCount >= maximumPoolSize,并且线程池内的阻塞队列已满,则根据拒绝策略来处理该任务,默认的处理方式是直接抛异常。

     

4 线程池封装

在 RocketMQ 里 ,网络请求都会携带命令编码,每种命令映射对应的处理器,而处理器又会注册对应的线程池。

当服务端 Broker 接收到发送消息命令时,都会有单独的线程池 sendMessageExecutor 来处理这种命令请求。

基于 ThreadPoolExecutor 做了一个简单的封装 ,BrokerFixedThreadPoolExecutor 构造函数包含六个核心参数:

  1. 核心线程数和最大线程数相同 ,数量是:cpu 核数和 4 比较后的最小值;
  2. 空闲线程的回收的时间限制,默认 1 分钟;
  3. 发送消息队列,有界队列,默认 10000;
  4. 线程工厂 ThreadFactoryImpl ,定义了线程名前缀:SendMessageThread_ 。

RocketMQ 实现了一个简单的线程工厂:ThreadFactoryImpl,线程工厂可以定义线程名称,以及是否是守护线程 。

开源项目 Cobar ,Xmemcached,Metamorphosis 中都有类似线程工厂的实现 。

5 线程名很重要

线程名很重要,线程名很重要,线程名很重要 ,重要的事情说三遍。

我们看到 RocketMQ 中,无论是单线程抽象类还是多线程的封装都会配置线程名 ,因为通过线程名,非常容易定位问题,从而大大提升解决问题的效率。

定位的媒介常见有两种:日志文件和堆栈记录。

▍一、日志文件

经常处理业务问题的同学,一定都经常与日志打交道。

  • 查看 ERROR 日志,追溯到执行线程, 要是线程池隔离做的好,基本可以判断出哪种业务场景出了问题;
  • 通过查看线程打印的日志,推断线程调度是否正常,比如有的定时任务线程打印了开始,没有打印结束,推论当前线程可能已经挂掉或者阻塞。

▍二、堆栈记录

jstack 是 java 虚拟机自带的一种堆栈跟踪工具 ,主要用来查看 Java 线程的调用堆栈,线程快照包含当前 java 虚拟机内每一条线程正在执行的方法堆栈的集合,可以用来分析线程问题。

jstack -l 进程pid

笔者查看线程堆栈,一般关注如下几点:

  1. 当前 jvm 进程中的线程数量和线程分类是否在预期的范围内;
  2. 系统接口超时或者定时任务停止的异常场景下 ,分析堆栈中是否有锁未释放,或者线程一直等待网络通讯响应;
  3. 分析 jvm 进程中哪个线程占用的 CPU 最高。

6 总结

本文是 RocketMQ 系列文章的开篇,和朋友们简单聊聊 RocketMQ 源码里创建线程的技巧。

  1. 单线程抽象类 ServiceThread

    使用者只需要实现业务逻辑以及定义线程名即可 ,不需要写冗余的代码。

  2. 线程池封装

    适当封装,定义线程工厂,并合理配置线程池参数。

  3. 线程名很重要

    文件日志,堆栈记录配合线程名能大大提升解决问题的效率。

技术人十年成长路径:从写代码到定义问题的三次跃迁 软件工程师的成长,本质是从‘工具使用者’向‘系统构建者’演进的过程。它始于对基础编程能力的掌握,深化于对操作系统、网络、数据库等底层原理的理解,其技术价值在于将抽象知识转化为解决真实故障与业务瓶颈的确定性能力。典型应用场景包括线上事故快速定位、高并发系统权衡设计、跨职能需求本质挖掘等。这一过程高度依赖问题驱动的学习机制、可验证的知识沉淀和面向协作的技术表达——正如文中反复强调的‘画依赖图’‘算经济账’‘给财务讲备份’,正是技术人突破CRUD瓶颈、建立不可替代性的关键跃迁。 阅读详情

相关推荐

SSM框架实现高并发火车票系统:数据库设计与订单状态机实战

在Java Web企业级开发中,数据库设计与并发控制是构建稳定系统的基石。其核心原理在于通过合理的表结构、事务隔离与锁机制来保障数据一致性,尤其在电商、票务等高并发场景下价值凸显。以在线票务系统为例,应用场景要求系统能精准处理余票查询、下单支付及退改签等复杂业务流。本文聚焦于利用SSM(Spring+SpringMVC+MyBatis)框架技术栈,深入探讨如何通过**乐观锁**机制解决库存超卖问题,并设计**订单状态机**来管理订单生命周期的状态流转,从而构建一个健壮、可扩展的火车票预售系统。

weixin_30664615的博客 361

如何在 SpringBoot 项目中控制 RocketMQ消费线程数量

1 背景最近在新项目开发中遇到一个有趣的问题,如何在 SpringBoot 项目中控制 RocketMQ 消费线程数量。如何设置单个 topic 消费线程的最小数量和最大数量,用来区分不同 topic 吞吐量不同。我们先介绍一下 RocketMQ 消息监听再来说明 RocketMQ 消费线程。2 RocketMQ 消息监听设置消费者组为 my_consumer_g...

中生代技术 7420

构建低延迟AI语音对话系统:从流式处理到工程实践全解析

在语音交互和人工智能应用领域,实现流畅自然的实时对话体验是核心技术挑战。其核心原理在于打破传统的串行处理流水线,通过流式处理技术将语音识别、语言理解和语音合成模块并行化,从而将端到端延迟从秒级降低到几百毫秒。这项技术的工程价值在于,它使得AI助手能够更自然地与人交互,提升了智能客服、虚拟伴侣、实时翻译等场景的用户体验。具体实现中,ASR(自动语音识别)模块进行流式识别,LLM(大语言模型)支持流式生成与预测解码,TTS(文本转语音)模块进行流式合成,三者通过一个中央控制面进行智能调度与决策,共同构建出“GP

weixin_33724659的博客 509

全网最全的,RocketMQ全部配置表,一文看懂掌握

前言 RocketMQ对于JAVA程序员来说应该都不陌生,RocketMQ是一款由阿里巴巴开源出来的一款消息中间件,各个大厂基本上都在用的这么一个中间件,其优点自不必言说,所以今天就不给大家来剖析RocketMQ了。 我们来分享点不一样的,相信大家在用RocketMQ时或多或少都会遇到一些问题,而比较常见的就是当其报错或配置一个参数时,往往一些新手就会懵逼这是啥意思呀,不知道如何处理。所以小编在这里整理了一份《RocketMQ全部参数配置表》,帮助大家来更好的使用RocketMQ。 废话不多说直接上干

weixin_51702416的博客 8678

扫地机器人全场景测试实战:从实验室到真实家庭的可靠性验证

本文深入探讨了扫地机器人从实验室到真实家庭的全场景测试方法,揭示了软硬件测试中的关键挑战。通过分析场景化测试的重要性,文章详细介绍了硬件耐久性、软件稳定性和环境适应性三大测试维度,并提供了真实家庭测试的实用方法论。消费者可重点关注清洁率、覆盖率等核心指标,同时了解测试工程师的私房建议,帮助选择更可靠的扫地机器人产品。

hhh00的博客 1077

Ubuntu22.04下3分钟搞定GitHub加速:SwitchHosts+小鱼工具保姆级配置指南

本文提供Ubuntu22.04下快速解决GitHub下载超时问题的保姆级教程,通过SwitchHosts图形化工具和小鱼一键换源工具实现高效加速。详细步骤包括环境准备、工具安装配置及验证方法,帮助开发者轻松优化GitHub访问速度,提升工作效率。

weixin_29258297的博客 564

RocketMQ设置的ConsumeThreadMax无效

问题 RocketMQ设置的ConsumeThreadMax无效,线程数只会达到ConsumeThreadMin值 回答 RocketMQ源码 RocketMQ的线程池是ThreadPoolExecutor,线程池的核心线程数等于mq设置的最小线程数,线程池的最大线程数等于mq设置的最大线程数。 即:ThreadPoolExecutor.corePoolSize == RocketMQ.consumeThreadMin ThreadPoolExecutor.maximumPoolSize.

懒人记录处 6490

图神经网络实战(21)——图神经网络的可解释性

在本节中,我们探讨了应用于图神经网络 (Graph Neural Networks, GNN) 的可解释性人工智能 (Explainable Artificial Intelligence, XAI) 技术。可解释性是许多领域的关键要素,可以帮助我们建立更好的模型。我们介绍了不同的局部解释技术,并重点讨论了 GNNExplainer (基于扰动的方法),在图分类任务中应用 GNNExplainer。

盼小辉丶的博客 9536

六月份校招面试备战:面经拆解、算法攻坚与项目表达全攻略

技术面试考察的从来不只是知识点记忆,而是候选人对原理的理解、表达的结构化以及面对追问时的应变能力。在校招时间窗口里,系统拆解面经比盲目刷题更重要。面经中的追问链与考察路径能还原面试官的思维逻辑,帮助求职者建立精准的知识地图。通过将高频算法题、八股文与项目经历分类整理,并融入模拟实战与复盘迭代,才能把资料真正转化为面试战斗力。六月份正值秋招提前批启动前夕,利用这段时间完成基础复习、项目复盘与限时训练,将大幅提升后续面试的通过率。本文结合70+页校招面经,拆解高效备战方法,覆盖开发、算法、测开等岗位的差异化准备

weixin_34379433的博客 381

JavaScript实现边缘检测Canny(附完整源码)

JavaScript实现边缘检测Canny(附完整源码)

希望我的博客,能帮上你解决学习中工作中所遇到的问题 707

2026年数字IC设计华为笔试带答案解析

这篇文章是一份数字IC设计工程师笔试的试卷结构和部分题目解析。试卷包含单选题31题(每题2分)、多选题10题(每题4分)和简答/编程题4题(每题7分),总分130分,考试时长120分钟。 摘要重点: 试卷涵盖数字IC设计的关键知识点,包括Verilog语法、时序逻辑、状态机设计、跨时钟域处理等; 题目解析详细说明了各选项的正确性,如非阻塞赋值特性(D错误)、功耗影响因素(C与组合逻辑级数弱相关)等; 包含实际工程问题,如DDR4接口电平(SSTL-1.2)、卡诺图变量排序(格雷码)等; 部分题目考察基础概念

Open 369

RocketMQMessageListener 线程池大小

以上代码设置consumeThreadMax = 1 开启一个线程。总感觉rocktMq注解只启动一个线程处理任务,实则不然。打印日志如下,默认最少开启了20个线程。

qq_39763510的博客 1466

数据挖掘7、银行精准营销

利用数据挖掘技术,对银行已有数据进行分析,对客户进行识别,对客户是否能够进行存款精准营销Windows11。

m0_63099685的博客 394

如何确定RocketMQ中消费者的线程大小

随着物联网行业的发展、智能设备数量越来越多,随着设备活跃量过大,常常存在一些高并发的请求,形成了流量尖峰,过多的请求会压垮服务器,影响其他服务运行。因此,为了保护云端服务,需要对请求进行缓冲,`RocketMQ`就是一款非常优秀消息队列的中间件,在互联网领域久经考验,也被各个行业广泛应用。

5453

【小程序抓取】解决痛点:如何用 AI-RPA 工具抓取无法获取 URL 的微信小程序数据?

本文探讨了传统爬虫技术在微信小程序数据采集中的局限性,并提出了AI-RPA(人工智能驱动的机器人流程自动化)这一前沿解决方案。随着微信小程序安全防护体系的全面升级(包括证书锁定、加密传输和三级防御机制),传统"抓包-模拟请求"的方式已基本失效。文章对比了Reqable、Fiddler等主流抓包工具的优劣,通过某程旅行小程序案例展示了传统抓包的技术流程和动态参数处理的难点。最终指出,2026年最有效的解决方案是采用AI-RPA技术,通过视觉识别、鼠标键盘模拟、OCR和AI智能体编排的组合方案,直接从小程序UI

ZDQ58818的博客 124

STM32实战开发(71):STM32人脸识别开发教程:基于摄像头模块的人脸识别系统

在嵌入式系统中,STM32凭借其强大的计算性能、丰富的外设接口以及低功耗特性,成为了实现人脸识别系统的理想平台。STM32虽然没有强大的计算能力,但可以通过合理利用外部硬件加速模块,如DSP、GPU、FPGA等,结合轻量级的人脸识别算法,实现高效的人脸识别系统。尽管STM32的计算资源相对有限,但通过合理的优化和使用高效的算法,我们依然能够实现高效的人脸识别功能。在本项目中,我们使用。在STM32开发中,虽然处理能力有限,但通过优化算法和合理利用硬件加速,我们仍然可以实现一个轻量级的、实时的人脸识别系统。

2201_76125393的博客 1662

从源码分析RocketMQ系列-start()方法详解

导语   在之前的分析中主要介绍的是关于Producer 发送消息的逻辑,但是在实例代码中有一个操作是producer.start()方法,在Consumer中看到的方法是consumer.start(),那么这两个start()方法分别都做了什么样的操作。下面就来看看看这个start()方法为Producer和Consumer分别提供了什么样的操作? 文章目录Producer方面 Produ...

初学者 4476

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

rocketmq 踩坑

主要是有两点: 1: shell脚本启动失败也没有任何日志输出,启动日志不知道 rocketmq 默认的工作目录是root/logs下,找了半天才发现,无语,文档也没有太清楚 2: try to start service thread:AllocateMappedFileService started:false lastThread:null 这个异常处理 找到日志文件就好办了,很明显FileService 是个文件目录异常,(初次启动,生产环境不要这么做)删除broker-a.properti

tomMMMMMMMMMMM的博客 2234

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

RocketMQ - 消费者并发消费:线程池配置与性能调优

RocketMQ 消费者并发消费优化指南 本文深入解析 RocketMQ 消费者并发消费机制,从线程模型到核心参数配置,提供完整的性能调优方案。主要内容包括: 并发消费原理 多线程并行处理消息,显著提升吞吐量(理论可提升20倍) 采用双层线程模型:拉取线程(单线程)与消费线程池分离 关键配置参数 consumeThreadMin/Max:控制线程池规模(建议CPU核数×2起) pullBatchSize:单次拉取消息数(推荐32-256) consumeMessageBatchMaxSize:批量处理消息数

千淘万漉虽辛苦,吹尽狂沙始到金 2万+

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

上一篇: 十年架构师总结(SSM+微服务+Nginx+Redis+MySQL),掌握这些你也是大牛
下一篇: Java | final关键字快速上手【通俗易懂,看这篇就够了】
Java技术那些事儿
博客等级 码龄5年 2306粉丝 2584原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值