首页 > 投稿 > 正文内容

Java多线程阻塞问题如何快速定位?实用排查方法与工具推荐

投稿2025-05-28 05:10:20

鍑屾櫒涓夌偣锛岃繍缁寸粡鐞嗚€佸紶鐩潃鎶ヨ澶у睆涓婇绾㈢殑CPU鏇茬嚎锛岃鍗曠郴缁熺殑鍝嶅簲鏃堕棿宸茬粡绐佺牬10绉掋€傝繖宸茬粡鏄湰鏈堢涓夋鍥犵嚎绋嬮樆濉炲紩鍙戠殑鐢熶骇浜嬫晠锛屽洟闃熸柊浜哄皬鐜嬫€ュ緱鐩存尃澶达細"杩欎箞澶氭湇鍔$浉浜掕皟鐢紝鍒板簳鎬庝箞鎻嚭閭d釜鎹h泲鐨勭嚎绋嬶紵" 缁忓巻杩囨暟鍗佹瀹炴垬锛屾垜鎬荤粨鍑鸿繖濂楁帓鏌ュ績娉曘€?/p>


鍦烘櫙涓€锛氭湇鍔$獊鐒?鍋囨"鎬庝箞鍔烇紵

鈥?strong>鈥嬬粡鍏哥幇璞♀€?/strong>鈥?/p>

  • 璇锋眰鍫嗙Н鍦ㄧ洃鎺у浘琛ㄩ噷褰㈡垚"楂樺師"
  • 鏃ュ織鍑虹幇澶ч噺"Timeout waiting for connection"
  • 鏈嶅姟鍣╨oad鍊肩獊鐮翠复鐣岀偣

鈥?strong>鈥嬩笁姝ユ€ユ晳娉曗€?/strong>鈥?/p>

  1. 鈥?strong>鈥嬪揩鐓ф崟鑾封€?/strong>鈥嬶細绔嬪嵆鎵цjstack -l > thread_dump.log
  2. 鈥?strong>鈥嬬姸鎬佽繃婊も€?/strong>鈥嬶細鐢╣rep鏌ユ壘BLOCKED/WATING鐘舵€佺殑绾跨▼
  3. 鈥?strong>鈥嬮攣鍒嗘瀽鈥?/strong>鈥嬶細瀹氫綅鎸佹湁閿佺殑绾跨▼鏍?/li>

涓婁釜鏈堟煇鐗╂祦绯荤粺鍗¢】锛岄€氳繃杩欎釜鍔炴硶鍙戠幇鏄疪edis杩炴帴姹犻厤缃敊璇細

bash澶嶅埗
# 鍒嗘瀽绀轰緥  
cat thread_dump.log | grep -A 30 'BLOCKED'  

鍙戠幇20涓嚎绋嬪崱鍦?code>JedisPool.getResource()锛屾渶缁堟妸鏈€澶х瓑寰呮椂闂翠粠榛樿鍊艰皟鏁翠负3绉掕В鍐抽棶棰樸€?/p>


鍦烘櫙浜岋細鍛ㄦ湡鎬ф€ц兘楠ら檷濡備綍鐮达紵

鈥?strong>鈥嬪吀鍨嬫渚嬧€?/strong>鈥?br/> 鏌愮數鍟嗗钩鍙版瘡澶╀笂鍗?0鐐瑰噯鏃跺嚭鐜?鍒嗛挓鏈嶅姟闄嶇骇锛屾渶缁堝畾浣嶅埌鏄畾鏃朵换鍔$嚎绋嬩笌鏍稿績涓氬姟绾跨▼浜夋姠鏁版嵁搴撻攣銆?/p>

鈥?strong>鈥嬫帓鏌ュ伐鍏风粍鍚堟嫵鈥?/strong>鈥?/p>

  1. 鈥?strong>鈥婣rthas瀹炴椂瑙傛祴鈥?/strong>鈥嬶細thread -n 5鏄剧ず鏈€蹇欑嚎绋?/li>
  2. 鈥?strong>鈥婮Profiler閿佹娴嬧€?/strong>鈥嬶細鏌ョ湅monitor绔炰簤鎺掕
  3. 鈥?strong>鈥婸rometheus瓒嬪娍鍒嗘瀽鈥?/strong>鈥嬶細鍏宠仈绾跨▼鐘舵€佷笌涓氬姟鎸囨爣

鍏抽敭鎿嶄綔瀹炲綍锛?/p>

bash澶嶅埗
# Arthas鏌ョ湅绾跨▼鐘舵€佸垎甯? 
thread --state BLOCKED  
# 杈撳嚭鏄剧ず87%闃诲鍙戠敓鍦∣rderService瀹炰緥  

鍦烘櫙涓夛細鐢熶骇鐜鏃犳硶澶嶇幇鐨勫菇鐏甸樆濉?/h3>

鈥?strong>鈥嬫鎵嬮棶棰樷€?/strong>鈥?br/> 娴嬭瘯鐜杩愯姝e父锛屼笂绾垮悗闅忔満鍑虹幇绾跨▼鎸傝捣銆傚幓骞撮亣鍒拌繃涓€涓寮傛渚嬶細鍙湁鍦ㄦ祦閲忓嘲鍊兼椂锛屾敮浠樻湇鍔$殑绾跨▼浼氬崱鍦ㄦ棩蹇楁墦鍗扮幆鑺傘€?/p>

鈥?strong>鈥嬫鍣ㄥ簱鎺ㄨ崘鈥?/strong>鈥?/p>

  • 鈥?strong>鈥婤Trace鑴氭湰鈥?/strong>鈥嬶細鍔ㄦ€佺洃鎺ч攣鑾峰彇鎯呭喌
  • 鈥?strong>鈥婩light Recorder鈥?/strong>鈥嬶細鎸佺画璁板綍閿佷簨浠?/li>
  • 鈥?strong>鈥嬫櫤鑳芥棩蹇椻€?/strong>鈥嬶細鍦ㄥ叧閿攣鎿嶄綔澶勬鍏ヨ拷韪爣璁?/li>

褰撴椂閫氳繃鑷畾涔夋棩蹇楁爣璁扮牬瑙i毦棰橈細

java澶嶅埗
// 鍦ㄩ攣浠g爜鍧楁坊鍔犺拷韪偣  
log.debug("Acquire lock[{}] by thread {}", lockId, Thread.currentThread().getId());  

閰嶅悎鏃ュ織鍒嗘瀽骞冲彴锛屾渶缁堝彂鐜版槸鏃ュ織缁勪欢寮傛鍐欏叆鏃剁殑閿佺珵浜夈€?/p>


鍦烘櫙鍥涳細鍒嗗竷寮忕幆澧冧笅鐨勮法鏈嶅姟闃诲

鈥?strong>鈥嬪鏉傛儏鍐碘€?/strong>鈥?br/> 寰湇鍔℃灦鏋勪腑锛孉鏈嶅姟鐨勭嚎绋嬪湪绛夊緟B鏈嶅姟鐨勫搷搴旓紝鑰孊鏈嶅姟鍙堝湪绛夊緟C鏈嶅姟銆備粖骞村鐞嗚繃鏈€澶嶆潅鐨勬渚嬫秹鍙?涓湇鍔¢棿鐨勫惊鐜瓑寰呫€?/p>

鈥?strong>鈥嬪叏閾捐矾鎺掓煡鏂规鈥?/strong>鈥?/p>

  1. 鈥?strong>鈥婽raceID璐€氣€?/strong>鈥嬶細閫氳繃鍏ㄩ摼璺拷韪爣璇嗕覆鑱旇姹?/li>
  2. 鈥?strong>鈥嬬嚎绋嬫睜鏌撹壊鈥?/strong>鈥嬶細缁欎笉鍚屼笟鍔$嚎绋嬫睜鎵撴爣绛?/li>
  3. 鈥?strong>鈥嬭秴鏃剁啍鏂€?/strong>鈥嬶細璁剧疆灞傜骇寮忚秴鏃舵帶鍒?/li>

浣跨敤SkyWalking瀹氫綅鍒板崱鐐癸細

[璁㈠崟鏈嶅姟] Waiting on HTTP璇锋眰 鈫?[搴撳瓨鏈嶅姟]  
[搴撳瓨鏈嶅姟] Blocked by DB閿?鈫?[鍒嗗簱涓棿浠禲  

鏈€缁堥€氳繃寮曞叆浜岀骇缂撳瓨鍑忓皯鏁版嵁搴撻攣绔炰簤銆?/p>


瀹炴垬宸ュ叿鏁堣兘鎺掕姒滐紙瀹炴祴鏁版嵁锛?/h3>
宸ュ叿鍚嶇О鍚姩閫熷害绮惧害鐢熶骇渚靛叆鎬?/th>瀛︿範鎴愭湰
jstack鈿★笍0.3绉?/td>楂?/td>鏃?/td>浣?/td>
Arthas鈿★笍2绉?/td>涓珮浣?/td>涓?/td>
JProfiler馃悽20绉?/td>瓒呴珮楂?/td>楂?/td>
async-profiler鈿★笍5绉?/td>楂?/td>涓?/td>涓珮

涓撳绉佹埧閰嶇疆锛堝崈涓囩骇绯荤粺楠岃瘉锛?/h3>

鈥?strong>鈥嬮粍閲戝弬鏁扮粍鍚堚€?/strong>鈥?/p>

properties澶嶅埗
# JVM鐩戞帶澧炲己  
-XX:+UnlockDiagnosticVMOptions  
-XX:+DebugNonSafepoints  
# 寮傛閲囨牱閰嶇疆  
-XX:+UsePerfData  

鈥?strong>鈥嬬嚎绋嬫睜鐩戞帶妯℃澘鈥?/strong>鈥?/p>

java澶嶅埗
ThreadPoolExecutor executor = new ThreadPoolExecutor(  
    鏍稿績绾跨▼鏁?  
    鏈€澶х嚎绋嬫暟,  
    60绉?  
    new TaskQueue(100), // 鏈夌晫闃熷垪  
    new NamedThreadFactory("鏀粯涓氬姟"),  
    new CallerBlocksPolicy() // 鑷畾涔夋嫆缁濈瓥鐣? 
);  

棰犺璁ょ煡鐨勬帓鏌ョ湡鐩?/h3>

琛屼笟璋冩煡鏄剧ず锛?2%鐨勬墍璋?绾跨▼闃诲"闂锛屽叾鏍规簮绔熷湪鍏朵粬灞傞潰锛?/p>

  • 28% 婧愯嚜鏁版嵁搴撹閿佺瓑寰?/li>
  • 15% 鍥犵綉缁滀腑闂翠欢閰嶇疆涓嶅綋
  • 9% 鏄搷浣滅郴缁熸枃浠舵弿杩扮鑰楀敖

涓婂懆澶勭悊鐨勫吀鍨嬫渚嬶細琛ㄩ潰鏄嚎绋嬮樆濉炲憡璀︼紝瀹為檯鏄疜afka娑堣垂鑰呴厤缃簡max.poll.interval.ms=5s锛岃€屼笟鍔″鐞嗛渶瑕?绉掞紝璋冩暣鍙傛暟鍚庨棶棰樻秷澶便€?/p>


閫佺粰鎺掓煡鑰呯殑鍏瓧鐪熻█

鈥?strong>鈥嬬湅鈥?/strong>鈥嬶紙绾跨▼鐘舵€侊級鈫?鈥?strong>鈥嬫煡鈥?/strong>鈥嬶紙鍫嗘爤杞ㄨ抗锛夆啋 鈥?strong>鈥嬫祴鈥?/strong>鈥嬶紙璧勬簮姘翠綅锛夆啋
鈥?strong>鈥嬫瘮鈥?/strong>鈥嬶紙鍘嗗彶鍩虹嚎锛夆啋 鈥?strong>鈥嬫柇鈥?/strong>鈥嬶紙渚濊禆閾捐矾锛夆啋 鈥?strong>鈥嬮槻鈥?/strong>鈥嬶紙閲嶅鍙戠敓锛?/p>

璁颁綇锛氱嚎绋嬮樆濉炲氨鍍忕數璺煭璺紝涓嶄粎瑕佷慨澶嶇啍鏂殑淇濋櫓涓濓紝鏇磋鎵惧埌鑰佸寲鐨勭粷缂樺眰銆傚綋浣犱笅娆¢潰瀵归樆濉炲憡璀︽椂锛屼笉濡ㄥ厛闂笁涓棶棰橈細

  1. 杩欎釜闃诲鏄甯镐繚鎶よ繕鏄紓甯告晠闅滐紵
  2. 闃诲鐐规槸鍚﹀湪鍏抽敭涓氬姟璺緞涓婏紵
  3. 鏈夋病鏈夋洿浼橀泤鐨勯伩璁╂柟妗堬紵

姣曠珶锛屾渶楂樻槑鐨勬晠闅滄帓鏌ヤ笉鏄В鍐抽棶棰橈紝鑰屾槸璁╅棶棰樻牴鏈病鏈夋満浼氬彂鐢熴€?/p>

搜索