您好,登錄后才能下訂單哦!
本篇內容介紹了“Java怎么獲取線程狀態及堆棧信息”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
出現內存泄漏或者運行緩慢場景,有時候無法直接從業務日志看出問題時候,需要分析jvm內存和線程堆棧
線程堆棧信息主要記錄jvm線程在某時刻線程執行情況,分析線程狀態可以跟蹤到程序出問題的地方 內存堆棧信息主要記錄jvm堆中在某時刻對象使用情況,主要用于跟蹤是哪個對象占用了太多的空間,從而跟蹤導致內存泄漏的地方
actuator
1.x
http://host:port/metrics/threads //當前進程的線程數 http://host:port/metrics/threads.daemon //當前進程后臺駐留線程數 http://host:port/metrics/threads.peak //當前進程線程數峰值
2.x
http://host:port/actuator/metrics/jvm.threads.daemon //當前進程后臺駐留線程數 http://host:port/actuator/metrics/jvm.threads.live //當前進程的線程數 http://host:port/actuator/metrics/jvm.threads.peak //當前進程線程數峰值
hystrix 線程狀態
如果接入了turbine可以直接通過turbine查看整個集群狀態
當集群較大的時候,單純想看hystrix線程池狀態,可以單獨從hystrix監控統計類里面獲取
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
當服務cup飆升或者出問題需要從主機層面定位時候,使用top -c 命令查看對應哪個進程占用了過高資源
找到資源占用高的進程
明確需要定位的進程通過如下命令找到對應的進程id
ps aux|grep {application alias}
可以通過如下命令定位具體高load線程:
查詢進程具體哪個線程占用高load top -Hp {進程pid} thread id為十六進制格式轉十六進制值 printf %x {線程pid} 指定特定行數堆棧信息 jstack {進程id}|grep -A 200 {線程id}
接下來通過jstack導出對應的線程堆棧
jstack 對應參數如下
-m to print both java and native frames (mixed mode)
-l long listing. Prints additional information about locks
服務器線程相對較多,文件大小較大,一般不會考慮在服務器看,另外這樣查也會導致忽略了一些統計信息
通過如下命令導出文件,下載到本地查
jstack -l {pid} >> {dump-file-path}
docker環境涉及一些權限,需要進入docker執行,docker里面進程id根據實際情況,一般會聯系運維操作
“Java怎么獲取線程狀態及堆棧信息”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。