Spring Boot 使用 OSHI 实现系统运行状态监控接口

在实际开发中,我们经常需要获取服务器的运行状态,例如:CPU 使用率、内存使用情况、磁盘状态、JVM 运行信息等,以便于运维监控和性能分析。本文将基于 Spring Boot + OSHI 实现一个系统信息接口,可返回当前服务运行的详细信息。

🚀 技术栈

  • Spring Boot

  • OSHI(Operating System and Hardware Information)

  • Java 8+

📦 引入依赖

在你的 pom.xml 中添加如下依赖(建议使用最新版):

java 复制代码
<!-- OSHI 获取系统硬件信息 -->
<dependency>
    <groupId>com.github.oshi</groupId>
    <artifactId>oshi-core</artifactId>
    <version>6.4.4</version>
</dependency>

📄 控制器代码

创建一个 SystemInfoController 类,提供一个 /api/system/info 接口,返回系统、JVM、CPU、内存、磁盘等运行信息。

java 复制代码
@RestController
@RequestMapping("/api/system")
public class SystemInfoController {

    private final long startTime = System.currentTimeMillis();

    @GetMapping("info")
    public Map<String, Object> getSystemInfo() {
        Map<String, Object> result = new LinkedHashMap<>();

        // 运行时长
        long uptimeMillis = System.currentTimeMillis() - startTime;
        result.put("项目运行时间", formatDuration(uptimeMillis));

        SystemInfo si = new SystemInfo();
        HardwareAbstractionLayer hal = si.getHardware();
        OperatingSystem os = si.getOperatingSystem();

        // CPU 信息
        CentralProcessor processor = hal.getProcessor();
        Map<String, Object> cpu = new LinkedHashMap<>();
        int coreCount = processor.getLogicalProcessorCount();
        long[] ticks1 = processor.getSystemCpuLoadTicks();
        try { Thread.sleep(1000); } catch (InterruptedException ignored) {}
        long[] ticks2 = processor.getSystemCpuLoadTicks();

        long user = ticks2[CentralProcessor.TickType.USER.getIndex()] - ticks1[CentralProcessor.TickType.USER.getIndex()];
        long system = ticks2[CentralProcessor.TickType.SYSTEM.getIndex()] - ticks1[CentralProcessor.TickType.SYSTEM.getIndex()];
        long idle = ticks2[CentralProcessor.TickType.IDLE.getIndex()] - ticks1[CentralProcessor.TickType.IDLE.getIndex()];
        long total = Arrays.stream(ticks2).sum() - Arrays.stream(ticks1).sum();

        cpu.put("核心数", coreCount);
        cpu.put("用户使用率", String.format("%.2f%%", user * 100.0 / total));
        cpu.put("系统使用率", String.format("%.2f%%", system * 100.0 / total));
        cpu.put("当前空闲率", String.format("%.2f%%", idle * 100.0 / total));
        result.put("CPU", cpu);

        // 内存信息
        GlobalMemory memory = hal.getMemory();
        Map<String, Object> mem = new LinkedHashMap<>();
        long totalMem = memory.getTotal();
        long available = memory.getAvailable();
        long used = totalMem - available;
        mem.put("总内存", FormatUtil.formatBytes(totalMem));
        mem.put("已用内存", FormatUtil.formatBytes(used));
        mem.put("剩余内存", FormatUtil.formatBytes(available));
        mem.put("使用率", String.format("%.2f%%", used * 100.0 / totalMem));
        result.put("内存", mem);

        // JVM 信息
        RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean();
        Map<String, Object> jvm = new LinkedHashMap<>();
        jvm.put("JVM名称", runtime.getVmName());
        jvm.put("Java版本", System.getProperty("java.version"));
        jvm.put("启动时间", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(runtime.getStartTime())));
        jvm.put("运行时长", formatDuration(uptimeMillis));
        jvm.put("运行路径", System.getProperty("user.dir"));
        jvm.put("启动类路径", System.getProperty("java.class.path"));
        jvm.put("启动参数", runtime.getInputArguments());
        result.put("JVM", jvm);

        // 服务器信息
        Map<String, Object> server = new LinkedHashMap<>();
        try {
            server.put("服务器名称", InetAddress.getLocalHost().getHostName());
            server.put("服务器IP", InetAddress.getLocalHost().getHostAddress());
        } catch (Exception e) {
            server.put("服务器名称", "未知");
            server.put("服务器IP", "未知");
        }
        server.put("操作系统", os.toString());
        server.put("系统架构", System.getProperty("os.arch"));
        result.put("服务器信息", server);

        // 磁盘信息
        FileSystem fileSystem = os.getFileSystem();
        List<OSFileStore> fileStores = fileSystem.getFileStores();
        List<Map<String, String>> disks = new ArrayList<>();
        for (OSFileStore fs : fileStores) {
            Map<String, String> disk = new LinkedHashMap<>();
            disk.put("盘符路径", fs.getMount());
            disk.put("类型", fs.getType());
            disk.put("总大小", FormatUtil.formatBytes(fs.getTotalSpace()));
            disk.put("可用空间", FormatUtil.formatBytes(fs.getUsableSpace()));
            disks.add(disk);
        }
        result.put("磁盘状态", disks);

        return result;
    }

    // 格式化运行时长
    private String formatDuration(long uptimeMillis) {
        long seconds = uptimeMillis / 1000;
        long days = seconds / (3600 * 24);
        long hours = (seconds % (3600 * 24)) / 3600;
        long minutes = (seconds % 3600) / 60;
        return String.format("%d天%d小时%d分钟", days, hours, minutes);
    }
}

🔍 接口示例

访问路径:

java 复制代码
GET /api/system/info

响应示例:

java 复制代码
{
  "项目运行时间": "0天1小时23分钟",
  "CPU": {
    "核心数": 8,
    "用户使用率": "3.57%",
    "系统使用率": "1.29%",
    "当前空闲率": "94.31%"
  },
  "内存": {
    "总内存": "16.0 GiB",
    "已用内存": "8.2 GiB",
    "剩余内存": "7.8 GiB",
    "使用率": "51.33%"
  },
  "JVM": {
    "JVM名称": "OpenJDK 64-Bit Server VM",
    "Java版本": "17",
    "启动时间": "2025-05-13 08:00:00",
    "运行时长": "0天2小时10分钟",
    "运行路径": "/app",
    "启动类路径": "...",
    "启动参数": [...]
  },
  "服务器信息": {
    "服务器名称": "server-01",
    "服务器IP": "192.168.1.10",
    "操作系统": "Linux 5.15.0-1051-azure",
    "系统架构": "amd64"
  },
  "磁盘状态": [
    {
      "盘符路径": "/",
      "类型": "ext4",
      "总大小": "100.0 GiB",
      "可用空间": "62.5 GiB"
    }
  ]
}

📌 总结

本文介绍了如何使用 OSHI 在 Spring Boot 项目中快速构建一个系统运行状态接口,包括 CPU、内存、JVM、服务器信息、磁盘空间等,非常适合用于服务健康检查、后台管理系统监控页等场景。

如果你觉得有用,欢迎点赞 👍、收藏 ⭐、评论交流 💬!

如需源码,可在评论区留言获取或私信我~

相关推荐
意倾城2 分钟前
浅说MyBatis-Plus 的 saveBatch 方法
java·mybatis
景天科技苑2 分钟前
【Rust泛型】Rust泛型使用详解与应用场景
开发语言·后端·rust·泛型·rust泛型
JANYI20187 分钟前
C语言易混淆知识点详解
java·c语言·算法
I_itaiit16 分钟前
Spring Boot之Web服务器的启动流程分析
spring boot·nettywebserver·httphandler·webhandler
.生产的驴1 小时前
Maven 公司内部私服中央仓库搭建 局域网仓库 资源共享 依赖包构建共享
java·maven
Auc241 小时前
OJ判题系统第6期之判题逻辑开发——设计思路、实现步骤、代码实现(策略模式)
java·开发语言·docker·容器·策略模式
老李不敲代码1 小时前
榕壹云搭子系统技术解析:基于Spring Boot+MySQL+UniApp的同城社交平台开发实践
spring boot·mysql·微信小程序·uni-app·软件需求
快乐肚皮1 小时前
深入解析Docker:核心架构与最佳实践
java·运维·docker·容器
zhou1852 小时前
MySQL保姆级安装教程(附资源包+5分钟极速配置+环境变量调试技巧)
java·python·mysql·php
小雅痞2 小时前
[Java][Leetcode middle] 55. 跳跃游戏
java·leetcode