使用VMware VSphere WebService SDK进行开发 (二)——获取虚拟机cpu的使用情况

使用VMware VSphere WebService SDK进行开发 (二)——获取虚拟机cpu的使用情况

本文通过代码举例虚拟机cpu的使用情况来演示如何遍历搜寻VirtualMachine的对象,以及根据这个对象进行性能指标的见识。希望可以取到举一反三的效果。

首先下面先罗列出如何更具虚拟机的名称获得VirtualMachine的ManagedObjectReference对象。

private static TraversalSpec getVmTraversalSpec()
{
TraversalSpec vAppToVM = new TraversalSpec();
vAppToVM.setName("vAppToVM");
vAppToVM.setType("VirtualApp");
vAppToVM.setPath("vm");

TraversalSpec vAppToVApp = new TraversalSpec();
vAppToVApp.setName("vAppToVApp");
vAppToVApp.setType("VirtualApp");
vAppToVApp.setPath("resourcePool");

SelectionSpec vAppRecursion = new SelectionSpec();
vAppRecursion.setName("vAppToVApp");
SelectionSpec vmInVApp = new SelectionSpec();
vmInVApp.setName("vAppToVM");
List<SelectionSpec> vAppToVMSS = new ArrayList<SelectionSpec>();
vAppToVMSS.add(vAppRecursion);
vAppToVMSS.add(vmInVApp);
vAppToVApp.getSelectSet().addAll(vAppToVMSS);

SelectionSpec sSpec = new SelectionSpec();
sSpec.setName("VisitFolders");

TraversalSpec dataCenterToVMFolder = new TraversalSpec();
dataCenterToVMFolder.setName("DataCenterToVMFolder");
dataCenterToVMFolder.setType("Datacenter");
dataCenterToVMFolder.setPath("vmFolder");
dataCenterToVMFolder.setSkip(false);
dataCenterToVMFolder.getSelectSet().add(sSpec);

TraversalSpec traversalSpec = new TraversalSpec();
traversalSpec.setName("VisitFolders");
traversalSpec.setType("Folder");
traversalSpec.setPath("childEntity");
traversalSpec.setSkip(false);
List<SelectionSpec> sSpecArr = new ArrayList<SelectionSpec>();
sSpecArr.add(sSpec);
sSpecArr.add(dataCenterToVMFolder);
sSpecArr.add(vAppToVM);
sSpecArr.add(vAppToVApp);
traversalSpec.getSelectSet().addAll(sSpecArr);
return traversalSpec;
}
private static ManagedObjectReference getVmByVmName(String vmName)
{
ManagedObjectReference retVal = null;
ManagedObjectReference rootFolder = serviceContent.getRootFolder();
try
{
TraversalSpec tSpec = getVmTraversalSpec();
PropertySpec propertySpec = new PropertySpec();
propertySpec.setAll(Boolean.FALSE);
propertySpec.getPathSet().add("name");
propertySpec.setType("VirtualMachine");

ObjectSpec objectSpec = new ObjectSpec();
objectSpec.setObj(rootFolder);
objectSpec.setSkip(Boolean.TRUE);
objectSpec.getSelectSet().add(tSpec);

PropertyFilterSpec propertyFilterSpec = new PropertyFilterSpec();
propertyFilterSpec.getPropSet().add(propertySpec);
propertyFilterSpec.getObjectSet().add(objectSpec);

List<PropertyFilterSpec> listpfs = new ArrayList<PropertyFilterSpec>(1);
listpfs.add(propertyFilterSpec);
List<ObjectContent> listobjcont = retrievePropertiesAllObjects(listpfs);

if (listobjcont != null)
{
for (ObjectContent oc : listobjcont)
{
ManagedObjectReference mr = oc.getObj();
String vmnm = null;
List<DynamicProperty> dps = oc.getPropSet();
if (dps != null)
{
for (DynamicProperty dp : dps)
{
vmnm = (String) dp.getVal();
}
}
if (vmnm != null && vmnm.equals(vmName))
{
retVal = mr;
break;
}
}
}
}
catch (SOAPFaultException sfe)
{
printSoapFaultException(sfe);
}
catch (Exception e)
{
e.printStackTrace();
}
return retVal;
}

然后根据上面的VirtualMachine的ManagedObjectReference对象获取虚拟机的实时性能信息:

private static List<List<Long>> getVmData(String vmName, String nameInfo, String groupInfo) throws RuntimeFaultFaultMsg, DatatypeConfigurationException
{
List<List<Long>> list = new ArrayList<List<Long>>();
ManagedObjectReference vmmor = getVmByVmName(vmName);
if (vmmor != null)
{
List<PerfCounterInfo> cInfo = getPerfCounters();

int i = 0;
Map<Integer, PerfCounterInfo> counters = new HashMap<Integer, PerfCounterInfo>();
for (Iterator<PerfCounterInfo> it = cInfo.iterator(); it.hasNext();)
{
PerfCounterInfo pcInfo = (PerfCounterInfo) it.next();
counters.put(new Integer(pcInfo.getKey()), pcInfo);
}

List<PerfMetricId> listpermeid = vimPort.queryAvailablePerfMetric(perfManager, vmmor, null, null, new Integer(20));
ArrayList<PerfMetricId> mMetrics = new ArrayList<PerfMetricId>();
if (listpermeid != null)
{
for (int index = 0; index < listpermeid.size(); ++index)
{
if (counters.containsKey(new Integer(listpermeid.get(index).getCounterId())))
{
mMetrics.add(listpermeid.get(index));
}
}
}
PerfQuerySpec qSpec = new PerfQuerySpec();
qSpec.setEntity(vmmor);
qSpec.setMaxSample(new Integer(10));
qSpec.getMetricId().addAll(mMetrics);
qSpec.setIntervalId(new Integer(20));

List<PerfQuerySpec> qSpecs = new ArrayList<PerfQuerySpec>();
qSpecs.add(qSpec);

List<PerfEntityMetricBase> listpemb = vimPort.queryPerf(perfManager, qSpecs);
List<PerfEntityMetricBase> pValues = listpemb;
for (i = 0; i < pValues.size(); i++)
{
List<PerfMetricSeries> listpems = ((PerfEntityMetric) pValues.get(i)).getValue();
List<PerfSampleInfo> listinfo = ((PerfEntityMetric) pValues.get(i)).getSampleInfo();
for (int vi = 0; vi < listpems.size(); ++vi)
{
String printInf = "";
PerfCounterInfo pci = (PerfCounterInfo) counters.get(new Integer(listpems.get(vi).getId().getCounterId()));

if (pci != null)
{
if (pci.getNameInfo().getKey().equalsIgnoreCase(nameInfo) && pci.getGroupInfo().getKey().equalsIgnoreCase(groupInfo))
{
printInf += vi + ":" + pci.getNameInfo().getSummary() + ":" + pci.getNameInfo().getKey() + ":" + pci.getNameInfo().getLabel() + ":"
+ pci.getGroupInfo().getKey() + ":" + pci.getGroupInfo().getLabel() + ":" + pci.getGroupInfo().getSummary() + " ";

for (PerfMetricId pmi : mMetrics)
{
int counterId = pmi.getCounterId();
if (counterId == listpems.get(vi).getId().getCounterId())
{
printInf += "[" + pmi.getCounterId() + ":" + pmi.getInstance() + "] ";
}
}

if (listpems.get(vi) instanceof PerfMetricIntSeries)
{
PerfMetricIntSeries val = (PerfMetricIntSeries) listpems.get(vi);
List<Long> lislon = val.getValue();
for (Long k : lislon)
{
printInf += k + " ";
}
list.add(lislon);
}
printInf += " " + pci.getUnitInfo().getKey() + " " + pci.getUnitInfo().getLabel() + " " + pci.getUnitInfo().getSummary();
System.out.println(printInf);
}
}
}
}

}

return list;
}

真正获取cpu使用情况的方法只是调用上面的方法做一些简单的处理:

public static double getVmCpuUsageByVmName(String VmName) throws RuntimeFaultFaultMsg, DatatypeConfigurationException
{
double ans = 0.0;
List<List<Long>> list = getVmData(VmName, "usage", "cpu");

long maxInner = 0;
int times = 0;
for (List<Long> listOuter : list)
{
long tempInner = 0;
for (long inner : listOuter)
{
tempInner += inner;
}
if (tempInner > maxInner)
{
maxInner = tempInner;
times = listOuter.size();
}
}
if (times != 0)
{
ans = (double) maxInner / times;
}

ans = ans / 100;
return ans;
}

这里的虚拟机cpu使用情况是百分制的,而且vsphere sdk返回的百分比的结果都是要除以100的,譬如真实结果是5%,那么vsphere sdk返回的就是500,需要做一下处理。

接下来获取cpu的可用量:

public static double getVmCpuEntitlementByVmName(String VmName) throws RuntimeFaultFaultMsg, DatatypeConfigurationException
{
double ans = 0;
List<List<Long>> list = getVmData(VmName, "entitlement", "cpu");
long maxInner = 0;
int times = 0;
for (List<Long> listOuter : list)
{
long tempInner = 0;
for (long inner : listOuter)
{
tempInner += inner;
}
if (tempInner > maxInner)
{
maxInner = tempInner;
times = listOuter.size();
}
}
if (times != 0)
{
ans = (double) maxInner / times;
}

return ans;
}

细心的读者可能发现的差别,这里只需要修改nameinfo以及groupinfo即可以获取不同的结果。

有一些监控数据不是实时获取的,通过上面的方法是获取不到的,比如:获取虚拟机cpu的个数,类似这种比较固定的信息,或者说配置信息更,就要另辟蹊径了。

public static int getVmCpuNumByVmName(String VmName) throws RuntimeFaultFaultMsg, InvalidPropertyFaultMsg
{
int ans = 0;
String cpuNum = getVmPropertyByVmName("summary.config.numCpu", VmName);
ans = Integer.valueOf(cpuNum);

return ans;
}
private static String getVmPropertyByVmName(String property, String VmName) throws RuntimeFaultFaultMsg, InvalidPropertyFaultMsg
{
String ans = null;
RetrieveResult props = getRetrieveResultObjectWithProperty("VirtualMachine", property);

if (props != null)
{
Boolean flag = false;
if (property.compareToIgnoreCase("name") < 0)
{
for (ObjectContent oc : props.getObjects())
{
if (flag == true)
{
break;
}
String path = null;
List<DynamicProperty> dps = oc.getPropSet();

if (dps != null)
{
for (DynamicProperty dp : dps)
{
path = dp.getName();
if (path.equalsIgnoreCase(property))
{
String val = String.valueOf(dp.getVal());
ans = val;
}
if (path.equalsIgnoreCase("name"))
{
String value = (String) dp.getVal();
if (value.equals(VmName))
{
flag = true;
break;
}
}
}
}
}
}
else
{
for (ObjectContent oc : props.getObjects())
{
if (flag == true)
{
break;
}
String path = null;
List<DynamicProperty> dps = oc.getPropSet();

if (dps != null)
{
for (DynamicProperty dp : dps)
{
path = dp.getName();
if (path.equalsIgnoreCase("name"))
{
String value = (String) dp.getVal();
if (value.equals(VmName))
{
flag = true;
}
}
if (path.equalsIgnoreCase(property))
{
String val = String.valueOf(dp.getVal());
if (flag == true)
{
ans = val;
break;
}
}
}
}
}
}
}

return ans;
}
private static RetrieveResult getRetrieveResultObjectWithProperty(String MorName, String property) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg
{
ManagedObjectReference viewMgrRef = serviceContent.getViewManager();
ManagedObjectReference propColl = serviceContent.getPropertyCollector();

List<String> vmList = new ArrayList<String>();
vmList.add(MorName);

ManagedObjectReference cViewRef = vimPort.createContainerView(viewMgrRef, serviceContent.getRootFolder(), vmList, true);

ObjectSpec oSpec = new ObjectSpec();
oSpec.setObj(cViewRef);
oSpec.setSkip(true);

TraversalSpec tSpec = new TraversalSpec();
tSpec.setName("traversalEntities");
tSpec.setPath("view");
tSpec.setSkip(false);
tSpec.setType("ContainerView");

oSpec.getSelectSet().add(tSpec);

PropertySpec pSpec = new PropertySpec();
pSpec.setType(MorName);
pSpec.getPathSet().add("name");

PropertySpec pSpecRPr = new PropertySpec();
pSpecRPr.setType(MorName);
pSpecRPr.getPathSet().add(property);

PropertyFilterSpec fSpec = new PropertyFilterSpec();
fSpec.getObjectSet().add(oSpec);
fSpec.getPropSet().add(pSpec);
fSpec.getPropSet().add(pSpecRPr);

List<PropertyFilterSpec> fSpecList = new ArrayList<PropertyFilterSpec>();
fSpecList.add(fSpec);

RetrieveOptions ro = new RetrieveOptions();
RetrieveResult props = vimPort.retrievePropertiesEx(propColl, fSpecList, ro);

return props;
}

这样就可以获取虚拟机的cpu个数的信息。

附加一个方法(获取vCenter下所有虚拟机的名称)

public static List<String> getVmNames()
{
List<String> list = new ArrayList<String>();
ManagedObjectReference rootFolder = serviceContent.getRootFolder();
try
{
TraversalSpec tSpec = getVmTraversalSpec();
PropertySpec propertySpec = new PropertySpec();
propertySpec.setAll(Boolean.FALSE);
propertySpec.getPathSet().add("name");
propertySpec.setType("VirtualMachine");

ObjectSpec objectSpec = new ObjectSpec();
objectSpec.setObj(rootFolder);
objectSpec.setSkip(Boolean.TRUE);
objectSpec.getSelectSet().add(tSpec);

PropertyFilterSpec propertyFilterSpec = new PropertyFilterSpec();
propertyFilterSpec.getPropSet().add(propertySpec);
propertyFilterSpec.getObjectSet().add(objectSpec);

List<PropertyFilterSpec> listpfs = new ArrayList<PropertyFilterSpec>(1);
listpfs.add(propertyFilterSpec);
List<ObjectContent> listobjcont = retrievePropertiesAllObjects(listpfs);

if (listobjcont != null)
{
for (ObjectContent oc : listobjcont)
{
String vmnm = null;
List<DynamicProperty> dps = oc.getPropSet();
if (dps != null)
{
for (DynamicProperty dp : dps)
{
vmnm = (String) dp.getVal();
if (vmnm != null)
{
list.add(vmnm);
}
}
}
}
}
}
catch (SOAPFaultException sfe)
{
printSoapFaultException(sfe);
}
catch (Exception e)
{
e.printStackTrace();
}
return list;
}

关于主机(HostSystem)信息的获取将在下一篇文章中呈现。敬请期待。

Modified: 居然忘了写一个重要的函数了,这里赶紧补上:

private static List<PerfCounterInfo> getPerfCounters()
{
List<PerfCounterInfo> pciArr = null;

try
{
PropertySpec propertySpec = new PropertySpec();
propertySpec.setAll(Boolean.FALSE);
propertySpec.getPathSet().add("perfCounter");
propertySpec.setType("PerformanceManager");
List<PropertySpec> propertySpecs = new ArrayList<PropertySpec>();
propertySpecs.add(propertySpec);

ObjectSpec objectSpec = new ObjectSpec();
objectSpec.setObj(perfManager);
List<ObjectSpec> objectSpecs = new ArrayList<ObjectSpec>();
objectSpecs.add(objectSpec);

PropertyFilterSpec propertyFilterSpec = new PropertyFilterSpec();
propertyFilterSpec.getPropSet().add(propertySpec);
propertyFilterSpec.getObjectSet().add(objectSpec);

List<PropertyFilterSpec> propertyFilterSpecs = new ArrayList<PropertyFilterSpec>();
propertyFilterSpecs.add(propertyFilterSpec);

List<PropertyFilterSpec> listpfs = new ArrayList<PropertyFilterSpec>(10);
listpfs.add(propertyFilterSpec);
List<ObjectContent> listobjcont = retrievePropertiesAllObjects(listpfs);

if (listobjcont != null)
{
for (ObjectContent oc : listobjcont)
{
List<DynamicProperty> dps = oc.getPropSet();
if (dps != null)
{
for (DynamicProperty dp : dps)
{
List<PerfCounterInfo> pcinfolist = ((ArrayOfPerfCounterInfo) dp.getVal()).getPerfCounterInfo();
pciArr = pcinfolist;
}
}
}
}
}
catch (SOAPFaultException sfe)
{
printSoapFaultException(sfe);
}
catch (Exception e)
{
e.printStackTrace();
}
return pciArr;
}

欢迎支持笔者的作品《深入理解Kafka: 核心设计与实践原理》和《RabbitMQ实战指南》,同时欢迎关注笔者的微信公众号:朱小厮的博客(ID: hiddenkafka)。
本文作者: 朱小厮

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×