在实际开发中,我们经常需要获取服务器的运行状态,例如: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、服务器信息、磁盘空间等,非常适合用于服务健康检查、后台管理系统监控页等场景。
如果你觉得有用,欢迎点赞 👍、收藏 ⭐、评论交流 💬!
如需源码,可在评论区留言获取或私信我~