
嘻道奇闻
- 文章199742
- 阅读14625734
Java多线程阻塞问题如何快速定位?实用排查方法与工具推荐
鍑屾櫒涓夌偣锛岃繍缁寸粡鐞嗚€佸紶鐩潃鎶ヨ澶у睆涓婇绾㈢殑CPU鏇茬嚎锛岃鍗曠郴缁熺殑鍝嶅簲鏃堕棿宸茬粡绐佺牬10绉掋€傝繖宸茬粡鏄湰鏈堢涓夋鍥犵嚎绋嬮樆濉炲紩鍙戠殑鐢熶骇浜嬫晠锛屽洟闃熸柊浜哄皬鐜嬫€ュ緱鐩存尃澶达細"杩欎箞澶氭湇鍔$浉浜掕皟鐢紝鍒板簳鎬庝箞鎻嚭閭d釜鎹h泲鐨勭嚎绋嬶紵" 缁忓巻杩囨暟鍗佹瀹炴垬锛屾垜鎬荤粨鍑鸿繖濂楁帓鏌ュ績娉曘€?/p>
鍦烘櫙涓€锛氭湇鍔$獊鐒?鍋囨"鎬庝箞鍔烇紵
鈥?strong>鈥嬬粡鍏哥幇璞♀€?/strong>鈥?/p>
- 璇锋眰鍫嗙Н鍦ㄧ洃鎺у浘琛ㄩ噷褰㈡垚"楂樺師"
- 鏃ュ織鍑虹幇澶ч噺"Timeout waiting for connection"
- 鏈嶅姟鍣╨oad鍊肩獊鐮翠复鐣岀偣
鈥?strong>鈥嬩笁姝ユ€ユ晳娉曗€?/strong>鈥?/p>
- 鈥?strong>鈥嬪揩鐓ф崟鑾封€?/strong>鈥嬶細绔嬪嵆鎵ц
jstack -l
> thread_dump.log - 鈥?strong>鈥嬬姸鎬佽繃婊も€?/strong>鈥嬶細鐢╣rep鏌ユ壘BLOCKED/WATING鐘舵€佺殑绾跨▼
- 鈥?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>
- 鈥?strong>鈥婣rthas瀹炴椂瑙傛祴鈥?/strong>鈥嬶細
thread -n 5
鏄剧ず鏈€蹇欑嚎绋?/li> - 鈥?strong>鈥婮Profiler閿佹娴嬧€?/strong>鈥嬶細鏌ョ湅monitor绔炰簤鎺掕
- 鈥?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>
- 鈥?strong>鈥婽raceID璐€氣€?/strong>鈥嬶細閫氳繃鍏ㄩ摼璺拷韪爣璇嗕覆鑱旇姹?/li>
- 鈥?strong>鈥嬬嚎绋嬫睜鏌撹壊鈥?/strong>鈥嬶細缁欎笉鍚屼笟鍔$嚎绋嬫睜鎵撴爣绛?/li>
- 鈥?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>
璁颁綇锛氱嚎绋嬮樆濉炲氨鍍忕數璺煭璺紝涓嶄粎瑕佷慨澶嶇啍鏂殑淇濋櫓涓濓紝鏇磋鎵惧埌鑰佸寲鐨勭粷缂樺眰銆傚綋浣犱笅娆¢潰瀵归樆濉炲憡璀︽椂锛屼笉濡ㄥ厛闂笁涓棶棰橈細
- 杩欎釜闃诲鏄甯镐繚鎶よ繕鏄紓甯告晠闅滐紵
- 闃诲鐐规槸鍚﹀湪鍏抽敭涓氬姟璺緞涓婏紵
- 鏈夋病鏈夋洿浼橀泤鐨勯伩璁╂柟妗堬紵
姣曠珶锛屾渶楂樻槑鐨勬晠闅滄帓鏌ヤ笉鏄В鍐抽棶棰橈紝鑰屾槸璁╅棶棰樻牴鏈病鏈夋満浼氬彂鐢熴€?/p>