OpenStack之Nova分析——Nova Scheduler服务启动
来源:互联网 发布:手机象棋辅助软件 编辑:程序博客网 时间:2024/04/27 23:14
在继续介绍Nova虚拟机创建过程之前,我们来穿插一个很重要的内容,这就是Nova组件的“大脑”——Nova Scheduler(调度器)。它是我们后续分析虚拟机创建的基础。这个子服务的作用前面已经介绍过,从其名称也可以看出该子服务就是负责调度各子服务工作的。
Nova Scheduler属于RPC服务(至于什么是RPC服务可以关注我之前的文章),这篇文章我们先来分析一下Nova Scheduler的启动流程。
Nova Scheduler服务的启动脚本位于nova/bin/nova-scheduler文件
#加载配置项CONF = cfg.CONFCONF.import_opt('scheduler_topic','nova.scheduler.rpcapi')if __name__ == '__main__': config.prase_args(sys.argv) #加载控制台传入的参数 logging.setup("nova") #配置服务的日志文件 #定义Nova Scheduler服务对象 server = service.Service.create(binary='nova-scheduler',topic=CONF.scheduler_topic) service.serve(server) #创建线程运行Nova Scheduler服务 service.wait() #启动Nova Scheduler服务线程
import_opt方法首先会加载nova.scheduler.rpcapi模块,然后再检查模块中是否定义了scheduler_topic配置项。查看该模块的代码。
rpcapi_opts = [cfg.StrOpt('scheduler_topic', default='scheduler', help='the topic scheduler nodes listen on'),]
可以看到nova.scheduler.rpcapi模块中定义了scheduler_topic的默认值为scheduler。
注:在Nova文件的许多地方都定义了一些配置项的默认值,可以在nova.conf文件中做相应的配置来覆盖默认值
Nova Scheduler服务的启动代码加载了控制台传入的参数,例如我们通过命令:python /opt/stack/novabin/nova-scheduler --config-file=/etc/nova/nova.conf来启动Nova Scheduler服务,这里的控制台传入的参数就是配置文件的路径。
接下来调用service包中Service类的create方法创建Service对象,其中binary是服务名,topic是Nova Scheduler服务监听的RPC主题。然后分别调用了service包的serve和wait方法,创建和启动Nova Scheduler服务线程。
下面来详细分析一下service这个包。上述服务的启动过程主要用到了service包的Service类的create方法以及service包的serve和wait方法,分别来看一下。
1. Service类的create方法
class Service(object): @classmethod def create(cls, host=None, binary=None, topic=None, manager=None, report_interval=None, periodic_interval=None, periodic_fuzzy_delay=None): if not host: host = CONF.host if not binary: binary = os.path.basename(inspect.stack()[-1][1]) if not topic: topic = binary.rpartition('nova-')[2] if not manager: manager = CONF.get('%s_manager' % topic, None) if report_interval is None: report_interval = CONF.report_interval if periodic_interval is None: periodic_interval = CONF.periodic_interval if periodic_fuzzy_delay is None: periodic_fuzzy_delay = CONF.periodic_fuzzy_delay service_obj = cls(host, binary, topic, manager, report_interval=report_interval, periodic_interval=periodic_interval, periodic_fuzzy_delay=periodic_fuzzy_delay) return service_obj这个方法很简单,首先检查一些参数设置,如果没有设置则采用默认值,最后返回一个Service对象。Service类的初始化方法做了两件事——保存create方法传入的参数并创建所需的API对象,等待Conductor服务运行。
2. serve方法
def serve(server, workers=None): #设置_laucher全局变量,以保证每个进程只能启动一个服务 global _launcher if _launcher: raise RuntimeError(_('serve() can only be called once')) #如果传入了workers参数,则启动(workers)个线程运行服务 if workers: _launcher = ProcessLauncher() _launcher.launch_server(server, workers=workers) else: _launcher = ServiceLauncher() _launcher.launch_server(server)serve方法有两个参数,其中server是Service类的create方法创建的Service对象,workers是创建服务的线程数。如果定义了workers,会创建一个ProcessLauncher对象,该对象的launch_server方法会创建workers个线程,每个线程运行一个RPC服务。如果没有定义workers,会创建一个ServiceLauncher对象,该对象的launch_server方法只创建1个RPC服务。
在Nova Scheduler服务的启动脚本中,没有定义workers参数,所以会调用ServiceLauncher对象的launch_server方法。
def launch_server(self, server): ... gt = eventlet.spawn(self.run_server, server) self._services.append(gt)方法创建了一个绿色线程,该线程会运行ServiceLauncher对象的run_server方法。我们仔细看一下run_server方法,该方法中的server参数是一个Service对象。
def run_server(server): server.start() server.wait()
可以看到先调用了Service对象的start方法,start方法定义如下
class Service(object): def start(self): ... self.basic_config_check() #检查服务配置 self.manager.init_host() #初始化主机 self.model_disconnected = False ctxt = context.get_admin_context() try: #查看数据库,获取当前服务的id self.service_ref = self.conductor_api.service_get_by_args(ctxt, self.host, self.binary) self.service_id = self.service_ref['id'] except exception.NotFound: #如果不存在当前服务记录,则创建新记录 self._create_service_ref(ctxt) ... #创建与RabbitMQ服务器的连接 self.conn = rpc.create_connection(new=True) #创建分发RPC请求的RpcDispatcher对象 rpc_dispatcher = self.manager.create_rpc_dispatcher() #创建RPC消费者 self.conn.create_consumer(self.topic, rpc_dispatcher, fanout=False) node_topic = '%s.%s' % (self.topic, self.host) self.conn.create_consumer(node_topic, rpc_dispatcher, fanout=False) self.conn.create_consumer(self.topic, rpc_dispatcher, fanout=True) #激活消费者 self.conn.consume_in_thread() ... #创建定时任务 pulse = self.servicegroup_api.join(self.host, self.topic, self) if pulse: self.timers.append(pulse) ...
这个方法主要完成了两个工作,其一是:创建“消费者”,监听其它模块发来的RPC请求;其二是:创建线程运行的定时任务(这方面我目前还不太了解,后面研究一下吧)。
注:具体的关于RPC消息通信请参看我前面的文章,这里不再赘述。
Service对象的wait方法很简单,其功能就是启动线程运行周期任务。
3. wait方法
serve方法是创建了一个绿色线程,而wait方法的功能是运行线程。
到这里,Nova Scheduler服务启动过程就分析完了。需要说明的是,Nova中全部子服务的启动流程都极其相似,大家可以继续去分析其它子服务的启动流程~~- OpenStack之Nova分析——Nova Scheduler服务启动
- OpenStack之Nova分析——Nova Scheduler调度算法
- OpenStack之Nova分析——Nova API服务
- Nova RPC服务 之 Nova Scheduler 的启动流程
- Openstack nova-scheduler 源码分析 — Filters/Weighting
- openstack nova-scheduler 模块分析
- OpenStack Nova分析——Nova Scheduler调度算法分析(1)
- OpenStack Nova分析——Nova Scheduler调度算法分析(2)
- OpenStack Nova分析——Nova Scheduler调度算法分析(3)
- OpenStack Nova分析——Nova Scheduler调度算法分析(4)
- NOVA-SCHEDULER服务启动流程
- NOVA-SCHEDULER服务启动流程
- openstack之nova-api服务流程分析
- openstack之nova-api服务流程分析
- openstack nova 源码分析2之nova-api,nova-compute
- Openstack Nova 源码分析 — Create instances (nova-conductor阶段)
- openstack nova 基础知识——scheduler的filter和weight
- OpenStack源码探秘(一)——Nova-Scheduler
- MySQL忘记root密码解决办法
- 字符串函数的实现
- 堆栈平衡的应用
- Android 使用monkey自动测试
- gcc4.9.2 for osx
- OpenStack之Nova分析——Nova Scheduler服务启动
- 【深入JAVA】Java中获取系统相关信息——sigar
- AddHandler 与 RemoveHandler
- HDU 4684 - Arc of Dream(矩阵快速幂)
- 安卓常用的基本动画代码
- live555 播放视频 play 不能推送rtp数据
- hibernate source code 阅读二
- Codeforces Round #287 (Div. 2) 507E E. Breaking Good
- Android CountDownTimer 倒计时实现