فهرست منبع

FIX 任务,算法,温度

tjf 2 روز پیش
والد
کامیت
ad8bebfed2

+ 0 - 369
ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/AdvancedSystemMonitor.java

@@ -1,369 +0,0 @@
-package com.ruoyi.framework.web.domain;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileReader;
-import java.io.InputStreamReader;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.TimeUnit;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-public class AdvancedSystemMonitor {
-
-    /**
-     * CPU插槽 0 温度: 48.5°C
-     * CPU插槽 1 温度: 47.2°C
-     * CPU核心 Socket0-Core0 频率: 3.20 GHz
-     * CPU核心 Socket0-Core1 频率: 3.18 GHz
-     * CPU核心 Socket1-Core24 频率: 2.95 GHz
-     * CPU核心 Socket1-Core25 频率: 2.97 GHz
-     * <p>
-     * GPU #0 信息:
-     * 索引: 0
-     * 名称: NVIDIA GeForce RTX 3090
-     * 温度: 62°C
-     * 使用率: 24%
-     * 显存使用: 3456 MB
-     * 总显存: 24564 MB
-     * 功耗: 350.0 W
-     * 功耗限制: 400.0 W
-     * 图形时钟: 1860 MHz
-     * 显存时钟: 1219 MHz
-     * <p>
-     * GPU #1 信息:
-     * 索引: 1
-     * 名称: NVIDIA Tesla V100
-     * 温度: 58°C
-     * 使用率: 45%
-     * 显存使用: 16384 MB
-     * 总显存: 32768 MB
-     * 功耗: 250.0 W
-     * 功耗限制: 300.0 W
-     * 图形时钟: 1380 MHz
-     * 显存时钟: 877 MHz
-     * <p>
-     * 网络速率 (eth0):
-     * 下行: 1.23 Gbps
-     * 上行: 345.67 Mbps
-     */
-    public static String advancedSystem() {
-        try {
-            // 1. 获取所有CPU插槽的温度
-            Map<Integer, Double> cpuTemps = getCpuTemperatures();
-            cpuTemps.forEach((socket, temp) ->
-                    System.out.printf("CPU插槽 %d 温度: %.1f°C\n", socket, temp)
-            );
-
-            // 2. 获取所有CPU核心的实时频率
-            Map<String, Double> cpuFrequencies = getCpuFrequencies();
-            cpuFrequencies.forEach((core, freq) ->
-                    System.out.printf("CPU核心 %s 频率: %.2f GHz\n", core, freq)
-            );
-
-            // 3. 获取所有GPU信息
-            List<Map<String, String>> gpuInfoList = getMultiGpuInfo();
-            for (int i = 0; i < gpuInfoList.size(); i++) {
-                System.out.println("\nGPU #" + i + " 信息:");
-                gpuInfoList.get(i).forEach((key, value) ->
-                        System.out.println("  " + key + ": " + value)
-                );
-            }
-
-            // 4. 获取网络速率
-            String interfaceName = "eth0"; // 替换为你的网卡名称
-            NetworkStats stats1 = getNetworkStats(interfaceName);
-            TimeUnit.SECONDS.sleep(1);
-            NetworkStats stats2 = getNetworkStats(interfaceName);
-
-            long rxRate = (stats2.rxBytes - stats1.rxBytes) * 8; // 比特/秒
-            long txRate = (stats2.txBytes - stats1.txBytes) * 8; // 比特/秒
-
-            System.out.printf("\n网络速率 (%s):\n  下行: %s\n  上行: %s\n",
-                    interfaceName,
-                    formatRate(rxRate),
-                    formatRate(txRate)
-            );
-
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-        return null;
-    }
-
-    // 获取多CPU插槽的温度
-    private static Map<Integer, Double> getCpuTemperatures() throws Exception {
-        Map<Integer, Double> temps = new HashMap<>();
-
-        // 方法1: 通过hwmon获取物理CPU温度
-        File hwmonDir = new File("/sys/class/hwmon/");
-        for (File hwmon : hwmonDir.listFiles()) {
-            try {
-                // 检测是否为CPU温度传感器
-                File nameFile = new File(hwmon, "name");
-                if (!nameFile.exists()) continue;
-
-                try (BufferedReader nameReader = new BufferedReader(new FileReader(nameFile))) {
-                    String name = nameReader.readLine();
-                    if (name == null || !(name.contains("coretemp") || name.contains("k10temp"))) continue;
-
-                    // 查找所有物理CPU的温度
-                    for (int i = 1; i <= 16; i++) {
-                        File tempFile = new File(hwmon, "temp" + i + "_input");
-                        File labelFile = new File(hwmon, "temp" + i + "_label");
-
-                        if (tempFile.exists()) {
-                            // 读取温度标签确定是物理CPU
-                            String label = "Unknown";
-                            if (labelFile.exists()) {
-                                try (BufferedReader labelReader = new BufferedReader(new FileReader(labelFile))) {
-                                    label = labelReader.readLine();
-                                }
-                            }
-
-                            // 只获取物理CPU温度(Package或Tdie)
-                            if (label.contains("Package") || label.contains("Tdie")) {
-                                try (BufferedReader tempReader = new BufferedReader(new FileReader(tempFile))) {
-                                    double temp = Double.parseDouble(tempReader.readLine().trim()) / 1000.0;
-                                    // 提取CPU插槽ID
-                                    int socketId = 0;
-                                    Pattern p = Pattern.compile("(\\d+)");
-                                    Matcher m = p.matcher(label);
-                                    if (m.find()) socketId = Integer.parseInt(m.group());
-
-                                    temps.put(socketId, temp);
-                                }
-                            }
-                        }
-                    }
-                }
-            } catch (Exception e) {
-                // 继续下一个hwmon
-            }
-        }
-
-        // 方法2: 回退到thermal_zone方法
-        if (temps.isEmpty()) {
-            File thermalDir = new File("/sys/class/thermal/");
-            for (File zone : thermalDir.listFiles()) {
-                if (zone.getName().startsWith("thermal_zone")) {
-                    try {
-                        // 检查类型
-                        File typeFile = new File(zone, "type");
-                        if (!typeFile.exists()) continue;
-
-                        try (BufferedReader typeReader = new BufferedReader(new FileReader(typeFile))) {
-                            String type = typeReader.readLine();
-                            if (type == null || !type.contains("x86_pkg_temp")) continue;
-
-                            // 读取温度
-                            File tempFile = new File(zone, "temp");
-                            if (tempFile.exists()) {
-                                try (BufferedReader tempReader = new BufferedReader(new FileReader(tempFile))) {
-                                    double temp = Double.parseDouble(tempReader.readLine().trim()) / 1000.0;
-                                    // 尝试从目录名获取zone ID
-                                    String zoneId = zone.getName().replace("thermal_zone", "");
-                                    temps.put(Integer.parseInt(zoneId), temp);
-                                }
-                            }
-                        }
-                    } catch (Exception e) {
-                        // 忽略错误
-                    }
-                }
-            }
-        }
-
-        if (temps.isEmpty()) throw new Exception("无法检测到CPU温度传感器");
-        return temps;
-    }
-
-    // 获取所有CPU核心频率
-    private static Map<String, Double> getCpuFrequencies() throws Exception {
-        Map<String, Double> frequencies = new HashMap<>();
-        int socketCount = 0;
-        int coreCount = 0;
-
-        // 检测CPU核心
-        File cpuDir = new File("/sys/devices/system/cpu/");
-        for (File file : cpuDir.listFiles()) {
-            if (file.getName().matches("cpu\\d+")) {
-                String coreId = file.getName().replace("cpu", "");
-
-                // 读取实时频率
-                String freqPath = "/sys/devices/system/cpu/cpu" + coreId + "/cpufreq/scaling_cur_freq";
-                File freqFile = new File(freqPath);
-
-                if (freqFile.exists()) {
-                    try (BufferedReader br = new BufferedReader(new FileReader(freqFile))) {
-                        String line = br.readLine();
-                        if (line != null) {
-                            double freq = Double.parseDouble(line.trim()) / 1_000_000.0;
-                            frequencies.put("Socket0-Core" + coreId, freq);
-                        }
-                    }
-                }
-                coreCount++;
-            }
-        }
-
-        // 如果通过sysfs获取失败,尝试从/proc/cpuinfo获取
-        if (frequencies.isEmpty()) {
-            try (BufferedReader br = new BufferedReader(new FileReader("/proc/cpuinfo"))) {
-                String line;
-                int processor = -1;
-                while ((line = br.readLine()) != null) {
-                    if (line.startsWith("processor")) {
-                        String[] parts = line.split(":");
-                        processor = Integer.parseInt(parts[1].trim());
-                    } else if (line.startsWith("cpu MHz")) {
-                        String[] parts = line.split(":");
-                        double freq = Double.parseDouble(parts[1].trim()) / 1000.0;
-                        frequencies.put("Core" + processor, freq);
-                    }
-                }
-            }
-        }
-
-        return frequencies;
-    }
-
-    // 获取多GPU信息
-    private static List<Map<String, String>> getMultiGpuInfo() {
-        List<Map<String, String>> gpuList = new ArrayList<>();
-
-        // 使用nvidia-smi获取多GPU信息
-        try {
-            Process process = Runtime.getRuntime().exec(
-                    "nvidia-smi --query-gpu=index,name,temperature.gpu,utilization.gpu,memory.used,memory.total,power.draw,power.limit,clocks.current.graphics,clocks.current.memory --format=csv,noheader,nounits"
-            );
-
-            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
-            String line;
-            int gpuIndex = 0;
-
-            while ((line = reader.readLine()) != null) {
-                String[] parts = line.split(", ");
-                if (parts.length >= 10) {
-                    Map<String, String> gpuInfo = new HashMap<>();
-                    gpuInfo.put("索引", parts[0].trim());
-                    gpuInfo.put("名称", parts[1].trim());
-                    gpuInfo.put("温度", parts[2].trim() + "°C");
-                    gpuInfo.put("使用率", parts[3].trim() + "%");
-                    gpuInfo.put("显存使用", parts[4].trim() + " MB");
-                    gpuInfo.put("总显存", parts[5].trim() + " MB");
-                    gpuInfo.put("功耗", parts[6].trim() + " W");
-                    gpuInfo.put("功耗限制", parts[7].trim() + " W");
-                    gpuInfo.put("图形时钟", parts[8].trim() + " MHz");
-                    gpuInfo.put("显存时钟", parts[9].trim() + " MHz");
-
-                    gpuList.add(gpuInfo);
-                    gpuIndex++;
-                }
-            }
-
-            // 检查是否有GPU被检测到
-            if (gpuIndex > 0) return gpuList;
-        } catch (Exception e) {
-            System.err.println("nvidia-smi执行错误: " + e.getMessage());
-        }
-
-        // 备用方法:尝试从sysfs读取AMD/集成GPU信息
-        try {
-            File hwmonDir = new File("/sys/class/hwmon/");
-            for (File hwmon : hwmonDir.listFiles()) {
-                try {
-                    // 检测是否为GPU
-                    File nameFile = new File(hwmon, "name");
-                    if (!nameFile.exists()) continue;
-
-                    try (BufferedReader nameReader = new BufferedReader(new FileReader(nameFile))) {
-                        String name = nameReader.readLine();
-                        if (name == null || !(name.contains("amdgpu") || name.contains("radeon"))) continue;
-
-                        Map<String, String> gpuInfo = new HashMap<>();
-                        gpuInfo.put("类型", name);
-
-                        // 读取温度
-                        for (int i = 1; i <= 5; i++) {
-                            File tempFile = new File(hwmon, "temp" + i + "_input");
-                            if (tempFile.exists()) {
-                                try (BufferedReader tempReader = new BufferedReader(new FileReader(tempFile))) {
-                                    double temp = Double.parseDouble(tempReader.readLine().trim()) / 1000.0;
-                                    gpuInfo.put("温度", String.format("%.1f°C", temp));
-                                    break;
-                                }
-                            }
-                        }
-
-                        // 读取功耗(如果可用)
-                        File powerFile = new File(hwmon, "power1_average");
-                        if (powerFile.exists()) {
-                            try (BufferedReader powerReader = new BufferedReader(new FileReader(powerFile))) {
-                                double power = Double.parseDouble(powerReader.readLine().trim()) / 1_000_000.0;
-                                gpuInfo.put("功耗", String.format("%.1f W", power));
-                            }
-                        }
-
-                        gpuList.add(gpuInfo);
-                    }
-                } catch (Exception e) {
-                    // 继续下一个hwmon
-                }
-            }
-        } catch (Exception e) {
-            System.err.println("sysfs读取错误: " + e.getMessage());
-        }
-
-        // 如果没有检测到GPU,添加一个错误信息
-        if (gpuList.isEmpty()) {
-            Map<String, String> errorInfo = new HashMap<>();
-            errorInfo.put("错误", "未检测到GPU或需要安装驱动");
-            gpuList.add(errorInfo);
-        }
-
-        return gpuList;
-    }
-
-    // 网络统计数据结构
-    private static class NetworkStats {
-        long rxBytes;
-        long txBytes;
-    }
-
-    // 获取网络统计信息
-    private static NetworkStats getNetworkStats(String interfaceName) throws Exception {
-        NetworkStats stats = new NetworkStats();
-        File file = new File("/proc/net/dev");
-
-        try (BufferedReader br = new BufferedReader(new FileReader(file))) {
-            String line;
-            while ((line = br.readLine()) != null) {
-                line = line.trim();
-                if (line.startsWith(interfaceName + ":")) {
-                    String[] parts = line.split("\\s+");
-                    stats.rxBytes = Long.parseLong(parts[1]);
-                    stats.txBytes = Long.parseLong(parts[9]);
-                    break;
-                }
-            }
-        }
-        return stats;
-    }
-
-    // 格式化网络速率
-    private static String formatRate(long rateBitsPerSec) {
-        if (rateBitsPerSec < 1000) {
-            return rateBitsPerSec + " bps";
-        } else if (rateBitsPerSec < 1_000_000) {
-            return String.format("%.2f Kbps", rateBitsPerSec / 1000.0);
-        } else if (rateBitsPerSec < 1_000_000_000) {
-            return String.format("%.2f Mbps", rateBitsPerSec / 1_000_000.0);
-        } else {
-            return String.format("%.2f Gbps", rateBitsPerSec / 1_000_000_000.0);
-        }
-    }
-}

+ 466 - 77
ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/Server.java

@@ -13,26 +13,37 @@ import oshi.software.os.OSFileStore;
 import oshi.software.os.OperatingSystem;
 import oshi.util.Util;
 
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.InputStreamReader;
 import java.net.UnknownHostException;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Properties;
-
-import static com.ruoyi.framework.web.domain.AdvancedSystemMonitor.advancedSystem;
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 /**
  * 服务器相关信息
- * 
+ *
  * @author ruoyi
  */
-public class Server
-{
+public class Server {
     private static final int OSHI_WAIT_SECOND = 1000;
-    
+
     /**
      * CPU相关信息
      */
     private Cpu cpu = new Cpu();
+    private List<Cpu> cpuList = new ArrayList<>();
+
+    /**
+     * GPU
+     */
+    private List<Gpu> gpuList = new ArrayList<>();
+    /**
+     * 网络
+     */
+    private List<Network> netWorkList = new ArrayList<>();
 
     /**
      * 內存相关信息
@@ -54,58 +65,71 @@ public class Server
      */
     private List<SysFile> sysFiles = new LinkedList<SysFile>();
 
-    public Cpu getCpu()
-    {
+    public List<Network> getNetWorkList() {
+        return netWorkList;
+    }
+
+    public void setNetWorkList(List<Network> netWorkList) {
+        this.netWorkList = netWorkList;
+    }
+
+    public List<Gpu> getGpuList() {
+        return gpuList;
+    }
+
+    public void setGpuList(List<Gpu> gpuList) {
+        this.gpuList = gpuList;
+    }
+
+    public List<Cpu> getCpuList() {
+        return cpuList;
+    }
+
+    public void setCpuList(List<Cpu> cpuList) {
+        this.cpuList = cpuList;
+    }
+
+    public Cpu getCpu() {
         return cpu;
     }
 
-    public void setCpu(Cpu cpu)
-    {
+    public void setCpu(Cpu cpu) {
         this.cpu = cpu;
     }
 
-    public Mem getMem()
-    {
+    public Mem getMem() {
         return mem;
     }
 
-    public void setMem(Mem mem)
-    {
+    public void setMem(Mem mem) {
         this.mem = mem;
     }
 
-    public Jvm getJvm()
-    {
+    public Jvm getJvm() {
         return jvm;
     }
 
-    public void setJvm(Jvm jvm)
-    {
+    public void setJvm(Jvm jvm) {
         this.jvm = jvm;
     }
 
-    public Sys getSys()
-    {
+    public Sys getSys() {
         return sys;
     }
 
-    public void setSys(Sys sys)
-    {
+    public void setSys(Sys sys) {
         this.sys = sys;
     }
 
-    public List<SysFile> getSysFiles()
-    {
+    public List<SysFile> getSysFiles() {
         return sysFiles;
     }
 
-    public void setSysFiles(List<SysFile> sysFiles)
-    {
+    public void setSysFiles(List<SysFile> sysFiles) {
         this.sysFiles = sysFiles;
     }
 
-    public void copyTo() throws Exception
-    {
+    public void copyTo() throws Exception {
         SystemInfo si = new SystemInfo();
         HardwareAbstractionLayer hal = si.getHardware();
 
@@ -119,40 +143,417 @@ public class Server
 
         setSysFiles(si.getOperatingSystem());
 
-        advancedSystem();
+        setGpuInfo();
+
+        List<String> interfaceNameList = new ArrayList<>();
+        interfaceNameList.add("eno1np0");// 替换为你的网卡名称
+        interfaceNameList.add("eno2np1");// 替换为你的网卡名称
+        for (String interfaceName : interfaceNameList) {
+            Network netWork = new Network();
+            NetworkStats stats1 = getNetworkStats(interfaceName);
+            if (stats1 != null) {
+                Util.sleep(OSHI_WAIT_SECOND);
+                NetworkStats stats2 = getNetworkStats(interfaceName);
+                long rxRate = (stats2.rxBytes - stats1.rxBytes) * 8; // 比特/秒
+                long txRate = (stats2.txBytes - stats1.txBytes) * 8; // 比特/秒
+                netWork.setNetworkName(interfaceName);
+                netWork.setNetworkUp(txRate);
+                netWork.setNetworkDown(rxRate);
+                netWorkList.add(netWork);
+                System.out.printf("\n网络速率 (%s):\n  下行: %s\n  上行: %s\n",
+                        interfaceName,
+                        formatRate(rxRate),
+                        formatRate(txRate)
+                );
+            }
+        }
+    }
+
+    // 网络统计数据结构
+    private static class NetworkStats {
+        long rxBytes;
+        long txBytes;
+    }
+
+    // 获取网络统计信息
+    private static NetworkStats getNetworkStats(String interfaceName) throws Exception {
+        File file = new File("/proc/net/dev");
+        if (file == null || !file.exists()) {
+            return null;
+        }
+        NetworkStats stats = new NetworkStats();
+        try (BufferedReader br = new BufferedReader(new FileReader(file))) {
+            String line;
+            while ((line = br.readLine()) != null) {
+                line = line.trim();
+                if (line.startsWith(interfaceName + ":")) {
+                    String[] parts = line.split("\\s+");
+                    stats.rxBytes = Long.parseLong(parts[1]);
+                    stats.txBytes = Long.parseLong(parts[9]);
+                    break;
+                }
+            }
+        }
+        return stats;
+    }
+
+    // 格式化网络速率
+    private static String formatRate(long rateBitsPerSec) {
+        if (rateBitsPerSec < 1000) {
+            return rateBitsPerSec + " bps";
+        } else if (rateBitsPerSec < 1_000_000) {
+            return String.format("%.2f Kbps", rateBitsPerSec / 1000.0);
+        } else if (rateBitsPerSec < 1_000_000_000) {
+            return String.format("%.2f Mbps", rateBitsPerSec / 1_000_000.0);
+        } else {
+            return String.format("%.2f Gbps", rateBitsPerSec / 1_000_000_000.0);
+        }
+    }
+
+    private void setGpuInfo() {
+        // 3. 获取所有GPU信息
+        List<Map<String, String>> gpuInfoList = getMultiGpuInfo();
+        for (int i = 0; i < gpuInfoList.size(); i++) {
+            Gpu gpu = new Gpu();
+            System.out.println("\nGPU #" + i + " 信息:");
+            for (Map<String, String> stringStringMap : gpuInfoList) {
+                gpu.setName(stringStringMap.get("名称"));
+                gpu.setGpuMemory(stringStringMap.get("总显存"));
+                gpu.setUseMemory(stringStringMap.get("显存使用"));
+                gpu.setUsed(stringStringMap.get("使用率"));
+                gpu.setTemperature(stringStringMap.get("温度"));
+                gpu.setPower(stringStringMap.get("功耗"));
+                gpuList.add(gpu);
+            }
+            gpuInfoList.get(i).forEach((key, value) ->
+                    System.out.println("  " + key + ": " + value)
+            );
+        }
+    }
+
+    // 获取多GPU信息
+    private static List<Map<String, String>> getMultiGpuInfo() {
+        List<Map<String, String>> gpuList = new ArrayList<>();
+
+        // 使用nvidia-smi获取多GPU信息
+        try {
+            Process process = Runtime.getRuntime().exec(
+                    "nvidia-smi --query-gpu=index,name,temperature.gpu,utilization.gpu,memory.used,memory.total,power.draw,power.limit,clocks.current.graphics,clocks.current.memory --format=csv,noheader,nounits"
+            );
+
+            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
+            String line;
+            int gpuIndex = 0;
+
+            while ((line = reader.readLine()) != null) {
+                String[] parts = line.split(", ");
+                if (parts.length >= 10) {
+                    Map<String, String> gpuInfo = new HashMap<>();
+                    gpuInfo.put("索引", parts[0].trim());
+                    gpuInfo.put("名称", parts[1].trim());
+                    gpuInfo.put("温度", parts[2].trim() + "°C");
+                    gpuInfo.put("使用率", parts[3].trim() + "%");
+                    gpuInfo.put("显存使用", parts[4].trim() + " MB");
+                    gpuInfo.put("总显存", parts[5].trim() + " MB");
+                    gpuInfo.put("功耗", parts[6].trim() + " W");
+                    gpuInfo.put("功耗限制", parts[7].trim() + " W");
+                    gpuInfo.put("图形时钟", parts[8].trim() + " MHz");
+                    gpuInfo.put("显存时钟", parts[9].trim() + " MHz");
+                    gpuList.add(gpuInfo);
+                    gpuIndex++;
+                }
+            }
+
+            // 检查是否有GPU被检测到
+            if (gpuIndex > 0) return gpuList;
+        } catch (Exception e) {
+            System.err.println("nvidia-smi执行错误: " + e.getMessage());
+        }
+
+        // 备用方法:尝试从sysfs读取AMD/集成GPU信息
+        try {
+            File hwmonDir = new File("/sys/class/hwmon/");
+            for (File hwmon : hwmonDir.listFiles()) {
+                try {
+                    // 检测是否为GPU
+                    File nameFile = new File(hwmon, "name");
+                    if (!nameFile.exists()) continue;
+
+                    try (BufferedReader nameReader = new BufferedReader(new FileReader(nameFile))) {
+                        String name = nameReader.readLine();
+                        if (name == null || !(name.contains("amdgpu") || name.contains("radeon"))) continue;
+
+                        Map<String, String> gpuInfo = new HashMap<>();
+                        gpuInfo.put("类型", name);
+
+                        // 读取温度
+                        for (int i = 1; i <= 5; i++) {
+                            File tempFile = new File(hwmon, "temp" + i + "_input");
+                            if (tempFile.exists()) {
+                                try (BufferedReader tempReader = new BufferedReader(new FileReader(tempFile))) {
+                                    double temp = Double.parseDouble(tempReader.readLine().trim()) / 1000.0;
+                                    gpuInfo.put("温度", String.format("%.1f°C", temp));
+                                    break;
+                                }
+                            }
+                        }
+
+                        // 读取功耗(如果可用)
+                        File powerFile = new File(hwmon, "power1_average");
+                        if (powerFile.exists()) {
+                            try (BufferedReader powerReader = new BufferedReader(new FileReader(powerFile))) {
+                                double power = Double.parseDouble(powerReader.readLine().trim()) / 1_000_000.0;
+                                gpuInfo.put("功耗", String.format("%.1f W", power));
+                            }
+                        }
+
+                        gpuList.add(gpuInfo);
+                    }
+                } catch (Exception e) {
+                    // 继续下一个hwmon
+                }
+            }
+        } catch (Exception e) {
+            System.err.println("sysfs读取错误: " + e.getMessage());
+        }
+
+        // 如果没有检测到GPU,添加一个错误信息
+        if (gpuList.isEmpty()) {
+            Map<String, String> errorInfo = new HashMap<>();
+            errorInfo.put("错误", "未检测到GPU或需要安装驱动");
+            gpuList.add(errorInfo);
+        }
+
+        return gpuList;
     }
 
     /**
      * 设置CPU信息
      */
-    private void setCpuInfo(CentralProcessor processor)
-    {
-        // CPU信息
-        long[] prevTicks = processor.getSystemCpuLoadTicks();
-        Util.sleep(OSHI_WAIT_SECOND);
-        long[] ticks = processor.getSystemCpuLoadTicks();
-        long nice = ticks[TickType.NICE.getIndex()] - prevTicks[TickType.NICE.getIndex()];
-        long irq = ticks[TickType.IRQ.getIndex()] - prevTicks[TickType.IRQ.getIndex()];
-        long softirq = ticks[TickType.SOFTIRQ.getIndex()] - prevTicks[TickType.SOFTIRQ.getIndex()];
-        long steal = ticks[TickType.STEAL.getIndex()] - prevTicks[TickType.STEAL.getIndex()];
-        long cSys = ticks[TickType.SYSTEM.getIndex()] - prevTicks[TickType.SYSTEM.getIndex()];
-        long user = ticks[TickType.USER.getIndex()] - prevTicks[TickType.USER.getIndex()];
-        long iowait = ticks[TickType.IOWAIT.getIndex()] - prevTicks[TickType.IOWAIT.getIndex()];
-        long idle = ticks[TickType.IDLE.getIndex()] - prevTicks[TickType.IDLE.getIndex()];
-        long totalCpu = user + nice + cSys + idle + iowait + irq + softirq + steal;
-        cpu.setCpuNum(processor.getLogicalProcessorCount());
-        cpu.setTotal(totalCpu);
-        cpu.setSys(cSys);
-        cpu.setUsed(user);
-        cpu.setWait(iowait);
-        cpu.setFree(idle);
+    private void setCpuInfo(CentralProcessor processor) {
+        // 1. 获取物理CPU数量
+        int physicalPackageCount = processor.getPhysicalPackageCount();
+        System.out.println("物理CPU数量: " + physicalPackageCount);
+        if (physicalPackageCount < 2) {
+            // CPU信息
+            long[] prevTicks = processor.getSystemCpuLoadTicks();
+            Util.sleep(OSHI_WAIT_SECOND);
+            long[] ticks = processor.getSystemCpuLoadTicks();
+            long nice = ticks[TickType.NICE.getIndex()] - prevTicks[TickType.NICE.getIndex()];
+            long irq = ticks[TickType.IRQ.getIndex()] - prevTicks[TickType.IRQ.getIndex()];
+            long softirq = ticks[TickType.SOFTIRQ.getIndex()] - prevTicks[TickType.SOFTIRQ.getIndex()];
+            long steal = ticks[TickType.STEAL.getIndex()] - prevTicks[TickType.STEAL.getIndex()];
+            long cSys = ticks[TickType.SYSTEM.getIndex()] - prevTicks[TickType.SYSTEM.getIndex()];
+            long user = ticks[TickType.USER.getIndex()] - prevTicks[TickType.USER.getIndex()];
+            long iowait = ticks[TickType.IOWAIT.getIndex()] - prevTicks[TickType.IOWAIT.getIndex()];
+            long idle = ticks[TickType.IDLE.getIndex()] - prevTicks[TickType.IDLE.getIndex()];
+            long totalCpu = user + nice + cSys + idle + iowait + irq + softirq + steal;
+            cpu.setCpuNum(processor.getLogicalProcessorCount());
+            cpu.setTotal(totalCpu);
+            cpu.setSys(cSys);
+            cpu.setUsed(user);
+            cpu.setWait(iowait);
+            cpu.setFree(idle);
+            cpuList.add(cpu);
+        } else {
+            // 2分组方法:使用物理处理器编号分组
+            Map<Integer, List<CentralProcessor.LogicalProcessor>> cpuGroups = new HashMap<>();
+            for (CentralProcessor.LogicalProcessor lp : processor.getLogicalProcessors()) {
+                int packageId = lp.getPhysicalProcessorNumber() % physicalPackageCount;
+                cpuGroups.computeIfAbsent(packageId, k -> new ArrayList<>()).add(lp);
+            }
+
+            // 3. 获取初始CPU滴答计数
+            long[] initialSystemTicks = processor.getSystemCpuLoadTicks();
+
+            // 4. 等待1秒获取新数据
+            Util.sleep(OSHI_WAIT_SECOND);
+
+            // 5. 获取新的CPU滴答计数
+            long[] newSystemTicks = processor.getSystemCpuLoadTicks();
+
+            // 6. 计算并显示每个物理CPU的数据
+            for (int pkgId = 0; pkgId < physicalPackageCount; pkgId++) {
+                Cpu cpuOne = new Cpu();
+                if (!cpuGroups.containsKey(pkgId)) continue;
+                System.out.println("\n===== 物理CPU " + (pkgId + 1) + " 数据 =====");
+                System.out.println("包含的逻辑处理器数量: " + cpuGroups.get(pkgId).size());
+                cpuOne.setCpuNum(cpuGroups.get(pkgId).size());
+                // 计算该物理CPU的负载
+                double load = calculateCpuLoad(initialSystemTicks, newSystemTicks);
+                System.out.printf("总负载: %.1f%%\n", load * 100);
+                cpuOne.setTotal(load * 100);
+                cpuOne.setSys(newSystemTicks[CentralProcessor.TickType.SYSTEM.getIndex()]);
+                cpuOne.setUsed(newSystemTicks[CentralProcessor.TickType.USER.getIndex()]);
+                cpuOne.setWait(newSystemTicks[CentralProcessor.TickType.IOWAIT.getIndex()]);
+                cpuOne.setFree(newSystemTicks[CentralProcessor.TickType.IDLE.getIndex()]);
+                // 显示详细负载数据
+                printCpuLoadDetails(newSystemTicks);
+                cpuList.add(cpuOne);
+            }
+        }
+        // 1. 获取所有CPU插槽的温度
+        Map<Integer, Double> cpuTemps = getCpuTemperatures();
+        if (cpuTemps != null) {
+            for (Integer socket : cpuTemps.keySet()) {
+                Double temp = cpuTemps.get(socket);
+                cpuList.get(socket).setTemperature(temp);
+                System.out.printf("CPU插槽 %d 温度: %.1f°C\n", socket, temp);
+            }
+        }
+    }
+
+    // 获取双CPU温度
+    private static Map<Integer, Double> getCpuTemperatures() {
+        Map<Integer, Double> temps = new HashMap<>();
+
+        // 方法1: 使用sensors命令(最可靠)
+        try {
+            Process process = Runtime.getRuntime().exec("sensors");
+            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
+            String line;
+
+            while ((line = reader.readLine()) != null) {
+                // 匹配物理CPU的温度(Package或Tdie)
+                if (line.contains("Package id") || line.contains("Tdie") || line.contains("Tccd1")) {
+                    // 提取温度值
+                    Pattern tempPattern = Pattern.compile("\\+([\\d\\.]+)°C");
+                    Matcher matcher = tempPattern.matcher(line);
+                    if (matcher.find()) {
+                        double temp = Double.parseDouble(matcher.group(1));
+
+                        // 提取CPU插槽ID
+                        Pattern socketPattern = Pattern.compile("id\\s*(\\d+)");
+                        Matcher socketMatcher = socketPattern.matcher(line);
+                        int socketId = socketMatcher.find() ? Integer.parseInt(socketMatcher.group(1)) : 0;
+
+                        temps.put(socketId, temp);
+                    }
+                }
+            }
+
+            if (!temps.isEmpty()) return temps;
+        } catch (Exception e) {
+            System.err.println("sensors命令执行错误: " + e.getMessage());
+        }
+
+        // 方法2: 通过hwmon接口获取
+        try {
+            File hwmonDir = new File("/sys/class/hwmon/");
+            for (File hwmon : hwmonDir.listFiles()) {
+                try {
+                    // 检测是否为CPU温度传感器
+                    File nameFile = new File(hwmon, "name");
+                    if (!nameFile.exists()) continue;
+
+                    try (BufferedReader nameReader = new BufferedReader(new FileReader(nameFile))) {
+                        String name = nameReader.readLine();
+                        if (name == null || !(name.contains("coretemp") || name.contains("k10temp"))) continue;
+
+                        // 查找所有物理CPU的温度
+                        for (int i = 1; i <= 16; i++) {
+                            File tempFile = new File(hwmon, "temp" + i + "_input");
+                            File labelFile = new File(hwmon, "temp" + i + "_label");
+
+                            if (tempFile.exists() && labelFile.exists()) {
+                                // 读取温度标签确定是物理CPU
+                                String label;
+                                try (BufferedReader labelReader = new BufferedReader(new FileReader(labelFile))) {
+                                    label = labelReader.readLine();
+                                }
+
+                                // 只获取物理CPU温度(Package或Tdie)
+                                if (label != null && (label.contains("Package") || label.contains("Tdie"))) {
+                                    try (BufferedReader tempReader = new BufferedReader(new FileReader(tempFile))) {
+                                        double temp = Double.parseDouble(tempReader.readLine().trim()) / 1000.0;
+                                        // 提取CPU插槽ID
+                                        int socketId = 0;
+                                        Pattern p = Pattern.compile("(\\d+)");
+                                        Matcher m = p.matcher(label);
+                                        if (m.find()) socketId = Integer.parseInt(m.group());
+
+                                        temps.put(socketId, temp);
+                                    }
+                                }
+                            }
+                        }
+                    }
+                } catch (Exception e) {
+                    // 继续下一个hwmon
+                }
+            }
+
+            if (!temps.isEmpty()) return temps;
+        } catch (Exception e) {
+            System.err.println("hwmon接口访问错误: " + e.getMessage());
+        }
+
+        // 方法3: 通过thermal_zone获取
+        try {
+            File thermalDir = new File("/sys/class/thermal/");
+            int socketCount = 0;
+
+            for (File zone : thermalDir.listFiles()) {
+                if (zone.getName().startsWith("thermal_zone")) {
+                    // 检查类型
+                    File typeFile = new File(zone, "type");
+                    if (!typeFile.exists()) continue;
+
+                    try (BufferedReader typeReader = new BufferedReader(new FileReader(typeFile))) {
+                        String type = typeReader.readLine();
+                        if (type == null || !(type.contains("x86_pkg_temp") || type.contains("acpitz"))) continue;
+
+                        // 读取温度
+                        File tempFile = new File(zone, "temp");
+                        if (tempFile.exists()) {
+                            try (BufferedReader tempReader = new BufferedReader(new FileReader(tempFile))) {
+                                double temp = Double.parseDouble(tempReader.readLine().trim()) / 1000.0;
+                                temps.put(socketCount++, temp);
+                            }
+                        }
+                    }
+                }
+            }
+
+            if (!temps.isEmpty()) return temps;
+        } catch (Exception e) {
+            System.err.println("thermal_zone访问错误: " + e.getMessage());
+        }
+        System.out.println("无法检测到CPU温度传感器");
+        return temps;
+    }
+
+    private static void printCpuLoadDetails(long[] ticks) {
+        System.out.println("详细负载数据:");
+        System.out.printf("  User:   %d\n", ticks[CentralProcessor.TickType.USER.getIndex()]);
+        System.out.printf("  Nice:   %d\n", ticks[CentralProcessor.TickType.NICE.getIndex()]);
+        System.out.printf("  System: %d\n", ticks[CentralProcessor.TickType.SYSTEM.getIndex()]);
+        System.out.printf("  Idle:   %d\n", ticks[CentralProcessor.TickType.IDLE.getIndex()]);
+        System.out.printf("  IOWait: %d\n", ticks[CentralProcessor.TickType.IOWAIT.getIndex()]);
+        System.out.printf("  IRQ:    %d\n", ticks[CentralProcessor.TickType.IRQ.getIndex()]);
+        System.out.printf("  SoftIRQ:%d\n", ticks[CentralProcessor.TickType.SOFTIRQ.getIndex()]);
+        System.out.printf("  Steal:  %d\n", ticks[CentralProcessor.TickType.STEAL.getIndex()]);
+    }
+
+    private static double calculateCpuLoad(long[] initialTicks, long[] newTicks) {
+        long user = newTicks[CentralProcessor.TickType.USER.getIndex()] - initialTicks[CentralProcessor.TickType.USER.getIndex()];
+        long nice = newTicks[CentralProcessor.TickType.NICE.getIndex()] - initialTicks[CentralProcessor.TickType.NICE.getIndex()];
+        long system = newTicks[CentralProcessor.TickType.SYSTEM.getIndex()] - initialTicks[CentralProcessor.TickType.SYSTEM.getIndex()];
+        long idle = newTicks[CentralProcessor.TickType.IDLE.getIndex()] - initialTicks[CentralProcessor.TickType.IDLE.getIndex()];
+        long iowait = newTicks[CentralProcessor.TickType.IOWAIT.getIndex()] - initialTicks[CentralProcessor.TickType.IOWAIT.getIndex()];
+        long irq = newTicks[CentralProcessor.TickType.IRQ.getIndex()] - initialTicks[CentralProcessor.TickType.IRQ.getIndex()];
+        long softirq = newTicks[CentralProcessor.TickType.SOFTIRQ.getIndex()] - initialTicks[CentralProcessor.TickType.SOFTIRQ.getIndex()];
+        long steal = newTicks[CentralProcessor.TickType.STEAL.getIndex()] - initialTicks[CentralProcessor.TickType.STEAL.getIndex()];
+        long totalUsed = user + nice + system + irq + softirq + steal;
+        long total = totalUsed + idle + iowait;
+
+        return total > 0 ? (double) totalUsed / total : 0;
     }
 
     /**
      * 设置内存信息
      */
-    private void setMemInfo(GlobalMemory memory)
-    {
+    private void setMemInfo(GlobalMemory memory) {
         mem.setTotal(memory.getTotal());
         mem.setUsed(memory.getTotal() - memory.getAvailable());
         mem.setFree(memory.getAvailable());
@@ -161,8 +562,7 @@ public class Server
     /**
      * 设置服务器信息
      */
-    private void setSysInfo()
-    {
+    private void setSysInfo() {
         Properties props = System.getProperties();
         sys.setComputerName(IpUtils.getHostName());
         sys.setComputerIp(IpUtils.getHostIp());
@@ -174,8 +574,7 @@ public class Server
     /**
      * 设置Java虚拟机
      */
-    private void setJvmInfo() throws UnknownHostException
-    {
+    private void setJvmInfo() throws UnknownHostException {
         Properties props = System.getProperties();
         jvm.setTotal(Runtime.getRuntime().totalMemory());
         jvm.setMax(Runtime.getRuntime().maxMemory());
@@ -187,12 +586,10 @@ public class Server
     /**
      * 设置磁盘信息
      */
-    private void setSysFiles(OperatingSystem os)
-    {
+    private void setSysFiles(OperatingSystem os) {
         FileSystem fileSystem = os.getFileSystem();
         List<OSFileStore> fsArray = fileSystem.getFileStores();
-        for (OSFileStore fs : fsArray)
-        {
+        for (OSFileStore fs : fsArray) {
             long free = fs.getUsableSpace();
             long total = fs.getTotalSpace();
             long used = total - free;
@@ -210,31 +607,23 @@ public class Server
 
     /**
      * 字节转换
-     * 
+     *
      * @param size 字节大小
      * @return 转换后值
      */
-    public String convertFileSize(long size)
-    {
+    public String convertFileSize(long size) {
         long kb = 1024;
         long mb = kb * 1024;
         long gb = mb * 1024;
-        if (size >= gb)
-        {
+        if (size >= gb) {
             return String.format("%.1f GB", (float) size / gb);
-        }
-        else if (size >= mb)
-        {
+        } else if (size >= mb) {
             float f = (float) size / mb;
             return String.format(f > 100 ? "%.0f MB" : "%.1f MB", f);
-        }
-        else if (size >= kb)
-        {
+        } else if (size >= kb) {
             float f = (float) size / kb;
             return String.format(f > 100 ? "%.0f KB" : "%.1f KB", f);
-        }
-        else
-        {
+        } else {
             return String.format("%d B", size);
         }
     }

+ 12 - 0
ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/server/Cpu.java

@@ -38,6 +38,18 @@ public class Cpu
      * CPU当前空闲率
      */
     private double free;
+    /**
+     * CPU温度
+     */
+    private double temperature;
+
+    public double getTemperature() {
+        return temperature;
+    }
+
+    public void setTemperature(double temperature) {
+        this.temperature = temperature;
+    }
 
     public int getCpuNum()
     {

+ 83 - 0
ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/server/Gpu.java

@@ -0,0 +1,83 @@
+package com.ruoyi.framework.web.domain.server;
+
+/**
+ * @Author: tjf
+ * @Date: 2025/8/13 星期三 15:19
+ * @Describe:
+ */
+public class Gpu {
+
+    /**
+     * 总显存
+     */
+    private String gpuMemory;
+    /**
+     * 使用率
+     */
+    private String used;
+    /**
+     * 显存使用
+     */
+    private String useMemory;
+    /**
+     * 名称
+     */
+    private String name;
+    /**
+     * 功耗
+     */
+    private String power;
+
+    /**
+     * GPU温度
+     */
+    private String temperature;
+
+    public String getGpuMemory() {
+        return gpuMemory;
+    }
+
+    public void setGpuMemory(String gpuMemory) {
+        this.gpuMemory = gpuMemory;
+    }
+
+    public String getUsed() {
+        return used;
+    }
+
+    public void setUsed(String used) {
+        this.used = used;
+    }
+
+    public String getUseMemory() {
+        return useMemory;
+    }
+
+    public void setUseMemory(String useMemory) {
+        this.useMemory = useMemory;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getPower() {
+        return power;
+    }
+
+    public void setPower(String power) {
+        this.power = power;
+    }
+
+    public String getTemperature() {
+        return temperature;
+    }
+
+    public void setTemperature(String temperature) {
+        this.temperature = temperature;
+    }
+}

+ 46 - 0
ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/server/Network.java

@@ -0,0 +1,46 @@
+package com.ruoyi.framework.web.domain.server;
+
+/**
+ * @Author: tjf
+ * @Date: 2025/8/13 星期三 15:26
+ * @Describe:
+ */
+public class Network {
+    /**
+     * 上行
+     */
+    private double networkUp;
+    /**
+     * 下行
+     */
+    private double networkDown;
+    /**
+     * 名称
+     */
+    private String networkName;
+
+
+    public double getNetworkUp() {
+        return networkUp;
+    }
+
+    public void setNetworkUp(double networkUp) {
+        this.networkUp = networkUp;
+    }
+
+    public double getNetworkDown() {
+        return networkDown;
+    }
+
+    public void setNetworkDown(double networkDown) {
+        this.networkDown = networkDown;
+    }
+
+    public String getNetworkName() {
+        return networkName;
+    }
+
+    public void setNetworkName(String networkName) {
+        this.networkName = networkName;
+    }
+}