最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java獲取服務(wù)器狀態(tài)之CPU、內(nèi)存、存儲(chǔ)等核心信息監(jiān)控全攻略

 更新時(shí)間:2026年04月01日 09:07:15   作者:醉風(fēng)塘  
作為一名剛?cè)胄械腏ava開(kāi)發(fā)者,了解如何獲取服務(wù)器的CPU和內(nèi)存使用情況是一項(xiàng)基本技能,這篇文章主要介紹了Java獲取服務(wù)器狀態(tài)之CPU、內(nèi)存、存儲(chǔ)等核心信息監(jiān)控的相關(guān)資料,需要的朋友可以參考下

服務(wù)器健康狀態(tài)如同人體的脈搏,實(shí)時(shí)監(jiān)控是保障系統(tǒng)穩(wěn)定運(yùn)行的關(guān)鍵。掌握J(rèn)ava監(jiān)控技術(shù),讓你對(duì)服務(wù)器狀態(tài)了如指掌。

一、為什么需要監(jiān)控服務(wù)器狀態(tài)?

在實(shí)際生產(chǎn)環(huán)境中,服務(wù)器性能監(jiān)控是系統(tǒng)穩(wěn)定運(yùn)行的生命線。通過(guò)實(shí)時(shí)獲取CPU使用率、內(nèi)存占用、磁盤空間等核心指標(biāo),我們可以:

  • 預(yù)測(cè)和防止系統(tǒng)崩潰:在資源耗盡前及時(shí)預(yù)警
  • 優(yōu)化資源分配:合理調(diào)整應(yīng)用部署策略
  • 故障診斷:快速定位性能瓶頸
  • 容量規(guī)劃:為系統(tǒng)擴(kuò)展提供數(shù)據(jù)支持

Java提供了多種方式來(lái)獲取這些信息,從基礎(chǔ)的JDK內(nèi)置API到功能強(qiáng)大的第三方庫(kù),本文將一一為你解析。

二、監(jiān)控技術(shù)方案對(duì)比

在選擇具體實(shí)現(xiàn)方案前,我們先了解各種技術(shù)的特點(diǎn):

方案優(yōu)點(diǎn)缺點(diǎn)適用場(chǎng)景
JDK內(nèi)置API無(wú)需額外依賴、跨平臺(tái)功能有限、獲取復(fù)雜基礎(chǔ)監(jiān)控需求
OSHI庫(kù)功能全面、跨平臺(tái)、API友好需要額外依賴全面的系統(tǒng)監(jiān)控
JMX標(biāo)準(zhǔn)化、可遠(yuǎn)程監(jiān)控配置復(fù)雜、性能開(kāi)銷企業(yè)級(jí)應(yīng)用監(jiān)控
Sigar功能強(qiáng)大、歷史悠久維護(hù)較少、需要本地庫(kù)遺留系統(tǒng)

對(duì)于大多數(shù)現(xiàn)代應(yīng)用,OSHI(Open Source Hardware Information) 是目前最推薦的選擇,它純Java實(shí)現(xiàn),支持跨平臺(tái),無(wú)需安裝本地庫(kù)。

三、使用OSHI庫(kù)獲取系統(tǒng)信息

3.1 環(huán)境配置

首先在項(xiàng)目中添加OSHI依賴:

<!-- Maven依賴 -->
<dependency>
    <groupId>com.github.oshi</groupId>
    <artifactId>oshi-core</artifactId>
    <version>6.4.7</version>
</dependency>
<!-- 或者Gradle -->
implementation 'com.github.oshi:oshi-core:6.4.7'

OSHI支持Java 8及以上版本,會(huì)自動(dòng)檢測(cè)操作系統(tǒng)并加載相應(yīng)的本地庫(kù)。

3.2 完整的服務(wù)器監(jiān)控實(shí)現(xiàn)

以下是一個(gè)完整的服務(wù)器狀態(tài)監(jiān)控類,封裝了獲取各項(xiàng)指標(biāo)的方法:

import oshi.SystemInfo;
import oshi.hardware.CentralProcessor;
import oshi.hardware.GlobalMemory;
import oshi.hardware.HardwareAbstractionLayer;
import oshi.software.os.FileSystem;
import oshi.software.os.OSFileStore;
import oshi.software.os.OperatingSystem;
import oshi.util.FormatUtil;
import oshi.util.Util;
import java.text.DecimalFormat;
import java.util.*;
/**
 * 服務(wù)器狀態(tài)監(jiān)控工具類
 * 使用OSHI庫(kù)獲取CPU、內(nèi)存、磁盤等核心信息
 */
public class ServerMonitor {
    private static final SystemInfo systemInfo = new SystemInfo();
    private static final HardwareAbstractionLayer hardware = systemInfo.getHardware();
    private static final OperatingSystem os = systemInfo.getOperatingSystem();
    // 用于CPU使用率計(jì)算的緩存
    private static long[] previousTicks;
    private static long previousTime;
    /**
     * 獲取CPU信息
     */
    public static Map<String, Object> getCpuInfo() {
        Map<String, Object> cpuInfo = new LinkedHashMap<>();
        CentralProcessor processor = hardware.getProcessor();
        // CPU基本信息
        cpuInfo.put("CPU名稱", processor.getProcessorIdentifier().getName());
        cpuInfo.put("物理核心數(shù)", processor.getPhysicalProcessorCount());
        cpuInfo.put("邏輯核心數(shù)", processor.getLogicalProcessorCount());
        // CPU使用率(需要計(jì)算)
        double cpuUsage = calculateCpuUsage(processor);
        cpuInfo.put("系統(tǒng)使用率", String.format("%.2f%%", cpuUsage));
        // CPU頻率
        long maxFreq = processor.getMaxFreq();
        if (maxFreq > 0) {
            cpuInfo.put("最大頻率", FormatUtil.formatHertz(maxFreq));
        }
        // 每個(gè)邏輯處理器的使用率(按核心顯示)
        double[] load = processor.getProcessorCpuLoadBetweenTicks(previousTicks);
        if (previousTicks == null) {
            previousTicks = processor.getSystemCpuLoadTicks();
        }
        List<Map<String, String>> perCoreUsage = new ArrayList<>();
        for (int i = 0; i < load.length; i++) {
            Map<String, String> coreMap = new HashMap<>();
            coreMap.put("核心" + i, String.format("%.2f%%", load[i] * 100));
            perCoreUsage.add(coreMap);
        }
        cpuInfo.put("各核心使用率", perCoreUsage);
        return cpuInfo;
    }
    /**
     * 計(jì)算CPU總使用率
     */
    private static double calculateCpuUsage(CentralProcessor processor) {
        long[] ticks = processor.getSystemCpuLoadTicks();
        if (previousTicks != null) {
            long user = ticks[CentralProcessor.TickType.USER.getIndex()] 
                      - previousTicks[CentralProcessor.TickType.USER.getIndex()];
            long nice = ticks[CentralProcessor.TickType.NICE.getIndex()] 
                      - previousTicks[CentralProcessor.TickType.NICE.getIndex()];
            long system = ticks[CentralProcessor.TickType.SYSTEM.getIndex()] 
                        - previousTicks[CentralProcessor.TickType.SYSTEM.getIndex()];
            long idle = ticks[CentralProcessor.TickType.IDLE.getIndex()] 
                      - previousTicks[CentralProcessor.TickType.IDLE.getIndex()];
            long iowait = ticks[CentralProcessor.TickType.IOWAIT.getIndex()] 
                        - previousTicks[CentralProcessor.TickType.IOWAIT.getIndex()];
            long irq = ticks[CentralProcessor.TickType.IRQ.getIndex()] 
                     - previousTicks[CentralProcessor.TickType.IRQ.getIndex()];
            long softirq = ticks[CentralProcessor.TickType.SOFTIRQ.getIndex()] 
                         - previousTicks[CentralProcessor.TickType.SOFTIRQ.getIndex()];
            long steal = ticks[CentralProcessor.TickType.STEAL.getIndex()] 
                       - previousTicks[CentralProcessor.TickType.STEAL.getIndex()];
            long totalCpu = user + nice + system + idle + iowait + irq + softirq + steal;
            if (totalCpu > 0) {
                long nonIdle = user + nice + system + irq + softirq + steal;
                return (nonIdle * 100.0) / totalCpu;
            }
        }
        previousTicks = ticks;
        return processor.getSystemCpuLoadBetweenTicks(previousTicks)[0] * 100;
    }
    /**
     * 獲取內(nèi)存信息
     */
    public static Map<String, String> getMemoryInfo() {
        Map<String, String> memoryInfo = new LinkedHashMap<>();
        GlobalMemory memory = hardware.getMemory();
        // 總內(nèi)存和可用內(nèi)存
        long totalMemory = memory.getTotal();
        long availableMemory = memory.getAvailable();
        long usedMemory = totalMemory - availableMemory;
        memoryInfo.put("總內(nèi)存", FormatUtil.formatBytes(totalMemory));
        memoryInfo.put("已用內(nèi)存", FormatUtil.formatBytes(usedMemory));
        memoryInfo.put("可用內(nèi)存", FormatUtil.formatBytes(availableMemory));
        memoryInfo.put("使用率", String.format("%.2f%%", (usedMemory * 100.0) / totalMemory));
        // 交換空間信息(如果啟用)
        long swapTotal = memory.getVirtualMemory().getSwapTotal();
        if (swapTotal > 0) {
            long swapUsed = memory.getVirtualMemory().getSwapUsed();
            memoryInfo.put("交換空間總量", FormatUtil.formatBytes(swapTotal));
            memoryInfo.put("已用交換空間", FormatUtil.formatBytes(swapUsed));
            memoryInfo.put("交換空間使用率", 
                String.format("%.2f%%", (swapUsed * 100.0) / swapTotal));
        }
        return memoryInfo;
    }
    /**
     * 獲取磁盤信息
     */
    public static List<Map<String, String>> getDiskInfo() {
        List<Map<String, String>> diskList = new ArrayList<>();
        FileSystem fileSystem = os.getFileSystem();
        List<OSFileStore> fileStores = fileSystem.getFileStores();
        DecimalFormat df = new DecimalFormat("#.##");
        for (OSFileStore fs : fileStores) {
            // 跳過(guò)特殊文件系統(tǒng)(如內(nèi)存文件系統(tǒng))
            if (fs.getType().toLowerCase().contains("tmpfs") || 
                fs.getType().toLowerCase().contains("devtmpfs")) {
                continue;
            }
            Map<String, String> diskInfo = new LinkedHashMap<>();
            long totalSpace = fs.getTotalSpace();
            long freeSpace = fs.getFreeSpace();
            long usableSpace = fs.getUsableSpace();
            long usedSpace = totalSpace - freeSpace;
            double usagePercentage = (usedSpace * 100.0) / totalSpace;
            diskInfo.put("磁盤名稱", fs.getName());
            diskInfo.put("掛載點(diǎn)", fs.getMount());
            diskInfo.put("文件系統(tǒng)類型", fs.getType());
            diskInfo.put("總空間", FormatUtil.formatBytes(totalSpace));
            diskInfo.put("已用空間", FormatUtil.formatBytes(usedSpace));
            diskInfo.put("可用空間", FormatUtil.formatBytes(freeSpace));
            diskInfo.put("使用率", df.format(usagePercentage) + "%");
            // 添加警告信息(如果使用率超過(guò)85%)
            if (usagePercentage > 85) {
                diskInfo.put("狀態(tài)", "警告: 磁盤空間不足");
            } else if (usagePercentage > 70) {
                diskInfo.put("狀態(tài)", "注意: 磁盤空間緊張");
            } else {
                diskInfo.put("狀態(tài)", "正常");
            }
            diskList.add(diskInfo);
        }
        return diskList;
    }
    /**
     * 獲取系統(tǒng)負(fù)載(Linux/Unix系統(tǒng))
     */
    public static Map<String, String> getSystemLoad() {
        Map<String, String> loadInfo = new LinkedHashMap<>();
        CentralProcessor processor = hardware.getProcessor();
        // 系統(tǒng)負(fù)載平均值(1分鐘,5分鐘,15分鐘)
        double[] loadAverages = processor.getSystemLoadAverage(3);
        if (loadAverages[0] >= 0) {
            loadInfo.put("1分鐘負(fù)載", String.format("%.2f", loadAverages[0]));
            loadInfo.put("5分鐘負(fù)載", String.format("%.2f", loadAverages[1]));
            loadInfo.put("15分鐘負(fù)載", String.format("%.2f", loadAverages[2]));
            // 負(fù)載解釋
            int logicalCpuCount = processor.getLogicalProcessorCount();
            String loadStatus;
            double loadPerCpu = loadAverages[0] / logicalCpuCount;
            if (loadPerCpu < 0.7) {
                loadStatus = "正常";
            } else if (loadPerCpu < 1.0) {
                loadStatus = "偏高";
            } else {
                loadStatus = "過(guò)高";
            }
            loadInfo.put("負(fù)載狀態(tài)", loadStatus);
            loadInfo.put("建議", String.format("每核心負(fù)載: %.2f", loadPerCpu));
        } else {
            loadInfo.put("備注", "系統(tǒng)負(fù)載信息不可用(可能不是Linux/Unix系統(tǒng))");
        }
        return loadInfo;
    }
    /**
     * 獲取系統(tǒng)基本信息
     */
    public static Map<String, String> getSystemInfo() {
        Map<String, String> sysInfo = new LinkedHashMap<>();
        // 操作系統(tǒng)信息
        sysInfo.put("操作系統(tǒng)", os.getFamily() + " " + os.getVersionInfo().getVersion());
        sysInfo.put("系統(tǒng)架構(gòu)", os.getBitness() + "位");
        sysInfo.put("制造商", systemInfo.getHardware().getComputerSystem().getManufacturer());
        sysInfo.put("型號(hào)", systemInfo.getHardware().getComputerSystem().getModel());
        // 運(yùn)行時(shí)間
        long uptime = os.getSystemUptime();
        long days = uptime / (24 * 3600);
        long hours = (uptime % (24 * 3600)) / 3600;
        long minutes = (uptime % 3600) / 60;
        long seconds = uptime % 60;
        sysInfo.put("運(yùn)行時(shí)間", 
            String.format("%d天 %02d:%02d:%02d", days, hours, minutes, seconds));
        // JVM信息
        Runtime runtime = Runtime.getRuntime();
        sysInfo.put("JVM總內(nèi)存", FormatUtil.formatBytes(runtime.totalMemory()));
        sysInfo.put("JVM可用內(nèi)存", FormatUtil.formatBytes(runtime.freeMemory()));
        sysInfo.put("JVM最大內(nèi)存", FormatUtil.formatBytes(runtime.maxMemory()));
        sysInfo.put("Java版本", System.getProperty("java.version"));
        return sysInfo;
    }
    /**
     * 獲取所有監(jiān)控信息的匯總報(bào)告
     */
    public static Map<String, Object> getServerStatusReport() {
        Map<String, Object> report = new LinkedHashMap<>();
        report.put("采集時(shí)間", new Date());
        report.put("系統(tǒng)信息", getSystemInfo());
        report.put("CPU信息", getCpuInfo());
        report.put("內(nèi)存信息", getMemoryInfo());
        report.put("磁盤信息", getDiskInfo());
        report.put("系統(tǒng)負(fù)載", getSystemLoad());
        // 整體健康狀態(tài)評(píng)估
        String healthStatus = assessServerHealth(report);
        report.put("健康狀態(tài)", healthStatus);
        return report;
    }
    /**
     * 評(píng)估服務(wù)器健康狀態(tài)
     */
    private static String assessServerHealth(Map<String, Object> report) {
        List<String> warnings = new ArrayList<>();
        // 檢查CPU使用率
        Map<String, Object> cpuInfo = (Map<String, Object>) report.get("CPU信息");
        if (cpuInfo.containsKey("系統(tǒng)使用率")) {
            String cpuUsageStr = (String) cpuInfo.get("系統(tǒng)使用率");
            double cpuUsage = Double.parseDouble(cpuUsageStr.replace("%", ""));
            if (cpuUsage > 90) {
                warnings.add("CPU使用率過(guò)高: " + cpuUsageStr);
            } else if (cpuUsage > 80) {
                warnings.add("CPU使用率偏高: " + cpuUsageStr);
            }
        }
        // 檢查內(nèi)存使用率
        Map<String, String> memoryInfo = (Map<String, String>) report.get("內(nèi)存信息");
        String memoryUsageStr = memoryInfo.get("使用率");
        double memoryUsage = Double.parseDouble(memoryUsageStr.replace("%", ""));
        if (memoryUsage > 90) {
            warnings.add("內(nèi)存使用率過(guò)高: " + memoryUsageStr);
        }
        // 檢查磁盤使用率
        List<Map<String, String>> diskInfo = (List<Map<String, String>>) report.get("磁盤信息");
        for (Map<String, String> disk : diskInfo) {
            String diskUsageStr = disk.get("使用率");
            double diskUsage = Double.parseDouble(diskUsageStr.replace("%", ""));
            if (diskUsage > 90) {
                warnings.add("磁盤[" + disk.get("磁盤名稱") + "]空間嚴(yán)重不足: " + diskUsageStr);
            } else if (diskUsage > 85) {
                warnings.add("磁盤[" + disk.get("磁盤名稱") + "]空間不足: " + diskUsageStr);
            }
        }
        // 檢查系統(tǒng)負(fù)載
        Map<String, String> loadInfo = (Map<String, String>) report.get("系統(tǒng)負(fù)載");
        if (loadInfo.containsKey("負(fù)載狀態(tài)")) {
            String loadStatus = loadInfo.get("負(fù)載狀態(tài)");
            if ("過(guò)高".equals(loadStatus)) {
                warnings.add("系統(tǒng)負(fù)載過(guò)高: " + loadInfo.get("1分鐘負(fù)載"));
            }
        }
        if (warnings.isEmpty()) {
            return "健康";
        } else {
            return "警告 - 存在" + warnings.size() + "個(gè)問(wèn)題: " + String.join("; ", warnings);
        }
    }
    /**
     * 格式化輸出監(jiān)控報(bào)告
     */
    public static void printServerStatusReport() {
        Map<String, Object> report = getServerStatusReport();
        System.out.println("========== 服務(wù)器狀態(tài)監(jiān)控報(bào)告 ==========");
        System.out.println("采集時(shí)間: " + report.get("采集時(shí)間"));
        System.out.println("健康狀態(tài): " + report.get("健康狀態(tài)"));
        System.out.println();
        System.out.println("--------------- 系統(tǒng)信息 ---------------");
        Map<String, String> systemInfo = (Map<String, String>) report.get("系統(tǒng)信息");
        for (Map.Entry<String, String> entry : systemInfo.entrySet()) {
            System.out.printf("%-15s: %s%n", entry.getKey(), entry.getValue());
        }
        System.out.println("\n--------------- CPU信息 ---------------");
        Map<String, Object> cpuInfo = (Map<String, Object>) report.get("CPU信息");
        for (Map.Entry<String, Object> entry : cpuInfo.entrySet()) {
            if ("各核心使用率".equals(entry.getKey())) {
                System.out.println("各核心使用率:");
                List<Map<String, String>> coreUsage = (List<Map<String, String>>) entry.getValue();
                for (int i = 0; i < coreUsage.size(); i++) {
                    Map<String, String> core = coreUsage.get(i);
                    System.out.printf("  核心%d: %s%n", i, core.get("核心" + i));
                }
            } else {
                System.out.printf("%-15s: %s%n", entry.getKey(), entry.getValue());
            }
        }
        System.out.println("\n--------------- 內(nèi)存信息 ---------------");
        Map<String, String> memoryInfo = (Map<String, String>) report.get("內(nèi)存信息");
        for (Map.Entry<String, String> entry : memoryInfo.entrySet()) {
            System.out.printf("%-15s: %s%n", entry.getKey(), entry.getValue());
        }
        System.out.println("\n--------------- 磁盤信息 ---------------");
        List<Map<String, String>> diskInfo = (List<Map<String, String>>) report.get("磁盤信息");
        for (Map<String, String> disk : diskInfo) {
            System.out.println("磁盤: " + disk.get("磁盤名稱") + 
                             " [" + disk.get("掛載點(diǎn)") + "]");
            System.out.printf("  類型: %s, 總空間: %s%n", 
                disk.get("文件系統(tǒng)類型"), disk.get("總空間"));
            System.out.printf("  已用: %s, 可用: %s%n",
                disk.get("已用空間"), disk.get("可用空間"));
            System.out.printf("  使用率: %s, 狀態(tài): %s%n",
                disk.get("使用率"), disk.get("狀態(tài)"));
            System.out.println();
        }
        System.out.println("--------------- 系統(tǒng)負(fù)載 ---------------");
        Map<String, String> loadInfo = (Map<String, String>) report.get("系統(tǒng)負(fù)載");
        for (Map.Entry<String, String> entry : loadInfo.entrySet()) {
            System.out.printf("%-15s: %s%n", entry.getKey(), entry.getValue());
        }
        System.out.println("\n========== 報(bào)告結(jié)束 ==========");
    }
    /**
     * 主方法 - 測(cè)試用
     */
    public static void main(String[] args) {
        System.out.println("正在收集服務(wù)器狀態(tài)信息...\n");
        // 打印完整報(bào)告
        printServerStatusReport();
        // 也可以單獨(dú)獲取某項(xiàng)信息
        // Map<String, Object> cpuInfo = getCpuInfo();
        // System.out.println("CPU使用率: " + cpuInfo.get("系統(tǒng)使用率"));
        // 定時(shí)監(jiān)控示例
        if (args.length > 0 && "monitor".equals(args[0])) {
            System.out.println("\n啟動(dòng)定時(shí)監(jiān)控,每10秒刷新一次...");
            startPeriodicMonitoring(10);
        }
    }
    /**
     * 啟動(dòng)定時(shí)監(jiān)控
     */
    public static void startPeriodicMonitoring(int intervalSeconds) {
        Timer timer = new Timer();
        timer.scheduleAtFixedRate(new TimerTask() {
            private int count = 0;
            private final int maxCount = 30; // 最多監(jiān)控30次
            @Override
            public void run() {
                count++;
                System.out.println("\n--- 監(jiān)控周期 #" + count + " ---");
                Map<String, Object> report = getServerStatusReport();
                String healthStatus = (String) report.get("健康狀態(tài)");
                String cpuUsage = ((Map<String, Object>) report.get("CPU信息"))
                                 .get("系統(tǒng)使用率").toString();
                String memoryUsage = ((Map<String, String>) report.get("內(nèi)存信息"))
                                   .get("使用率");
                System.out.printf("健康狀態(tài): %s, CPU: %s, 內(nèi)存: %s%n", 
                    healthStatus, cpuUsage, memoryUsage);
                if (count >= maxCount) {
                    System.out.println("監(jiān)控任務(wù)完成。");
                    timer.cancel();
                }
            }
        }, 0, intervalSeconds * 1000);
    }
}

四、使用JMX監(jiān)控Java應(yīng)用

除了系統(tǒng)級(jí)監(jiān)控,JMX(Java Management Extensions)是監(jiān)控Java應(yīng)用自身狀態(tài)的強(qiáng)大工具:

import javax.management.*;
import java.lang.management.*;
/**
 * JMX監(jiān)控工具類
 */
public class JmxMonitor {
    /**
     * 獲取JVM內(nèi)存使用情況
     */
    public static void monitorJvmMemory() {
        MemoryMXBean memoryMxBean = ManagementFactory.getMemoryMXBean();
        MemoryUsage heapMemoryUsage = memoryMxBean.getHeapMemoryUsage();
        MemoryUsage nonHeapMemoryUsage = memoryMxBean.getNonHeapMemoryUsage();
        System.out.println("=== JVM內(nèi)存監(jiān)控 ===");
        System.out.printf("堆內(nèi)存: 已用=%.2fMB, 提交=%.2fMB, 最大=%.2fMB%n",
            heapMemoryUsage.getUsed() / (1024.0 * 1024),
            heapMemoryUsage.getCommitted() / (1024.0 * 1024),
            heapMemoryUsage.getMax() / (1024.0 * 1024));
        System.out.printf("非堆內(nèi)存: 已用=%.2fMB, 提交=%.2fMB%n",
            nonHeapMemoryUsage.getUsed() / (1024.0 * 1024),
            nonHeapMemoryUsage.getCommitted() / (1024.0 * 1024));
    }
    /**
     * 獲取線程信息
     */
    public static void monitorThreads() {
        ThreadMXBean threadMxBean = ManagementFactory.getThreadMXBean();
        System.out.println("\n=== 線程監(jiān)控 ===");
        System.out.println("活動(dòng)線程數(shù): " + threadMxBean.getThreadCount());
        System.out.println("守護(hù)線程數(shù): " + threadMxBean.getDaemonThreadCount());
        System.out.println("峰值線程數(shù): " + threadMxBean.getPeakThreadCount());
        System.out.println("啟動(dòng)的總線程數(shù): " + threadMxBean.getTotalStartedThreadCount());
        // 檢測(cè)死鎖
        long[] deadlockedThreads = threadMxBean.findDeadlockedThreads();
        if (deadlockedThreads != null && deadlockedThreads.length > 0) {
            System.out.println("警告: 檢測(cè)到死鎖線程!");
        }
    }
    /**
     * 獲取GC信息
     */
    public static void monitorGarbageCollector() {
        List<GarbageCollectorMXBean> gcMxBeans = 
            ManagementFactory.getGarbageCollectorMXBeans();
        System.out.println("\n=== 垃圾回收監(jiān)控 ===");
        for (GarbageCollectorMXBean gcMxBean : gcMxBeans) {
            System.out.printf("GC名稱: %s%n", gcMxBean.getName());
            System.out.printf("  回收次數(shù): %d%n", gcMxBean.getCollectionCount());
            System.out.printf("  回收時(shí)間: %dms%n", gcMxBean.getCollectionTime());
        }
    }
}

五、高級(jí)監(jiān)控:Spring Boot Actuator集成

對(duì)于Spring Boot應(yīng)用,可以輕松集成監(jiān)控功能:

# application.yml
management:
  endpoints:
    web:
      exposure:
        include: health,info,metrics,prometheus
  endpoint:
    health:
      show-details: always
  metrics:
    export:
      prometheus:
        enabled: true
// 自定義健康檢查
@Component
public class ServerHealthIndicator implements HealthIndicator {
    @Override
    public Health health() {
        Map<String, Object> serverStatus = ServerMonitor.getServerStatusReport();
        String healthStatus = (String) serverStatus.get("健康狀態(tài)");
        if ("健康".equals(healthStatus)) {
            return Health.up()
                .withDetail("服務(wù)器狀態(tài)", "正常")
                .withDetail("CPU使用率", 
                    ((Map<String, Object>) serverStatus.get("CPU信息"))
                    .get("系統(tǒng)使用率"))
                .withDetail("內(nèi)存使用率", 
                    ((Map<String, String>) serverStatus.get("內(nèi)存信息"))
                    .get("使用率"))
                .build();
        } else {
            return Health.down()
                .withDetail("服務(wù)器狀態(tài)", "異常")
                .withDetail("問(wèn)題", healthStatus)
                .build();
        }
    }
}

六、監(jiān)控?cái)?shù)據(jù)可視化

收集到的監(jiān)控?cái)?shù)據(jù)可以通過(guò)以下方式可視化:

  1. Prometheus + Grafana:行業(yè)標(biāo)準(zhǔn)的監(jiān)控組合
  2. 自定義Dashboard:使用ECharts等前端庫(kù)
  3. 日志聚合:ELK Stack(Elasticsearch, Logstash, Kibana)
// Prometheus指標(biāo)導(dǎo)出示例
import io.prometheus.client.*;
public class PrometheusExporter {
    private static final Gauge cpuUsage = Gauge.build()
        .name("server_cpu_usage_percent")
        .help("CPU使用率百分比")
        .register();
    private static final Gauge memoryUsage = Gauge.build()
        .name("server_memory_usage_percent")
        .help("內(nèi)存使用率百分比")
        .register();
    private static final Gauge diskUsage = Gauge.build()
        .name("server_disk_usage_percent")
        .help("磁盤使用率百分比")
        .labelNames("mount_point")
        .register();
    public static void updateMetrics() {
        Map<String, Object> report = ServerMonitor.getServerStatusReport();
        // 更新CPU指標(biāo)
        String cpuUsageStr = ((Map<String, Object>) report.get("CPU信息"))
                           .get("系統(tǒng)使用率").toString();
        cpuUsage.set(Double.parseDouble(cpuUsageStr.replace("%", "")));
        // 更新內(nèi)存指標(biāo)
        String memoryUsageStr = ((Map<String, String>) report.get("內(nèi)存信息"))
                              .get("使用率");
        memoryUsage.set(Double.parseDouble(memoryUsageStr.replace("%", "")));
        // 更新磁盤指標(biāo)
        List<Map<String, String>> diskInfo = 
            (List<Map<String, String>>) report.get("磁盤信息");
        for (Map<String, String> disk : diskInfo) {
            String usageStr = disk.get("使用率");
            diskUsage.labels(disk.get("掛載點(diǎn)"))
                    .set(Double.parseDouble(usageStr.replace("%", "")));
        }
    }
}

七、最佳實(shí)踐與注意事項(xiàng)

7.1 監(jiān)控頻率控制

  • 實(shí)時(shí)監(jiān)控:關(guān)鍵指標(biāo)每秒采集
  • 性能監(jiān)控:每5-30秒采集
  • 容量監(jiān)控:每小時(shí)或每天采集

7.2 異常處理

try {
    Map<String, Object> report = ServerMonitor.getServerStatusReport();
    // 處理監(jiān)控?cái)?shù)據(jù)
} catch (Exception e) {
    // 記錄錯(cuò)誤但不要影響主業(yè)務(wù)流程
    logger.error("監(jiān)控?cái)?shù)據(jù)采集失敗", e);
    // 返回降級(jí)數(shù)據(jù)或默認(rèn)值
}

7.3 性能優(yōu)化

  • 緩存監(jiān)控結(jié)果:避免頻繁獲取
  • 異步采集:不影響主線程性能
  • 批量更新:減少I/O操作

八、總結(jié)

通過(guò)本文的全面介紹,你應(yīng)該已經(jīng)掌握了使用Java獲取服務(wù)器狀態(tài)的各種方法。關(guān)鍵的要點(diǎn)包括:

  1. OSHI庫(kù)是最佳選擇:功能全面、跨平臺(tái)、API友好
  2. 分層監(jiān)控策略:系統(tǒng)層、應(yīng)用層、業(yè)務(wù)層全方位監(jiān)控
  3. 可視化是關(guān)鍵:將原始數(shù)據(jù)轉(zhuǎn)化為 actionable insights
  4. 監(jiān)控告警一體化:發(fā)現(xiàn)問(wèn)題后能及時(shí)通知相關(guān)人員

在實(shí)際項(xiàng)目中,建議根據(jù)具體需求選擇合適的監(jiān)控方案。對(duì)于簡(jiǎn)單的項(xiàng)目,可以直接使用本文提供的ServerMonitor類;對(duì)于企業(yè)級(jí)應(yīng)用,建議集成Spring Boot Actuator或?qū)I(yè)的APM工具(如SkyWalking、Pinpoint等)。

監(jiān)控不僅是技術(shù)問(wèn)題,更是運(yùn)維文化和工程實(shí)踐的體現(xiàn)。良好的監(jiān)控體系能顯著提高系統(tǒng)穩(wěn)定性和團(tuán)隊(duì)開(kāi)發(fā)效率,是每個(gè)負(fù)責(zé)任的開(kāi)發(fā)者和運(yùn)維人員必備的技能。

到此這篇關(guān)于Java獲取服務(wù)器狀態(tài)之CPU、內(nèi)存、存儲(chǔ)等核心信息監(jiān)控的文章就介紹到這了,更多相關(guān)Java獲取服務(wù)器CPU、內(nèi)存、存儲(chǔ)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java中checkbox實(shí)現(xiàn)跨頁(yè)多選的方法

    Java中checkbox實(shí)現(xiàn)跨頁(yè)多選的方法

    最近做了一個(gè)項(xiàng)目其中遇到這樣的需求,要實(shí)現(xiàn)checkbox跨頁(yè)多選功能,經(jīng)過(guò)小編整理,順利解決,今天小編給大家分享Java中checkbox實(shí)現(xiàn)跨頁(yè)多選的方法,需要的的朋友參考下
    2017-01-01
  • SpringBoot使用Redis的zset統(tǒng)計(jì)在線用戶信息

    SpringBoot使用Redis的zset統(tǒng)計(jì)在線用戶信息

    這篇文章主要介紹了SpringBoot使用Redis的zset統(tǒng)計(jì)在線用戶信息,幫助大家更好的理解和學(xué)習(xí)使用SpringBoot框架,感興趣的朋友可以了解下
    2021-04-04
  • springboot 項(xiàng)目某個(gè)接口響應(yīng)特別慢問(wèn)題排查分析

    springboot 項(xiàng)目某個(gè)接口響應(yīng)特別慢問(wèn)題排查分析

    文章描述了一個(gè)Spring Boot項(xiàng)目中某個(gè)接口請(qǐng)求日志顯示耗時(shí)極短,但通過(guò)Postman發(fā)起相同請(qǐng)求時(shí)耗時(shí)顯著增加的問(wèn)題,經(jīng)過(guò)排查,發(fā)現(xiàn)耗時(shí)主要集中在自定義的ControllerInterceptor中的logBefore方法,特別是SensitiveInfoSerialize.getJson方法,感興趣的朋友跟隨小編一起看看吧
    2025-12-12
  • mybatis 根據(jù)id批量刪除的實(shí)現(xiàn)操作

    mybatis 根據(jù)id批量刪除的實(shí)現(xiàn)操作

    這篇文章主要介紹了mybatis 根據(jù)id批量刪除的實(shí)現(xiàn)操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-08-08
  • java中hibernate二級(jí)緩存詳解

    java中hibernate二級(jí)緩存詳解

    本篇文章中主要介紹了java中hibernate二級(jí)緩存詳解,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-05-05
  • SpringBoot配置文件、多環(huán)境配置、讀取配置的4種實(shí)現(xiàn)方式

    SpringBoot配置文件、多環(huán)境配置、讀取配置的4種實(shí)現(xiàn)方式

    SpringBoot支持多種配置文件位置和格式,其中application.properties和application.yml是默認(rèn)加載的文件,配置文件可以根據(jù)環(huán)境通過(guò)spring.profiles.active屬性進(jìn)行區(qū)分,命令行參數(shù)具有最高優(yōu)先級(jí),可覆蓋其他所有配置
    2024-09-09
  • Java跨庫(kù)事務(wù)如何實(shí)現(xiàn)保證

    Java跨庫(kù)事務(wù)如何實(shí)現(xiàn)保證

    這段文章詳細(xì)介紹了Java中實(shí)現(xiàn)跨庫(kù)事務(wù)管理的方法,包括使用XA協(xié)議、Spring的JTA事務(wù)管理器和第三方解決方案如Seata,文章通過(guò)具體步驟和配置示例,解釋了如何在Java應(yīng)用中實(shí)現(xiàn)高效、可靠的分布式事務(wù)管理,適用于不同場(chǎng)景和需求
    2026-05-05
  • 在Spring Boot中加載XML配置的完整步驟

    在Spring Boot中加載XML配置的完整步驟

    這篇文章主要給大家介紹了關(guān)于在Spring Boot中加載XML配置的完整步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09
  • 詳解SpringBoot Mybatis如何對(duì)接多數(shù)據(jù)源

    詳解SpringBoot Mybatis如何對(duì)接多數(shù)據(jù)源

    這篇文章主要為大家介紹了SpringBoot Mybatis如何對(duì)接多數(shù)據(jù)源實(shí)現(xiàn)方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-09-09
  • mybatis防止SQL注入的方法實(shí)例詳解

    mybatis防止SQL注入的方法實(shí)例詳解

    SQL注入是一種很簡(jiǎn)單的攻擊手段,但直到今天仍然十分常見(jiàn)。那么mybatis是如何防止SQL注入的呢?下面腳本之家小編給大家?guī)?lái)了實(shí)例代碼,需要的朋友參考下吧
    2018-04-04

最新評(píng)論

商丘市| 开平市| 乐平市| 奉化市| 彭阳县| 乌拉特后旗| 乾安县| 莱芜市| 无为县| 咸宁市| 罗山县| 沾益县| 潼南县| 长顺县| 晋州市| 皮山县| 剑川县| 榆林市| 玉树县| 武隆县| 珠海市| 沅江市| 江山市| 闻喜县| 兰州市| 会同县| 九江市| 商南县| 方山县| 郴州市| 石柱| 衡东县| 琼中| 高密市| 安国市| 公安县| 苗栗县| 旌德县| 中西区| 北辰区| 辽中县|