Openstack Cinder 服务启动代码分析

来源:互联网 发布:最优化方法修订版答案 编辑:程序博客网 时间:2024/04/29 04:50

这个先发上去,慢慢再添加,希望把整个cindervolume启动的流程写清楚

 def start(self):        #vers=2013.2.3        version_string = version.version_string()        LOG.audit(_('Starting %(topic)s node (version %(version_string)s)'),                  {'topic': self.topic, 'version_string': version_string})        self.model_disconnected = False        #cinder.context.RequestContext is_admin=true; read_deleted=no        ctxt = context.get_admin_context()        try:            #/opt/stack/cinder/cinder/db/api.py(129)service_get_by_args()            #获得inder.db.sqlalchemy.models.Service模型类的一个对象service_ref                        service_ref = db.service_get_by_args(ctxt,                                                 self.host,                                                 self.binary)                        self.service_id = service_ref['id']        except exception.NotFound:            self._create_service_ref(ctxt)        #/opt/stack/cinder/cinder/openstack/common/rpc/__init__.py(82)create_connection()        #创建一个amqp的connection,默认是kombu实现        self.conn = rpc.create_connection(new=True)        LOG.debug(_("Creating Consumer connection for Service %s") %                  self.topic)        rpc_dispatcher = self.manager.create_rpc_dispatcher()        # Share this same connection for these Consumers        #topic类似cinder-volume,接收所有发给cinder-volume服务的消息        self.conn.create_consumer(self.topic, rpc_dispatcher, fanout=False)        #nodetopic类似cinder-volume:suning-HP-Compaq-Pro-6380-MT        node_topic = '%s:%s' % (self.topic, self.host)        #接收发给指定主机的cinder volume的消息?        self.conn.create_consumer(node_topic, rpc_dispatcher, fanout=False)        #接收广播用的消费者        self.conn.create_consumer(self.topic, rpc_dispatcher, fanout=True)        # Consume from all consumers in a thread        #在一个线程内启动所有的消费者        self.conn.consume_in_thread()        self.manager.init_host()        #report_interval是更新数据库中服务状态的时间间隔,默认是10s        if self.report_interval:            pulse = utils.LoopingCall(self.report_state)            pulse.start(interval=self.report_interval,                        initial_delay=self.report_interval)            #定时器添加任务            self.timers.append(pulse)        #有一个资源刷新的服务叫做periodic_tasks,猜测这个是资源刷新的时间间隔,默认是60秒,和上一个配置一样,保存在/etc/cinder/cind.conf文件中        if self.periodic_interval:            if self.periodic_fuzzy_delay:                initial_delay = random.randint(0, self.periodic_fuzzy_delay)            else:                initial_delay = None            periodic = utils.LoopingCall(self.periodic_tasks)            periodic.start(interval=self.periodic_interval,                           initial_delay=initial_delay)            #定时器添加任务            self.timers.append(periodic)


WSGIService初始化

    def __init__(self, name, loader=None):        """Initialize, but do not start the WSGI server.        :param name: The name of the WSGI server given to the loader.        :param loader: Loads the WSGI application using the given name.        :returns: None        """        self.name = name        self.manager = self._get_manager()        #创建一个loader实例,用来装载api-paste.ini配置文件        self.loader = loader or wsgi.Loader()        #利用paste.deploy第三方软件载入配置文件中指定的name应用        self.app = self.loader.load_app(name)                #方法 __call__   WSGI服务请求调用接口,通过装饰后实际上是将此处__call__方法的返回值作为参数传入到webob.dec.wsgify装饰类,        #并调用该类的同名方法__call__, __call__方法又根据web请求调用app既Resource的__call__来完成具体的功能,        #每当有nova-api相关请求时均会进入到Resource的__call__方法以便进行请求的dispatch,        #所以下面的ExtensionsResource就主要是将各个功能类进行manage操作,以便完成服务请求。        self.host = getattr(CONF, '%s_listen' % name, "0.0.0.0")        self.port = getattr(CONF, '%s_listen_port' % name, 0)        self.server = wsgi.Server(name,                                  self.app,                                  host=self.host,                                  port=self.port)
WSGIService启动

 """Run the blocking eventlet WSGI server.                        协同程序与线程差不多,也就是一条执行序列,拥有自己独立的栈,局部变量和指令指针,同时又与其它协同程序共享全局变量和其它大部分东西。线程与协同程序的主要区别在于,一个具有多线程的程序可以同时运行几个线程,而协同程序却需要彼此协作地运行。        eventlet是一个用来处理和网络相关的python库函数,而且可以通过协程来实现并发,在eventlet里,把“协程”叫做greenthread(绿色线程)。                        关于blocking eventlet的概念,参考http://blog.csdn.net/xiangmin2587/article/details/8182775        :returns: None        """        eventlet.wsgi.server(self._socket,                             self.app,                             protocol=self._protocol,                             custom_pool=self._pool,                             log=self._wsgi_logger)


0 0