日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當(dāng)前位置:首頁 > 科技  > 軟件

記一次線程池使用不當(dāng)觸發(fā)死鎖導(dǎo)致RocketMQ消費(fèi)停滯

來源: 責(zé)編: 時(shí)間:2024-09-10 09:51:10 152觀看
導(dǎo)讀背景團(tuán)隊(duì)小伙伴突然找到我們團(tuán)隊(duì)說,不得了了,線上的RocketMQ又出現(xiàn)了消費(fèi)停滯,怎么辦? 要不要我們先重啟一下其實(shí)早在之前也出現(xiàn)過一次,當(dāng)時(shí)為了快速恢復(fù)業(yè)務(wù)的,就直接重啟解決的。這次因?yàn)槎逊e量不多,所以想對(duì)運(yùn)行環(huán)境進(jìn)行

背景

團(tuán)隊(duì)小伙伴突然找到我們團(tuán)隊(duì)說,不得了了,線上的RocketMQ又出現(xiàn)了消費(fèi)停滯,怎么辦? 要不要我們先重啟一下dUs28資訊網(wǎng)——每日最新資訊28at.com

其實(shí)早在之前也出現(xiàn)過一次,當(dāng)時(shí)為了快速恢復(fù)業(yè)務(wù)的,就直接重啟解決的。dUs28資訊網(wǎng)——每日最新資訊28at.com

這次因?yàn)槎逊e量不多,所以想對(duì)運(yùn)行環(huán)境進(jìn)行一些環(huán)境快照保留。所以就和業(yè)務(wù)方溝通是否看見接受短暫的消息延時(shí)dUs28資訊網(wǎng)——每日最新資訊28at.com

得到肯定答案后就是放手干吧!dUs28資訊網(wǎng)——每日最新資訊28at.com

問題定位

首先我們要確定業(yè)務(wù)反饋的是否屬實(shí),所以需要去RocketMQ dashboard上看看具體的消費(fèi)進(jìn)度。dUs28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片dUs28資訊網(wǎng)——每日最新資訊28at.com

可以看到consumer中并不是全部的queue消費(fèi)都堆積了,只有一個(gè)queuq消息堆積了。dUs28資訊網(wǎng)——每日最新資訊28at.com

這個(gè)消費(fèi)者訂閱的topic是分區(qū)有序的,正常來說分區(qū)有序,如果某個(gè)分區(qū)的消息單條消息出現(xiàn)了消費(fèi)異常,必須要等這條消息消費(fèi)成功(或者是重試結(jié)束)后才能繼續(xù)消費(fèi)后面的消息。dUs28資訊網(wǎng)——每日最新資訊28at.com

有時(shí)候會(huì)因?yàn)檫@個(gè)原因出現(xiàn)消息堆積是正常的,但是業(yè)務(wù)對(duì)消息重試進(jìn)行了合理的設(shè)置,設(shè)置的重試次數(shù)比較合理,不會(huì)出現(xiàn)長時(shí)間的堆積。dUs28資訊網(wǎng)——每日最新資訊28at.com

RocketMQ的消費(fèi)線程

一般出現(xiàn)這種問題很明顯就是線程出現(xiàn)了死鎖或者僵死之類的情況。dUs28資訊網(wǎng)——每日最新資訊28at.com

熟悉RocketMQ的都知道RocketMQ消費(fèi)消息主要是依賴1個(gè)線程1個(gè)線程池。dUs28資訊網(wǎng)——每日最新資訊28at.com

  1. 以PullMessageService開頭的線程, 主要用來拉去消息

圖片圖片dUs28資訊網(wǎng)——每日最新資訊28at.com

  1. 以ConsumeMessageThread開頭的線程(實(shí)際是一個(gè)線程池),主要用來執(zhí)行消費(fèi)邏輯。

圖片圖片dUs28資訊網(wǎng)——每日最新資訊28at.com

直到了RocketMQ的消費(fèi)線程模型后我們就好解決了。我們直接通過jstack命令查看線程的堆棧信息。dUs28資訊網(wǎng)——每日最新資訊28at.com

線程快照分析

我們直接通過jstack命令生成線程快照。dUs28資訊網(wǎng)——每日最新資訊28at.com

jstack <pid> > thread_dump_$(date +%Y%m%d_%H%M%S).txt


dUs28資訊網(wǎng)——每日最新資訊28at.com

pid 和后面的 thread_dump_$(date +%Y%m%d_%H%M%S).txt自己隨便取個(gè)名字就行。自己記得就行。dUs28資訊網(wǎng)——每日最新資訊28at.com

由于應(yīng)用運(yùn)行在pod中,生成了我們就下載到本地。dUs28資訊網(wǎng)——每日最新資訊28at.com

我們自己看還是比較難分析出分體。這里我們直接使用一個(gè)在線的網(wǎng)站進(jìn)行線程快照的分析。dUs28資訊網(wǎng)——每日最新資訊28at.com

fastthread

fastthread是一個(gè)在線的線程快照分析工具,可以直接將線程快照上傳到這個(gè)網(wǎng)站進(jìn)行分析。dUs28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片dUs28資訊網(wǎng)——每日最新資訊28at.com

我們上傳我們下載的線程快照文件。dUs28資訊網(wǎng)——每日最新資訊28at.com

然后進(jìn)行線程分析:dUs28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片dUs28資訊網(wǎng)——每日最新資訊28at.com

很快定位到阻塞其他線程的代碼。dUs28資訊網(wǎng)——每日最新資訊28at.com

這里的代碼被我打碼了。dUs28資訊網(wǎng)——每日最新資訊28at.com

arhtas

如果我們使用arthas也可以很方便的找到阻塞的線程。dUs28資訊網(wǎng)——每日最新資訊28at.com

thread -b

arthas 提供了thread -b, 一鍵找出那個(gè)罪魁禍?zhǔn)住?span style="display:none">dUs28資訊網(wǎng)——每日最新資訊28at.com

問題元兇找到

通過阻塞代碼我們很快定位到是由于線程池使用不當(dāng)導(dǎo)致的阻塞。dUs28資訊網(wǎng)——每日最新資訊28at.com

線程池使用不當(dāng)

什么情況下會(huì)出現(xiàn)線程池使用不當(dāng)導(dǎo)致的"死鎖"呢?dUs28資訊網(wǎng)——每日最新資訊28at.com

我們看看下面的demo:dUs28資訊網(wǎng)——每日最新資訊28at.com

public class XiaoZouExample {    public static void main(String[] args) {        ExecutorService executor = new ThreadPoolExecutor(2, 5, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>());        // 提交兩個(gè)外部任務(wù)        for (int i = 0; i < 2; i++) {            executor.submit(new OuterTask(executor));        }        // 等待一段時(shí)間后關(guān)閉線程池        try {            Thread.sleep(10000);        } catch (InterruptedException e) {            e.printStackTrace();        }        executor.shutdown();    }    static class OuterTask implements Runnable {        private final ExecutorService executor;        public OuterTask(ExecutorService executor) {            this.executor = executor;        }        @Override        public void run() {            System.out.println("小奏技術(shù) Outer task started by thread: " + Thread.currentThread().getName());            // 創(chuàng)建一個(gè)Future來等待內(nèi)部任務(wù)的結(jié)果            Future<?> future = executor.submit(new InnerTask());            try {                // 等待內(nèi)部任務(wù)完成                future.get();            } catch (InterruptedException | ExecutionException e) {                e.printStackTrace();            }            System.out.println("小奏技術(shù) Outer task finished by thread: " + Thread.currentThread().getName());        }    }    static class InnerTask implements Runnable {        @Override        public void run() {            System.out.println("小奏技術(shù) Inner task started by thread: " + Thread.currentThread().getName());            try {                // 模擬長時(shí)間運(yùn)行的任務(wù)                Thread.sleep(5000);            } catch (InterruptedException e) {                e.printStackTrace();            }            System.out.println("小奏技術(shù) Inner task finished by thread: " + Thread.currentThread().getName());        }    }}
  • 運(yùn)行結(jié)果

圖片圖片dUs28資訊網(wǎng)——每日最新資訊28at.com

可以看到?jīng)]有任何任務(wù)執(zhí)行完成,線程池一直處于被阻塞狀態(tài)。dUs28資訊網(wǎng)——每日最新資訊28at.com

核心原因就是首先線程池的核心線程數(shù)是2,核心線程用來執(zhí)行2個(gè)任務(wù),用完了所有線程。dUs28資訊網(wǎng)——每日最新資訊28at.com

然后在核心線程執(zhí)行的2個(gè)任務(wù)中又用原來的線程池進(jìn)行執(zhí)行任務(wù),這時(shí)候因?yàn)闆]有線程可以去執(zhí)行任務(wù)了,所以會(huì)添加到阻塞隊(duì)列中等待核心線程執(zhí)行完任務(wù)后再執(zhí)行。dUs28資訊網(wǎng)——每日最新資訊28at.com

但是核心線程想要釋放任務(wù)又必須等待這兩個(gè)子任務(wù)執(zhí)行完,這樣就形成了一個(gè)死鎖。dUs28資訊網(wǎng)——每日最新資訊28at.com

解決方案

解決方式有多種,最簡單的方式可以考慮不要使用隊(duì)列,直接使用SynchronousQueue。dUs28資訊網(wǎng)——每日最新資訊28at.com

ExecutorService executor = new ThreadPoolExecutor(2, 5, 0L, TimeUnit.MILLISECONDS, new SynchronousQueue<>());

讓多的任務(wù)直接通過主線程執(zhí)行或者丟棄任務(wù)。dUs28資訊網(wǎng)——每日最新資訊28at.com

當(dāng)然最好的方式就是避免這種情況的發(fā)生,合理的使用線程池,不要線程池中的任務(wù)還要使用這個(gè)線程池去執(zhí)行任務(wù)。dUs28資訊網(wǎng)——每日最新資訊28at.com

這種情況是比較難避免的,因?yàn)楝F(xiàn)在大部分業(yè)務(wù)開發(fā)都是隱式使用線程池,自己也不知道自己用的哪個(gè)線程池。dUs28資訊網(wǎng)——每日最新資訊28at.com

比如spring的@Async注解,@Scheduled注解等等。dUs28資訊網(wǎng)——每日最新資訊28at.com

總結(jié)

線程池的使用還是要盡量消息,要避免出現(xiàn)線程池中的任務(wù)繼續(xù)使用該線程池去執(zhí)行任務(wù),出現(xiàn)死鎖。dUs28資訊網(wǎng)——每日最新資訊28at.com

也可以考慮對(duì)線程池進(jìn)行監(jiān)控,避免出現(xiàn)大量任務(wù)阻塞。dUs28資訊網(wǎng)——每日最新資訊28at.com

這個(gè)問題想要復(fù)現(xiàn)需要大量任務(wù)并且超過核心線程數(shù)才能復(fù)現(xiàn),還是比較難復(fù)現(xiàn)的,只有線上大流量的時(shí)候才能復(fù)現(xiàn)。dUs28資訊網(wǎng)——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-112791-0.html記一次線程池使用不當(dāng)觸發(fā)死鎖導(dǎo)致RocketMQ消費(fèi)停滯

聲明:本網(wǎng)頁內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問題請及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。郵件:2376512515@qq.com

上一篇: 深入理解 Babel - 微內(nèi)核架構(gòu)與 ECMAScript 標(biāo)準(zhǔn)化

下一篇: 我嘗試重現(xiàn) React 的 useState() Hook 并失去了工作機(jī)會(huì)

標(biāo)簽:
  • 熱門焦點(diǎn)
  • MIX Fold3包裝盒泄露 新機(jī)本月登場

    小米的全新折疊屏旗艦MIX Fold3將于本月發(fā)布,近日該機(jī)的真機(jī)包裝盒在網(wǎng)上泄露。從圖上來看,新的MIX Fold3包裝盒在外觀設(shè)計(jì)方面延續(xù)了之前的方案,變化不大,這也是目前小米旗艦
  • 7月安卓手機(jī)性價(jià)比榜:努比亞+紅魔兩款新機(jī)入榜

    7月登場的新機(jī)有努比亞Z50S Pro和紅魔8S Pro,除了三星之外目前唯二的兩款搭載超頻版驍龍8Gen2處理器的產(chǎn)品,而且努比亞和紅魔也一貫有著不錯(cuò)的性價(jià)比,所以在本次的性價(jià)比榜單
  • 6月安卓手機(jī)性能榜:vivo/iQOO霸占旗艦排行榜前三

    2023年上半年已經(jīng)正式過去了,我們也迎來了安兔兔V10版本,在新的驍龍8Gen3和天璣9300發(fā)布之前,性能榜的榜單大體會(huì)以驍龍8Gen2和天璣9200+為主,至于那顆3.36GHz的驍龍8Gen2領(lǐng)先
  • Rust中的高吞吐量流處理

    作者 | Noz編譯 | 王瑞平本篇文章主要介紹了Rust中流處理的概念、方法和優(yōu)化。作者不僅介紹了流處理的基本概念以及Rust中常用的流處理庫,還使用這些庫實(shí)現(xiàn)了一個(gè)流處理程序
  • 得物效率前端微應(yīng)用推進(jìn)過程與思考

    一、背景效率工程隨著業(yè)務(wù)的發(fā)展,組織規(guī)模的擴(kuò)大,越來越多的企業(yè)開始意識(shí)到協(xié)作效率對(duì)于企業(yè)團(tuán)隊(duì)的重要性,甚至是決定其在某個(gè)行業(yè)競爭中突圍的關(guān)鍵,是企業(yè)長久生存的根本。得物
  • 重估百度丨“晚熟”的百度云,能等到春天嗎?

    &copy;自象限原創(chuàng)作者|程心排版|王喻可2016年7月13日,百度云計(jì)算戰(zhàn)略發(fā)布會(huì)在北京舉行,宣告著百度智能云的正式啟程。彼時(shí)的會(huì)場座無虛席,甚至排隊(duì)排到了門外,在場的所有人幾乎都
  • 當(dāng)家的盒馬,加速謀生

    來源 | 價(jià)值星球Planet作者 | 歸去來自己&ldquo;當(dāng)家&rdquo;的盒馬,開始加速謀生了。據(jù)盒馬官微消息,盒馬計(jì)劃今年開放生鮮供應(yīng)鏈,將其生鮮商品送往食堂。目前,盒馬在上海已經(jīng)與
  • 國行版三星Galaxy Z Fold5/Z Flip5發(fā)布 售價(jià)7499元起

    2023年8月3日,三星電子舉行Galaxy新品中國發(fā)布會(huì),正式在國內(nèi)推出了新一代折疊屏智能手機(jī)三星Galaxy Z Fold5與Galaxy Z Flip5,以及三星Galaxy Tab S9
  • 微軟發(fā)布Windows 11新版 引入全新任務(wù)欄狀態(tài)

    近日,微軟發(fā)布了Windows 11新版,而Build 22563更新主要引入了幾周前曝光的平板模式任務(wù)欄等,系統(tǒng)更流暢了。更新中,Windows 11加入了專門針對(duì)平板優(yōu)化的任務(wù)欄
Top 主站蜘蛛池模板: 远安县| 桃园市| 监利县| 上蔡县| 白城市| 正蓝旗| 泗水县| 淮阳县| 信宜市| 沙洋县| 竹溪县| 大港区| 金阳县| 原阳县| 迁西县| 郯城县| 桐庐县| 天峨县| 贺兰县| 卓资县| 留坝县| 甘孜| 开封市| 平阴县| 罗平县| 云南省| 邢台县| 军事| 庆安县| 方正县| 济南市| 新竹县| 离岛区| 饶平县| 浏阳市| 阳曲县| 图木舒克市| 舞阳县| 鄂尔多斯市| 阿尔山市| 义乌市|