在Nova Scheduler的启动脚本中,最终的代码是创建Service类的create方法,以及service包的serve和wait方法。
分析Nova Scheduler服务的启动流程。
1、Service类的create方法
class Service(object): @classmethoddef 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.hostif not binary: #服务名binary = os.path.basename(inspect.stack()[-1][1])if not topic: #主题topic = binary.rpartition('nova-')[2]if not manager: #manager类名manager = ('%s_manager' % topic, None)if report_interval is None:report_interval = port_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对象service_obj = cls(host, binary, topic, manager,report_interval=report_interval,periodic_interval=periodic_interval,periodic_fuzzy_delay=periodic_fuzzy_delay)return service_obj
create方法首先检查一些参数设置,如果在方法调用时没有设置则采用默认值,最后
返回一个Service对象。
Service类的初始化方法做了两个工作:
(1) 保存create方法传入的参数
(2) 创建所需的API对象,并等待Conductor服务正常运行。注意:所有的数据库操作都是通过Nova Conductor服务完
成。因此,其他服务的正常运行,都依赖于Nova Conductor服务已经正常运行
2、serve方法
def serve(server, workers=None):#设置_laucher全局变量,以保证每个进程只能启动一个服务global _launcherif _launcher: #_launcher不为None,说明有服务启动了raise RuntimeError(_('serve() can only be called once'))#workers指定启动的服务个数#如果传入了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个线程,每个线
程运行一个Nova RPC服务。如果没有定义workers,会创建一个ServiceLauncher对象,该对象的launch_server方法
只创建一个线程运行Nova RPC服务。
在Nova Scheduler服务的启动脚本中,没有定义workers参数。因此serve方法会创建ServiceLauncher对象的
launch_server方法。ServiceLauncher类继承于Launcher类,launcher_server方法定义在Launcher类中。
def launch_server(self, server):...gt = eventlet.spawn(self.run_server, server)self._services.append(gt)
方法创建了一个绿色线程,该线程会运行
ServiceLauncher对象的run_server方法。我们仔细看一下run_server方
法,该方法中的server参数是一个Service对象。
3、wait方法
service包的serve方法创建了一个绿色线程,而wait方法的功能是运行线程。serve方法创建的绿色线程会执行
ServiceLauncher对象的run_server方法。ServiceLauncher类继承于Launcher类,launcher_server方法定义在
Launcher类中。如下:
class Launcher(object):
@staticmethod
def run_server(server):server.start()server.wait()
该server参数是一个Service对象。可以看到,run_server方法依次调用了Service对象的start和wait方法。
Service类的start方法定义如下:
class Service(object):def start(self):...self.basic_config_check() #检查服务配置self.manager.init_host() #初始化主机del_disconnected = Falsectxt = _admin_context() #获取管理员上下文try:#查看数据库,获取当前服务的idself.service_ref = ductor_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服务器的连接 出现高级消息队列的重要东东 = ate_connection(new=True)#创建分发RPC请求的RpcDispatcher对象rpc_dispatcher = ate_rpc_dispatcher()#创建RPC消费者ate_pic, rpc_dispatcher, fanout=False)node_topic = '%s.%s' % (pic, self.reate_consumer(node_topic, rpc_dispatcher, fanout=reate_pic, rpc_dispatcher, fanout=True)#激活RPC消费者sume_in_thread()...#创建定时任务,定时报道服务的状态pulse = self.servicegroup_api.join(self.host, pic, self)if pulse:self.timers.append(pulse)#如果允许运行周期任务,设置初始等待时间if self.periodic_enable:if self.periodic_fuzzy_delay:#初始等待时间在0~periodic_fuzzy_delay之间随机选择一个数initial_delay = random.randint(0, self.periodic_fuzzy_delay)else:#如果没有选择periodic_fuzzy_delay,则服务启动后立即运行定时任务initial_delay = None#创建线程,运行周期任务periodic = utils.DynamicLoopingCall(self.periodic_tasks)periodic.start(initial_delay=initial_delay,periodic_interval_max=self.periodic_interval_max)self.timers.append(periodic)
(1)创建RPC消费者,监听其他模块发来的RPC请求
(2)创建线程运行定时任务
1、创建RPC消费者。start方法中,共监听了3个消费者。topic类型的消费者,topic.host类型的消费者,广播类型
的消费者。功能:
2、创建一个RpcDispatcher对象,RpcDispatcher对象的功能是决定将RPC请求交给manager对象的哪个方法处理。
RpcDispatcher对象和manager对象在RPC服务中的地位已在"RPC调用的实现"部分介绍(后面详细读)。
3、创建定时任务线程的工作。start方法共两个线程,一个是线程会定时向数据库更新服务状态,一个是运行自定义
的周期任务。
Service对象的wait方法很简单,其功能就是启动线程运行周期任务。
4、wait方法
serve方法是创建了一个绿色线程,而wait方法的功能是运行线程。
总结:Nova Scheduler服务启动过程就分析完了。需要说明的是,Nova中全部子服务的启动流程都极其相似,可以继
续去分析其它子服务的启动流程!!!
本文发布于:2024-01-30 16:51:47,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170660471021462.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |