您好,登錄后才能下訂單哦!
本篇內(nèi)容介紹了“Java怎么獲取線程狀態(tài)及堆棧信息”的有關(guān)知識(shí),在實(shí)際案例的操作過程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!
出現(xiàn)內(nèi)存泄漏或者運(yùn)行緩慢場(chǎng)景,有時(shí)候無(wú)法直接從業(yè)務(wù)日志看出問題時(shí)候,需要分析jvm內(nèi)存和線程堆棧
線程堆棧信息主要記錄jvm線程在某時(shí)刻線程執(zhí)行情況,分析線程狀態(tài)可以跟蹤到程序出問題的地方 內(nèi)存堆棧信息主要記錄jvm堆中在某時(shí)刻對(duì)象使用情況,主要用于跟蹤是哪個(gè)對(duì)象占用了太多的空間,從而跟蹤導(dǎo)致內(nèi)存泄漏的地方
actuator
1.x
http://host:port/metrics/threads //當(dāng)前進(jìn)程的線程數(shù) http://host:port/metrics/threads.daemon //當(dāng)前進(jìn)程后臺(tái)駐留線程數(shù) http://host:port/metrics/threads.peak //當(dāng)前進(jìn)程線程數(shù)峰值
2.x
http://host:port/actuator/metrics/jvm.threads.daemon //當(dāng)前進(jìn)程后臺(tái)駐留線程數(shù) http://host:port/actuator/metrics/jvm.threads.live //當(dāng)前進(jìn)程的線程數(shù) http://host:port/actuator/metrics/jvm.threads.peak //當(dāng)前進(jìn)程線程數(shù)峰值
hystrix 線程狀態(tài)
如果接入了turbine可以直接通過turbine查看整個(gè)集群狀態(tài)
當(dāng)集群較大的時(shí)候,單純想看hystrix線程池狀態(tài),可以單獨(dú)從hystrix監(jiān)控統(tǒng)計(jì)類里面獲取
http://host:port/sys/hystrix/threads
源碼如下:
import com.alibaba.fastjson.JSON; import com.netflix.hystrix.HystrixThreadPoolMetrics; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.jmx.export.annotation.ManagedResource; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.List; import java.util.stream.Collectors; /** * @author yugj * @date 19/5/5 22:17. */ @RestController @RequestMapping(path = "/sys/hystrix") @ManagedResource(description = "hystrix Endpoint") @EnableScheduling public class HystrixThreadPoolEndpoint { private boolean showStats = false; private static final Logger log = LoggerFactory.getLogger(HystrixThreadPoolEndpoint.class); @GetMapping(value = "/threads") public List<HystrixThreadStats> threadStats() { return HystrixThreadPoolMetrics.getInstances().stream().map((m) -> { final HystrixThreadStats stats = new HystrixThreadStats(); stats.poolName = m.getThreadPoolKey().name(); stats.cumulativeExecuted = m.getCumulativeCountThreadsExecuted(); stats.currentActiveCount = m.getCurrentActiveCount().intValue(); stats.currentCompletedCount = m.getCurrentCompletedTaskCount().intValue(); stats.currentCorePoolSize = m.getCurrentCorePoolSize().intValue(); stats.currentLargestPoolSize = m.getCurrentLargestPoolSize().intValue(); stats.currentMaxPoolSize = m.getCurrentMaximumPoolSize().intValue(); stats.currentPoolSize = m.getCurrentPoolSize().intValue(); stats.currentQueueSize = m.getCurrentQueueSize().intValue(); stats.currentTaskCount = m.getCurrentTaskCount().intValue(); return stats; }).collect(Collectors.toList()); } @GetMapping(value = "/setShowStats") public String setShowStats(Boolean showStats) { if (showStats != null) { this.showStats = showStats; } return "this.show stats:" + this.showStats; } @Scheduled(fixedRate = 5000) public void showStats() { if (showStats) { List<HystrixThreadPoolEndpoint.HystrixThreadStats> statsList = threadStats(); log.info("thread stats :{}", JSON.toJSONString(statsList)); } } class HystrixThreadStats { private String poolName; private Long cumulativeExecuted; private Integer currentActiveCount; private Integer currentCompletedCount; private Integer currentCorePoolSize; private Integer currentLargestPoolSize; private Integer currentMaxPoolSize; private Integer currentPoolSize; private Integer currentQueueSize; private Integer currentTaskCount; public String getPoolName() { return poolName; } public void setPoolName(String poolName) { this.poolName = poolName; } public Long getCumulativeExecuted() { return cumulativeExecuted; } public void setCumulativeExecuted(Long cumulativeExecuted) { this.cumulativeExecuted = cumulativeExecuted; } public Integer getCurrentActiveCount() { return currentActiveCount; } public void setCurrentActiveCount(Integer currentActiveCount) { this.currentActiveCount = currentActiveCount; } public Integer getCurrentCompletedCount() { return currentCompletedCount; } public void setCurrentCompletedCount(Integer currentCompletedCount) { this.currentCompletedCount = currentCompletedCount; } public Integer getCurrentCorePoolSize() { return currentCorePoolSize; } public void setCurrentCorePoolSize(Integer currentCorePoolSize) { this.currentCorePoolSize = currentCorePoolSize; } public Integer getCurrentLargestPoolSize() { return currentLargestPoolSize; } public void setCurrentLargestPoolSize(Integer currentLargestPoolSize) { this.currentLargestPoolSize = currentLargestPoolSize; } public Integer getCurrentMaxPoolSize() { return currentMaxPoolSize; } public void setCurrentMaxPoolSize(Integer currentMaxPoolSize) { this.currentMaxPoolSize = currentMaxPoolSize; } public Integer getCurrentPoolSize() { return currentPoolSize; } public void setCurrentPoolSize(Integer currentPoolSize) { this.currentPoolSize = currentPoolSize; } public Integer getCurrentQueueSize() { return currentQueueSize; } public void setCurrentQueueSize(Integer currentQueueSize) { this.currentQueueSize = currentQueueSize; } public Integer getCurrentTaskCount() { return currentTaskCount; } public void setCurrentTaskCount(Integer currentTaskCount) { this.currentTaskCount = currentTaskCount; } } }
linux
ps huH p {pid}|wc -l
當(dāng)服務(wù)cup飆升或者出問題需要從主機(jī)層面定位時(shí)候,使用top -c 命令查看對(duì)應(yīng)哪個(gè)進(jìn)程占用了過高資源
找到資源占用高的進(jìn)程
明確需要定位的進(jìn)程通過如下命令找到對(duì)應(yīng)的進(jìn)程id
ps aux|grep {application alias}
可以通過如下命令定位具體高load線程:
查詢進(jìn)程具體哪個(gè)線程占用高load top -Hp {進(jìn)程pid} thread id為十六進(jìn)制格式轉(zhuǎn)十六進(jìn)制值 printf %x {線程pid} 指定特定行數(shù)堆棧信息 jstack {進(jìn)程id}|grep -A 200 {線程id}
接下來(lái)通過jstack導(dǎo)出對(duì)應(yīng)的線程堆棧
jstack 對(duì)應(yīng)參數(shù)如下
-m to print both java and native frames (mixed mode)
-l long listing. Prints additional information about locks
服務(wù)器線程相對(duì)較多,文件大小較大,一般不會(huì)考慮在服務(wù)器看,另外這樣查也會(huì)導(dǎo)致忽略了一些統(tǒng)計(jì)信息
通過如下命令導(dǎo)出文件,下載到本地查
jstack -l {pid} >> {dump-file-path}
docker環(huán)境涉及一些權(quán)限,需要進(jìn)入docker執(zhí)行,docker里面進(jìn)程id根據(jù)實(shí)際情況,一般會(huì)聯(lián)系運(yùn)維操作
“Java怎么獲取線程狀態(tài)及堆棧信息”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。