一、get_weighed_hosts方法:

1、HostManager对象的get_weighed_hosts方法定义如下:/nova/schediler/host_manager.py


class HostManager(object):
    def get_weighed_hosts(self, hosts, weight_properties):
        return self.weight_handler.get_weighed_objects(self.weight_classes,
                                                       hosts, weight_properties)

get_weighed_hosts方法较get_filtered_hosts方法要简单。它不需要外部传入类似weight_class_names的变量,而是

直接使用预先注册weight_classes列表中的权值类(self.weight_classes =

 self.weight_handler.get_matching_classes(CONF.scheduler_weight_classes))。HostManager类的初始化方法

中,会调用filter_handler对象的get_matching_classes方法注册可用的权值类


2、与get_filtered_hosts方法类似,get_weighed_host方法会调用weight_handler对象的get_weighed_objects方法

计算主机的权值。weight_handler变量是一个HostWeightHandler对象。HostWeightHandler类继承

BaseWeightHandler类。(/nova/scheduler/weights/_init_.py).BaseWeightHandler类中的get_weighed_host方法:

class BaseWeightHandler(loadables.BaseLoader):
    def get_weighed_objects(self, weigher_classes, obj_list, weighing_properties):
        if not obj_list:
            return []
        #将主机封装成WeighedObject对象
        weighed_objs = [self.object_class(obj, 0.0) for obj in obj_list]
        #遍历所有权值类
        for weigher_cls in weigher_classes:
            #创建权值对象
            weigher = weigher_cls()
            weigher.weigh_objects(weighed_objs, weighing_properties)
        #将主机列表按权值从高到低排序    
        return sorted(weighed_objs, key=lambda x: x.weight, reverse=True)

(1)、将主机封装成object_class对象,并且赋予主机的初始权值为0。

object_class类变量的值为WeighedObject

类。

(2)、WeighedObject类封装了主机的HostState对象和主机权值两个成员变量。

(3)、不断调用权值类对象的weigh_objects方法,不断修改主机WeighedObject对象的权值。将主机按照权值高低顺

序排序。

3、上面代码核心部分是:调用权值对象的weigh_objects方法。目前Nova只定义了RAMWeight标准权值类。

RAMWeight类继承自BaseHostWeigher类(/nova/scheduler/weights/__init__.py),BaseHostWeigher类继承了

BaseWeigher类。weigh_objects方法定义在BaseWeigher类中,定义如下:

class BaseWeigher(object):
    def weigh_objects(self, weighed_obj_list, weight_properties):
        for obj in weighed_obj_list:  #遍历主机列表
            #主机权值=原来的权值+权重*当前权值对象赋予主机的权值
            obj.weight += (self._weight_multiplier() *
                           self._weigh_object(obj.obj, weight_properties))

主机的权值 = 原来的权值 + 权重 * 当前权值对象赋予主机的权值

主机的权值实质上是各个权值类赋予给主机的权值加权和。

(1)_weight_multiplier方法:返回当前权值类的权重。

(2)_weigh_object方法:当前权值类赋予主机的权值。

RAMWeigher权值类的_weight_multiplier和_weigh_object方法。权重是由nova.conf配置文件的

ram_weight_multiplier,默认值为1.0。_weigh_object方法返回主机内存剩余的大小(MB)。

总结:HostManager类的get_weighed_hosts方法的工作流程

1、get_weighed_hosts方法调用HostWeightHandler对象的get_weighed_objects方法。

2、HostWeightHandler对象的get_weighed_objects方法 首先为每个主机创建一个WeighedObject对象。然后,依次

调用权值对象的weigh_objects方法不断修改主机WeighedObject对象的权值。 最后,将主机按照权值由高到低顺序

排序。

3、权值对象的weigh_objects方法在主机原有权值的基础上,加权累加当前权值对象赋予给主机的权值。 每个权值

类,都需要实现_weight_multiplier和_weigh_object方法。_weight_multiplier返回当前权值类的权重。

_weigh_object方法返回当前权值类赋予主机的权值。

二、get_matching_classes方法

HostManager类的初始化方法分别调用了HostFilterHandler对象和HostWeightHandler对象的get_matching_classes

方法来注册可用的过滤器类和权值类。

总结HostFilterHandler对象的get_matching_classes方法加载可用过滤器类的流程。

1、HostFilterHandler对象的get_matching_classes方法根据nova.conf文件的配置,调用all_filters方法

2、all_filters方法调用HostFilterHandler对象的get_all_classes方法

3、HostFilterHandler对象的get_all_classes方法遍历filters目录下的所有.py文件(__init__.py除外),将.py文

件中定义的所有类都当作是过滤类。