JavaはLinuxサービスのシステム情報(cpu使用量、メモリ使用量、システム負荷)を取得します

1コード

1.1ツール

説明:

  • cpuの使用法については、jdkツールメソッドを使用できますが、一部のブログでは、正確ではなく、ここでは使用されていないと述べています。これは、/ proc / statを介して実現されます。
  • メモリ使用率は、jdkツールの方法で実現されます。
  • システム負荷は、uptimeコマンドを使用した計算によって実現されます。
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バッキングビーンズ

  • 工法は少し冗長ですが、もっと良い方法があればメッセージを残してください
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つの質問

2.1javaはRuntime.execを使用してlinuxコマンドを正常に実行しません

2.1.1問題の説明

cpu論理コアの数を取得できませんでした。コマンドは「cat / proc / cpuinfo | grepprocessor | wc-l」です。

2.1.2問題の原因

  • パイプ文字「|」が原因でコマンドが失敗する場合があります。詳細はわかりません。ブロガーがいる場合は、メッセージを残して返信してください。
  • ブロガーは次のように答えました。execを使用して直接実行すると、コマンドがプロセスとして実行され、結果を照会できません。ただし、sh -cを使用した後、コマンドはパイプシンボルを介して3つのサブプロセスに分割され、それぞれ「cat / proc / cpuinfo」、「grepprocessor」、および「wc -l」を実行し、前のプロセスの結果が次のプロセスとしてパイプを通過します。特定の結果を照会するためのプロセスの入力。

2.1.3解決策

解决方式一(采用,有局限性):
    用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"};

おすすめ

転載: blog.csdn.net/weixin_45544465/article/details/109296693