Ovirt中的云主机监控

  1. PollVmStatsRefresher.java Vm刷新调度器

    • poll() 调度执行办法

      @OnTimerMethodAnnotation("poll")public void poll() {    if (isMonitoringNeeded(vdsManager.getStatus())) {        //负责获取虚拟机列表,并将其存储在VdsManager上进行剖析        VmsListFetcher fetcher = new VmsStatisticsFetcher(vdsManager);        long fetchTime = System.nanoTime();        //fetcher.fetch()  调用vdsm接口,获取AllVmStats信息        if (fetcher.fetch()) {            //剖析监控到的主机的数据变动并做出解决。相干的更改将被长久化,状态转换和外部命令将相应地产生            getVmsMonitoring().perform(fetcher.getChangedVms(), fetchTime, vdsManager, true);            Stream<VdsmVm> vdsmVmsToMonitor = filterVmsToDevicesMonitoring(fetcher.getChangedVms());            processDevices(vdsmVmsToMonitor, fetchTime);        } else {            log.info("Failed to fetch vms info for host '{}' - skipping VMs monitoring.", vdsManager.getVdsName());        }    }}
    • startMonitoring() 启动调度 10-15s

      public void startMonitoring() {    vmsMonitoringJob =        schedulerService.scheduleWithFixedDelay(                this::poll,                VMS_REFRESH_RATE * NUMBER_VMS_REFRESHES_BEFORE_SAVE,                VMS_REFRESH_RATE * NUMBER_VMS_REFRESHES_BEFORE_SAVE,                TimeUnit.MILLISECONDS);}
  2. VmsStatisticsFetcher.java 由PollVmStatsRefresher.poll()调用

    VmsListFetcher fetcher = new VmsStatisticsFetcher(vdsManager);fetcher.fetch()  //该办法会执行vdsm接口
    • fetch() 由VmsStatisticsFetcher继承VmsListFetcher

      public boolean fetch() {    VDSReturnValue pollReturnValue = poll();    if (pollReturnValue.getSucceeded()) {        vdsmVms = (Map<Guid, VdsmVm>) pollReturnValue.getReturnValue();        //该办法会对获取道德信息进行过滤,过滤处批改后的vms信息,并且会将VmDynamic信息存储到库中        onFetchVms();        return true;    } else {        onError();        return false;    }}

      poll()会被VmsStatisticsFetcher重写

    • poll() 调用vdsm接口GetAllVmStats

      @Overrideprotected VDSReturnValue poll() {    return getResourceManager().runVdsCommand(            VDSCommandType.GetAllVmStats,            new VdsIdVDSCommandParametersBase(vdsManager.getVdsId()));}
    • onFetchVms()

      protected void onFetchVms() {    //获取以后库中的vms信息    dbVms = getVmDynamicDao().getAllRunningForVds(vdsManager.getVdsId()).stream()            .collect(Collectors.toMap(VmDynamic::getId, Function.identity()));    changedVms = new ArrayList<>();    //过滤和比拟dbVms、vdsmVms,如果vm状态产生扭转,则从新调用vdsm接口GetVmStats,获取最新数据到changeVms中    filterVms();    //过滤没有运行的云主机    gatherNonRunningVms(dbVms);    //保留最新的vms列表    saveLastVmsList();}
  3. VmsMonitoring 调用手头的所有Vm分析器,遍历他们的报告并采取行动-触发VDSM命令(destroy,runrerun,migrate),报告实现的操作,移交迁徙和保留到db

    • perform() 由PollVmStatsRefresher.poll()调用

      public void perform(    List<Pair<VmDynamic, VdsmVm>> monitoredVms,    long fetchTime,    VdsManager vdsManager,    boolean updateStatistics) {    if (monitoredVms.isEmpty()) {        return;    }    List<VmAnalyzer> vmAnalyzers = Collections.emptyList();    try {        vmAnalyzers = analyzeVms(monitoredVms, fetchTime, vdsManager, updateStatistics);        // It is important to add the unmanaged VMs before flushing the dynamic data into the database        addUnmanagedVms(vmAnalyzers, vdsManager.getVdsId());        flush(vmAnalyzers);        postFlush(vmAnalyzers, vdsManager, fetchTime);        vdsManager.vmsMonitoringInitFinished();    } catch (RuntimeException ex) {        log.error("Failed during vms monitoring on host {} error is: {}", vdsManager.getVdsName(), ex);        log.error("Exception:", ex);    } finally {        unlockVms(vmAnalyzers);    }}
    • analyzeVms() 剖析虚拟机,获取剖析后果

      /*** Analyze the VM data pair* Skip analysis on VMs which cannot be locked* note: metrics calculation like memCommited and vmsCoresCount should be calculated *before**   this filtering.* @return The analyzers which hold all the data per VM*/private List<VmAnalyzer> analyzeVms(      List<Pair<VmDynamic, VdsmVm>> monitoredVms,      long fetchTime,      VdsManager vdsManager,      boolean updateStatistics) {  VmAnalyzerFactory vmAnalyzerFactory = getVmAnalyzerFactory(vdsManager, updateStatistics);  List<VmAnalyzer> vmAnalyzers = new ArrayList<>(monitoredVms.size());  monitoredVms.forEach(vm -> {      // TODO filter out migratingTo VMs if no action is taken on them      if (shouldAnalyzeVm(vm, fetchTime, vdsManager.getVdsId())) {          try {              VmAnalyzer vmAnalyzer = vmAnalyzerFactory.getVmAnalyzer(vm);              vmAnalyzer.analyze();              vmAnalyzers.add(vmAnalyzer);          } catch (RuntimeException ex) {              Guid vmId = getVmId(vm.getFirst(), vm.getSecond());              VmManager vmManager = getVmManager(vmId);              vmManager.unlock();              log.error("Failed during monitoring vm: {} , error is: {}", vmId, ex);              log.error("Exception:", ex);          }      }  });  vmAnalyzers.sort(Comparator.comparing(VmAnalyzer::getVmId));  return vmAnalyzers;}
    • flush(vmAnalyzers) 保留vm数据

      private void flush(List<VmAnalyzer> vmAnalyzers) {    saveVmDynamic(vmAnalyzers);    saveVmStatistics(vmAnalyzers);    saveVmInterfaceStatistics(vmAnalyzers);    saveVmDiskImageStatistics(vmAnalyzers);    saveVmGuestAgentNetworkDevices(vmAnalyzers);}

总结

  1. 在云主机中,监控信息通过vm_interface_view查问进去的,vm_interface_view 查问表vm_interface_statistics中的数据表。
  2. ovirt对云主机有一个调度工作,去获取vds主机上理论云主机信息,来同步本地云主机。大抵过程为:

    1. 创立调度办法,并启动调度。
    2. 在调度办法中,ovirt判断vds的状态是否须要监控
    3. ovirt会先调用vdsm接口GetAllVmStats获取全副的vmsStatic信息,并与以后库中的dbVms信息作比照,次要比拟dbvm是否为空,以及单方状态是否统一
    4. 比拟之后会从新调用vdsm接口GetVmStats获取须要批改的vms信息
    5. ovirt会依据批改的vms信息,剖析其变动并做出反馈。相干的更改将被长久化,状态转换和外部命令将相应地产生