Java使用OSHI获取服务器信息方式

 更新时间:2025年09月15日 16:07:29   作者:Spirit_NKlaus  
这篇文章主要介绍了Java使用OSHI获取服务器信息方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

Java使用OSHI获取服务器信息

OSHI可以获取系统信息(CPU、内存、磁盘、网络等),纯Java实现(通过JNA访问本地API,无需安装本地库),跨平台支持。

引入依赖

<dependency>
	<groupId>com.github.oshi</groupId>
	<artifactId>oshi-core</artifactId>
    <version>6.6.5</version>
</dependency>

编写测试用例

import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import oshi.SystemInfo;
import oshi.hardware.*;
import oshi.software.os.OSProcess;
import oshi.software.os.OperatingSystem;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;

@Slf4j
public class ResourceMonitorTest {

    @Test
    public void testGetResource() {
        // 获取系统信息
        SystemInfo si = new SystemInfo();
        // 获取硬件抽象层
        HardwareAbstractionLayer hardware = si.getHardware();

        log.info("===============================CPU信息===============================");
        CentralProcessor processor = hardware.getProcessor();
        CentralProcessor.ProcessorIdentifier processorIdentifier = processor.getProcessorIdentifier();

        String processorName = processorIdentifier.getName();
        log.info("CPU 名称: {}", processorName);

        String vendor = processorIdentifier.getVendor();
        log.info("CPU 供应商: {}", vendor);

        long cpuFreq = processorIdentifier.getVendorFreq();
        log.info("CPU 频率: {}", cpuFreq);

        int logicalProcessorCount = processor.getLogicalProcessorCount();
        log.info("CPU 核心数: {}", logicalProcessorCount);

        int physicalProcessorCount = processor.getPhysicalProcessorCount();
        log.info("CPU 物理核心数: {}", physicalProcessorCount);

        // CPU 负载 (最近1/5/15分钟)
        double[] loadAverage = processor.getSystemLoadAverage(3);
        log.info("CPU 负载: {}", loadAverage[0]);

        log.info("===============================实时 CPU 使用率===============================");
        // 第一次调用获取 ticks
        long[] prevTicks = processor.getSystemCpuLoadTicks();
        // 等待1秒
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        // 第二次调用计算使用率
        long[] ticks = processor.getSystemCpuLoadTicks();
        long user = ticks[CentralProcessor.TickType.USER.getIndex()] - prevTicks[CentralProcessor.TickType.USER.getIndex()];
        log.info("应用程序CPU使用率:{}", user);

        long nice = ticks[CentralProcessor.TickType.NICE.getIndex()] - prevTicks[CentralProcessor.TickType.NICE.getIndex()];
        log.info("应用程序优先CPU使用率:{}", nice);

        long sys = ticks[CentralProcessor.TickType.SYSTEM.getIndex()] - prevTicks[CentralProcessor.TickType.SYSTEM.getIndex()];
        log.info("系统程序CPU使用率:{}", sys);

        long idle = ticks[CentralProcessor.TickType.IDLE.getIndex()] - prevTicks[CentralProcessor.TickType.IDLE.getIndex()];
        log.info("CPU空闲时间:{}", idle);

        long iowait = ticks[CentralProcessor.TickType.IOWAIT.getIndex()] - prevTicks[CentralProcessor.TickType.IOWAIT.getIndex()];
        log.info("CPU等待率:{}", iowait);

        long irq = ticks[CentralProcessor.TickType.IRQ.getIndex()] - prevTicks[CentralProcessor.TickType.IRQ.getIndex()];
        log.info("CPU中断率:{}", irq);

        long softirq = ticks[CentralProcessor.TickType.SOFTIRQ.getIndex()] - prevTicks[CentralProcessor.TickType.SOFTIRQ.getIndex()];
        log.info("CPU软中断率:{}", softirq);

        long steal = ticks[CentralProcessor.TickType.STEAL.getIndex()] - prevTicks[CentralProcessor.TickType.STEAL.getIndex()];
        log.info("CPU抢占率:{}", steal);

        long totalCpu = user + nice + sys + idle + iowait + irq + softirq + steal;
        log.info("CPU总使用率:{}", totalCpu);

        // 计算各状态百分比
        double cpuUsage = 100d * (totalCpu - idle) / totalCpu;
        log.info("CPU使用率:{}", cpuUsage);

        double ioWaitPercent = 100d * iowait / totalCpu;
        log.info("IO等待使用率:{}", ioWaitPercent);

        log.info("===============================内存信息===============================");
        GlobalMemory memory = hardware.getMemory();
        double gbNum = 1024.0 * 1024.0 * 1024.0;
        // 总内存 (bytes)
        long totalMemory = memory.getTotal();
        BigDecimal totalMemoryDec = new BigDecimal(totalMemory / gbNum).setScale(2, RoundingMode.HALF_UP);
        log.info("总内存:{}GB", totalMemoryDec);

        // 可用内存 (bytes)
        long availableMemory = memory.getAvailable();
        BigDecimal availableMemoryDec = new BigDecimal(availableMemory / gbNum).setScale(2, RoundingMode.HALF_UP);
        log.info("可用内存:{}GB", availableMemoryDec);

        // 已用内存 (bytes)
        long usedMemory = totalMemory - availableMemory;
        BigDecimal usedMemoryDec = new BigDecimal(usedMemory / gbNum).setScale(2, RoundingMode.HALF_UP);
        log.info("已用内存:{}GB", usedMemoryDec);

        // 交换空间信息
        long totalSwap = memory.getVirtualMemory().getSwapTotal();
        BigDecimal totalSwapDec = new BigDecimal(totalSwap / gbNum).setScale(2, RoundingMode.HALF_UP);
        log.info("总交换空间:{}GB", totalSwapDec);

        long usedSwap = memory.getVirtualMemory().getSwapUsed();
        BigDecimal usedSwapDec = new BigDecimal(usedSwap / gbNum).setScale(2, RoundingMode.HALF_UP);
        log.info("已用交换空间:{}GB", usedSwapDec);

        // 内存使用率
        double memoryUsagePercent = 100d * usedMemory / totalMemory;
        BigDecimal memoryUsagePercentDec = new BigDecimal(memoryUsagePercent / gbNum).setScale(2, RoundingMode.HALF_UP);
        log.info("内存使用率:{}%", memoryUsagePercentDec);

        log.info("===============================磁盘设备信息===============================");
        List<HWDiskStore> diskStores = hardware.getDiskStores();
        for (HWDiskStore disk : diskStores) {
            String name = disk.getName();

            String model = disk.getModel();
            log.info("磁盘:{},磁盘型号:{}", name, model);

            long size = disk.getSize();
            BigDecimal sizeDec = new BigDecimal(size / gbNum).setScale(2, RoundingMode.HALF_UP);
            log.info("磁盘:{},磁盘大小:{}GB", name, sizeDec);

            long reads = disk.getReads();
            log.info("磁盘:{},读取次数:{}", name, reads);

            long readBytes = disk.getReadBytes();
            log.info("磁盘:{},读取字节数:{}", name, readBytes);

            long writes = disk.getWrites();
            log.info("磁盘:{},写入次数:{}", name, writes);

            long writeBytes = disk.getWriteBytes();
            log.info("磁盘:{},写入字节数:{}", name, writeBytes);

            long transferTime = disk.getTransferTime();
            log.info("磁盘:{},传输时间:{}", name, transferTime);
        }

        log.info("===============================网络接口信息===============================");
        List<NetworkIF> networkIFs = hardware.getNetworkIFs();
        for (NetworkIF net : networkIFs) {
            String name = net.getName();

            String displayName = net.getDisplayName();
            log.info("网络接口:{},显示名称:{}", name, displayName);

            String mac = net.getMacaddr();
            log.info("网络接口:{},MAC地址:{}", name, mac);

            long mtu = net.getMTU();
            log.info("网络接口:{},MTU值:{}", name, mtu);

            long speed = net.getSpeed();
            log.info("网络接口:{},网卡速度:{}", name, speed);

            String[] ipv4 = net.getIPv4addr();
            log.info("网络接口:{},IPv4 地址:{}", name, ipv4);

            String[] ipv6 = net.getIPv6addr();
            log.info("网络接口:{},IPv6 地址:{}", name, ipv6);
        }
        // 第一次获取数据
        long bytesRecv = 0L;
        long bytesSent = 0L;
        for (NetworkIF net : networkIFs) {
            net.updateAttributes();
            bytesRecv = net.getBytesRecv();
            bytesSent = net.getBytesSent();
            long packetsRecv = net.getPacketsRecv();
            long packetsSent = net.getPacketsSent();
        }
        // 等待1秒
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        // 第二次获取并计算速率
        for (NetworkIF net : networkIFs) {
            net.updateAttributes();
            long newRecv = net.getBytesRecv();
            long newSent = net.getBytesSent();
            // 计算每秒接收/发送的字节数
            long recvRate = newRecv - bytesRecv;
            long sentRate = newSent - bytesSent;
            log.info("网卡 {} 接收 {} 字节/秒, 发送 {} 字节/秒", net.getName(), recvRate, sentRate);
        }

        log.info("===============================操作系统信息===============================");
        OperatingSystem os = si.getOperatingSystem();

        String family = os.getFamily();
        log.info("操作系统 {}", family);

        String manufacturer = os.getManufacturer();
        log.info("操作系统制造商 {}", manufacturer);

        OperatingSystem.OSVersionInfo versionInfo = os.getVersionInfo();
        log.info("操作系统版本 {}", versionInfo.toString());

        long uptime = os.getSystemUptime();
        log.info("系统启动时间 {}", uptime);

        int processCount = os.getProcessCount();
        log.info("进程数量 {}", processCount);

        int threadCount = os.getThreadCount();
        log.info("线程数量 {}", threadCount);

        OSProcess currentProcess = os.getProcess(os.getProcessId());
        log.info("当前进程 {}", currentProcess.getName());

        long processMemory = currentProcess.getResidentSetSize();
        log.info("进程内存占用 {}", processMemory);

        double processCpuLoad = currentProcess.getProcessCpuLoadBetweenTicks(currentProcess);
        log.info("进程CPU使用率 {}", processCpuLoad);
    }
}

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • java中List集合及其实现类的方法详解

    java中List集合及其实现类的方法详解

    本篇文章给大家带来的内容是关于java中List集合及其实现类的方法介绍(附代码),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。下面我们就来学习一下吧
    2019-06-06
  • Java缓存Map设置过期时间实现解析

    Java缓存Map设置过期时间实现解析

    这篇文章主要介绍了Java缓存Map设置过期时间实现解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-12-12
  • K8S(Docker)如何优雅的关闭SpringBoot微服务

    K8S(Docker)如何优雅的关闭SpringBoot微服务

    这篇文章主要介绍了K8S(Docker)如何优雅的关闭SpringBoot微服务问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-01-01
  • Java中Synchronized的用法解析

    Java中Synchronized的用法解析

    synchronized是Java中的关键字,是一种同步锁,本文给大家详细介绍Java Synchronized 用法大全,感兴趣的朋友跟随小编一起看看吧
    2021-11-11
  • Jasypt的StandardPBEByteEncryptor使用源码解析

    Jasypt的StandardPBEByteEncryptor使用源码解析

    这篇文章主要介绍了Jasypt的StandardPBEByteEncryptor使用源码解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-09-09
  • springboot断点上传、续传、秒传实现方式

    springboot断点上传、续传、秒传实现方式

    这篇文章主要介绍了springboot断点上传、续传、秒传实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-07-07
  • 浅谈Java工程读取resources中资源文件路径的问题

    浅谈Java工程读取resources中资源文件路径的问题

    下面小编就为大家带来一篇浅谈Java工程读取resources中资源文件路径的问题。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-07-07
  • Java jar打包工具使用方法步骤解析

    Java jar打包工具使用方法步骤解析

    这篇文章主要介绍了Java jar打包工具使用方法步骤解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-10-10
  • SpringBoot整合ES高级查询方式

    SpringBoot整合ES高级查询方式

    这篇文章主要介绍了SpringBoot整合ES高级查询方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-05-05
  • Springboot整合Thymeleaf引入公共的CSS和JS文件的方法及注意点

    Springboot整合Thymeleaf引入公共的CSS和JS文件的方法及注意点

    有时候很多css文件是公共的,我们必须要在每个html文件中引入它们,下面这篇文章主要给大家介绍了关于Springboot整合Thymeleaf引入公共的CSS和JS文件的方法及注意点,需要的朋友可以参考下
    2024-06-06

最新评论