使用libvirt-java采集KVM虚拟机状态信息
虚拟化开发相较于普通开发是一个冷门的方向,大多数是使用Python开发,其中使用Java来做虚拟化的少之又少,资料更是少的可怜,为了实现需求我也是踩了不少坑,今天就为大家分享一下如何使用 libvirt-java 来采集KVM虚拟机的资源使用信息。 CPU使用率 libvirt并没有直接提供获取虚拟机CPU使用率的接口,需要我们自己来计算,网上分享的代码或者公式五花八门,大部分都是错误的,经过我的测试,找到了一个相对准确的计算公式。 cpu_usage = (cpu_time_now - cpu_time_t_second_ago) * 100 / (t * vCpus * 10^9) Java代码如下 // t秒前的CPU时间 long c1 = domain.getInfo().cpuTime; Thread.sleep(1000); // 当前CPU时间 long c2 = domain.getInfo().cpuTime; // 虚拟CPU数量 int vCpus = domain.getMaxVcpus(); // t 为1秒 Double cpuUsage = 100 * (c2 - c1) / (1 * vCpus * Math.pow(10, 9)); log.debug("虚拟机[{}]CPU使用率为: {}", uuid, cpuUsage); 内存使用率 不要使用domain.getInfo()返回的 memory字段,虽然它注释写的是the memory in KBytes used by the domain,但它的意思真的不是虚拟机内部进程已使用的内存大小,而是从宿主机器的角度来看分配给这个虚拟机的内存它使用了多少,如果没有特殊配置,它会和maxMem字段的值是相同的。 正确做法是使用domain.memoryStats(10)来获取,那为什么参数要输入一个10呢?这是因为10代表的是要返回的信息数量,经过我手动执行virsh dommemstat uuid 测试发现有10个参数返回,所以需要填入10。另外命令返回的unused 字段值与数组中tag=8的数据一致,最终我们获取到了未使用的内存大小,计算内存使用率更是轻轻松松。 Java代码如下 MemoryStatistic[] memoryStatistics = domain.memoryStats(10); Optional<MemoryStatistic> first = Arrays.stream(memoryStatistics).filter(x -> x.getTag() == 8).findFirst(); if (first.isPresent()) { MemoryStatistic memoryStatistic = first.get(); long unusedMemory = memoryStatistic.getValue(); long maxMemory = domain.getMaxMemory(); double memoryUsage = (maxMemory - unusedMemory) * 100.0 / maxMemory; log.debug("虚拟机[{}]内存使用率为: {}", uuid, memoryUsage); } 网卡数据包信息 同样libvirt并没有提供获取虚拟机网卡的接口,因此需要获取虚拟机的xml文件来查询。 ...