Java obtiene información del sistema de los servicios de Linux (uso de CPU, uso de memoria, carga del sistema)

1 código

1.1 Herramientas

Descripción:

  • Para la tasa de uso de la CPU, puede usar el método de la herramienta jdk, pero algunos blogs dicen que no es exacto y no se usa aquí. Se logra a través de / proc / stat.
  • La tasa de uso de memoria se realiza mediante el método de herramientas jdk.
  • La carga del sistema se realiza a través del cálculo utilizando el comando de tiempo de actividad.
import com.sun.management.OperatingSystemMXBean;
import lombok.extern.slf4j.Slf4j;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.lang.management.ManagementFactory;
import java.math.BigDecimal;
import java.util.StringTokenizer;

@Slf4j
public class LinuxInfoUtil {
    private static final String CPU_FILE = "/proc/stat";
    private static final String LOAD_COMMAND = "uptime";

    /**
     * 获得Linux cpu使用率 pcpu =100* (total-idle)/total
     * total = total2-total1
     * idle = idle2 -idle1
     * total1 = user1+nice1+system1+idle1+iowait1+irq1+softirq1+stealstolen1+guest1+guest_nice1
     */
    public static BigDecimal getCpuInfo() {
        try {
            File file = new File(CPU_FILE);
            BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
            StringTokenizer procStatFirstLine = new StringTokenizer(br.readLine());
            CpuInfoBean cpuInfoBean1 = new CpuInfoBean(procStatFirstLine);
            BigDecimal total1 = cpuInfoBean1.getCpuTotal();
            Thread.sleep(1000);
            br = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
            procStatFirstLine = new StringTokenizer(br.readLine());
            CpuInfoBean cpuInfoBean2 = new CpuInfoBean(procStatFirstLine);
            BigDecimal total2 = cpuInfoBean2.getCpuTotal();
            BigDecimal total = total2.subtract(total1);
            BigDecimal idle = cpuInfoBean2.getIdle().subtract(cpuInfoBean1.getIdle());
            BigDecimal pcpu = new BigDecimal(100).multiply(total.subtract(idle)).divide(total, 0, BigDecimal.ROUND_HALF_UP);
            br.close();
            return pcpu;
        } catch (Exception e) {
            log.info(e.toString());
            return new BigDecimal(0);
        }

    }

    // 获取内存使用率
    public static BigDecimal getMemory() {
        OperatingSystemMXBean osmxb = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
        BigDecimal total = new BigDecimal(osmxb.getTotalPhysicalMemorySize());
        BigDecimal free = new BigDecimal(osmxb.getFreePhysicalMemorySize());
        BigDecimal pmem = new BigDecimal(100).multiply(total.subtract(free)).divide(total, 0, BigDecimal.ROUND_HALF_UP);
        return pmem;
    }

    /**
     * 获取系统负载:top的15分钟平均值/(逻辑cpu核数*0.7)
     */
    public static BigDecimal getLoad() {
        try {
            Runtime r = Runtime.getRuntime();
            BigDecimal cpuPerformance = new BigDecimal(0.7).multiply(new BigDecimal(r.availableProcessors()));
            Process pro = r.exec(LOAD_COMMAND);
            BufferedReader br = new BufferedReader(new InputStreamReader(pro.getInputStream()));
            String topLoad = br.readLine();
            BigDecimal load = new BigDecimal(topLoad.substring(topLoad.lastIndexOf(" ")+1));
            BigDecimal pload = new BigDecimal(100).multiply(load).divide(cpuPerformance, 0, BigDecimal.ROUND_HALF_UP);
            br.close();
            pro.destroy();
            return pload;
        } catch (Exception e) {
            log.info(e.toString());
            return new BigDecimal(0);
        }
    }
}

1.2 Frijoles de respaldo

  • El método de construcción es un poco detallado, si tiene una mejor manera, deje un mensaje
import lombok.Data;

import java.math.BigDecimal;
import java.util.StringTokenizer;

@Data
public class CpuInfoBean {
    // /proc/stat中cpu数据10元组
    private BigDecimal user, nice, system, idle, iowait, irq, softirq, stealstolen, guest, guest_nice;

    public CpuInfoBean(StringTokenizer procStatFirstLine) {
        procStatFirstLine.nextToken();
        this.user = procStatFirstLine.hasMoreTokens() ? new BigDecimal(procStatFirstLine.nextToken()) : BigDecimal.ZERO;
        this.nice = procStatFirstLine.hasMoreTokens() ? new BigDecimal(procStatFirstLine.nextToken()) : BigDecimal.ZERO;
        this.system = procStatFirstLine.hasMoreTokens() ? new BigDecimal(procStatFirstLine.nextToken()) : BigDecimal.ZERO;
        this.idle = procStatFirstLine.hasMoreTokens() ? new BigDecimal(procStatFirstLine.nextToken()) : BigDecimal.ZERO;
        this.iowait = procStatFirstLine.hasMoreTokens() ? new BigDecimal(procStatFirstLine.nextToken()) : BigDecimal.ZERO;
        this.irq = procStatFirstLine.hasMoreTokens() ? new BigDecimal(procStatFirstLine.nextToken()) : BigDecimal.ZERO;
        this.softirq = procStatFirstLine.hasMoreTokens() ? new BigDecimal(procStatFirstLine.nextToken()) : BigDecimal.ZERO;
        this.stealstolen = procStatFirstLine.hasMoreTokens() ? new BigDecimal(procStatFirstLine.nextToken()) : BigDecimal.ZERO;
        this.guest = procStatFirstLine.hasMoreTokens() ? new BigDecimal(procStatFirstLine.nextToken()) : BigDecimal.ZERO;
        this.guest_nice = procStatFirstLine.hasMoreTokens() ? new BigDecimal(procStatFirstLine.nextToken()) : BigDecimal.ZERO;
    }

    public BigDecimal getCpuTotal() {
        return user.add(nice).add(system).add(idle).add(iowait).add(irq).add(softirq).add(stealstolen).add(guest).add(guest_nice);
    }
}

2 preguntas

2.1 java usa Runtime.exec para ejecutar comandos de linux sin éxito

2.1.1 Descripción del problema

No se pudo obtener el número de núcleos lógicos de la CPU, el comando es "cat / proc / cpuinfo | procesador grep | wc -l"

2.1.2 Causa del problema

  • Puede ser porque el carácter de tubería "|" hace que el comando falle. No conozco los detalles. Si lo sabe, deje un mensaje y responda.
  • El blogger respondió: La ejecución directa con exec hará que el comando se ejecute como un proceso y los resultados no se pueden consultar. Pero después de usar sh -c, el comando se divide en tres subprocesos a través del símbolo de la tubería y ejecuta "cat / proc / cpuinfo", "procesador grep" y "wc -l" respectivamente, y el resultado del proceso anterior pasa por la tubería como el siguiente. La entrada del proceso, para consultar los resultados específicos.

2.1.3 Solución

解决方式一(采用,有局限性):
    用java自带工具实现Runtime.getRuntime().availableProcessors()
解决方式二:
    命令参数改为数组
    String[] command = {"sh", "-c", "cat /proc/cpuinfo | grep processor | wc -l"};
    或 String[] command = { "/bin/sh", "-c", "cat /proc/cpuinfo | grep processor | wc -l"};

Supongo que te gusta

Origin blog.csdn.net/weixin_45544465/article/details/109296693
Recomendado
Clasificación