Openstack nova service 启动过程
2015-07-23 22:48
267 查看
Openstack 中nova主要是用作运算,其是有多个service组成的。
在每个service启动的时候都会注册一个RPC server(nova-api 除外)以供RPC的client调用。
nova compute
nova/cmd/compute.py
service在程序的开头通过import导入
Service 是定义在nova/service .py 里面的一个类
其create方法使用@classmethod 修饰因此可以直接使用类名调用。此方法的作用是返回一个service的对象。
nova/service.py
在 service.py 中 service在开头import
service中的launch的实现为(nova/openstack/common/service.py)
services.add()方法实现使用了GreenThread关于Greenthraed会在单独一个文章里面介绍。
greenthread会执行run_service()方法。run_service()方法执行service.start()和done.wait(),完成了服务的启动,然后等待,一开始我看到Service类中有个start()方法,知道一个服务的启动实质性的内容都在这个方法里,但是就是找不到在哪里调用了这个方法,原来是在这里。。
在每个service启动的时候都会注册一个RPC server(nova-api 除外)以供RPC的client调用。
nova compute
nova/cmd/compute.py
def main(): config.parse_args(sys.argv) logging.setup('nova') utils.monkey_patch() objects.register_all() gmr.TextGuruMeditation.setup_autorun(version) if not CONF.conductor.use_local: block_db_access() objects_base.NovaObject.indirection_api = \ conductor_rpcapi.ConductorAPI() <em><strong> server = service.Service.create(binary='nova-compute', topic=CONF.compute_topic, db_allowed=CONF.conductor.use_local) service.serve(server) service.wait()</strong></em>
service在程序的开头通过import导入
from nova import service
Service 是定义在nova/service .py 里面的一个类
其create方法使用@classmethod 修饰因此可以直接使用类名调用。此方法的作用是返回一个service的对象。
def create(cls, host=None, binary=None, topic=None, manager=None, report_interval=None, periodic_enable=None, periodic_fuzzy_delay=None, periodic_interval_max=None, db_allowed=True): """Instantiates class and passes back application object. :param host: defaults to CONF.host :param binary: defaults to basename of executable :param topic: defaults to bin_name - 'nova-' part :param manager: defaults to CONF.<topic>_manager :param report_interval: defaults to CONF.report_interval :param periodic_enable: defaults to CONF.periodic_enable :param periodic_fuzzy_delay: defaults to CONF.periodic_fuzzy_delay :param periodic_interval_max: if set, the max time to wait between runs """ if not host: host = CONF.host if not binary: binary = os.path.basename(sys.argv[0]) if not topic: topic = binary.rpartition('nova-')[2] if not manager: manager_cls = ('%s_manager' % binary.rpartition('nova-')[2]) manager = CONF.get(manager_cls, None) if report_interval is None: report_interval = CONF.report_interval if periodic_enable is None: periodic_enable = CONF.periodic_enable if periodic_fuzzy_delay is None: periodic_fuzzy_delay = CONF.periodic_fuzzy_delay debugger.init() service_obj = cls(host, binary, topic, manager, report_interval=report_interval, periodic_enable=periodic_enable, periodic_fuzzy_delay=periodic_fuzzy_delay, periodic_interval_max=periodic_interval_max, db_allowed=db_allowed) return service_obj
<em><strong>service.serve(server)</strong></em>用来启动service
nova/service.py
def serve(server, workers=None): global _launcher if _launcher: raise RuntimeError(_('serve() can only be called once')) _<strong><em>launcher = service.launch(server, workers=workers)</em></strong>
在 service.py 中 service在开头import
from nova.openstack.common import service
service中的launch的实现为(nova/openstack/common/service.py)
def launch(service, workers=1): if workers is None or workers == 1: launcher = ServiceLauncher() launcher.launch_service(service) else: launcher = ProcessLauncher() launcher.launch_service(service, workers=workers) return launcher此处有两种加载方法ServiceLauncher和ProcessLauncher
ServiceLauncher类中的launch_service 实现为:注意ServiceLauncher类中并没有单独定义此方法而是继承自其父类Launcher
<pre name="code" class="python"> def launch_service(self, service): """Load and start the given service. :param service: The service you would like to start. :returns: None """ service.backdoor_port = self.backdoor_port self.services.add(service)
services.add()方法实现使用了GreenThread关于Greenthraed会在单独一个文章里面介绍。
def add(self, service): self.services.append(service) self.tg.add_thread(self.run_service, service, self.done)
def run_service(service, done): """Service start wrapper. :param service: service to run :param done: event to wait on until a shutdown is triggered :returns: None """ service.start() done.wait()
greenthread会执行run_service()方法。run_service()方法执行service.start()和done.wait(),完成了服务的启动,然后等待,一开始我看到Service类中有个start()方法,知道一个服务的启动实质性的内容都在这个方法里,但是就是找不到在哪里调用了这个方法,原来是在这里。。
def start(self): verstr = version.version_string_with_package() LOG.audit(_('Starting %(topic)s node (version %(version)s)'), {'topic': self.topic, 'version': verstr}) self.basic_config_check() self.manager.init_host() self.model_disconnected = False ctxt = context.get_admin_context() try: 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: try: self.service_ref = self._create_service_ref(ctxt) except (exception.ServiceTopicExists, exception.ServiceBinaryExists): # NOTE(danms): If we race to create a record with a sibling # worker, don't fail here. self.service_ref = self.conductor_api.service_get_by_args(ctxt, self.host, self.binary) self.manager.pre_start_hook() if self.backdoor_port is not None: self.manager.backdoor_port = self.backdoor_port LOG.debug("Creating RPC server for service %s", self.topic) target = messaging.Target(topic=self.topic, server=self.host) endpoints = [ self.manager, baserpc.BaseRPCAPI(self.manager.service_name, self.backdoor_port) ] endpoints.extend(self.manager.additional_endpoints) serializer = objects_base.NovaObjectSerializer() self.rpcserver = rpc.get_server(target, endpoints, serializer) self.rpcserver.start() self.manager.post_start_hook() LOG.debug("Join ServiceGroup membership for this service %s", 4000 self.topic) # Add service to the ServiceGroup membership group. self.servicegroup_api.join(self.host, self.topic, self) if self.periodic_enable: if self.periodic_fuzzy_delay: initial_delay = random.randint(0, self.periodic_fuzzy_delay) else: initial_delay = None self.tg.add_dynamic_timer(self.periodic_tasks, initial_delay=initial_delay, periodic_interval_max= self.periodic_interval_max)
def get_server(target, endpoints, serializer=None): assert TRANSPORT is not None serializer = RequestContextSerializer(serializer) return messaging.get_rpc_server(TRANSPORT, target, endpoints, executor='eventlet', serializer=serializer)
相关文章推荐
- CentOS6下安装Python
- shell序列和nohup &
- Office 2013在XenDesktop7.x 操作缓慢问题
- 一些研究SLAM的团队和网站 [2008年10月20日]
- 关于初级磁盘管理(gpt UEFI...)最好的一篇文章(来自gentoo linux)
- linux添加动态库搜索路径
- Linux下只需3步轻松反编译Android APK
- CentOS 6.3下配置软RAID(Software RAID)
- SVM源代码网站
- Shell 学习笔记 (org-mode制作)
- linux下ftp服务搭建
- linux磁盘管理笔记
- linux下crontab使用笔记
- Linux kernel 分析之二十二:内存管理-page fault处理流程
- linux基本命令学习笔记
- Openssl req命令
- Linux kernel 分析之二十一:定时器-巧妙的定时器算法
- apache无法解析php解决方法
- linux awk命令详解
- Linux kernel 分析之二十:内存管理-内核中的页表映射总结