Spring Boot 使用 OSHI 实现系统运行状态监控接口
在实际开发中,我们经常需要获取服务器的运行状态,例如:CPU 使用率、内存使用情况、磁盘状态、JVM 运行信息等,以便于运维监控和性能分析。本文将基于 Spring Boot + OSHI 实现一个系统信息接口,可返回当前服务运行的详细信息。
🚀 技术栈
-
Spring Boot
-
OSHI(Operating System and Hardware Information)
-
Java 8+
📦 引入依赖
在你的 pom.xml 中添加如下依赖(建议使用最新版):
<!-- OSHI 获取系统硬件信息 -->
<dependency><groupId>com.github.oshi</groupId><artifactId>oshi-core</artifactId><version>6.4.4</version>
</dependency>
📄 控制器代码
创建一个 SystemInfoController 类,提供一个 /api/system/info 接口,返回系统、JVM、CPU、内存、磁盘等运行信息。
@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);}
}
🔍 接口示例
访问路径:
GET /api/system/info
响应示例:
{"项目运行时间": "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、服务器信息、磁盘空间等,非常适合用于服务健康检查、后台管理系统监控页等场景。
如果你觉得有用,欢迎点赞 👍、收藏 ⭐、评论交流 💬!
如需源码,可在评论区留言获取或私信我~