溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Java怎么獲取線程狀態(tài)及堆棧信息

發(fā)布時(shí)間:2021-08-24 21:58:48 來(lái)源:億速云 閱讀:951 作者:chen 欄目:大數(shù)據(jù)

本篇內(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)存泄漏的地方

跟蹤線程信息

查看當(dāng)前線程數(shù)量

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)

Java怎么獲取線程狀態(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

jstack生成線程堆棧

當(dāng)服務(wù)cup飆升或者出問題需要從主機(jī)層面定位時(shí)候,使用top -c 命令查看對(duì)應(yīng)哪個(gè)進(jìn)程占用了過高資源

Java怎么獲取線程狀態(tài)及堆棧信息

找到資源占用高的進(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í)用文章!

向AI問一下細(xì)節(jié)

免責(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)容。

AI