码迷,mamicode.com
首页 > 其他好文 > 详细

Neutron分析(2)——neutron-server启动过程分析

时间:2014-07-16 19:22:23      阅读:346      评论:0      收藏:0      [点我收藏+]

标签:blog   http   os   art   for   io   

neutron-server启动过程分析

1. /etc/init.d/neutron-server

DAEMON=/usr/bin/neutron-server
DAEMON_ARGS="--log-file=$LOGFILE"
DAEMON_DIR=/var/run
...
case $1 in
    start)
        test "$ENABLED" = "true" || exit 0
        log_daemon_msg "Starting neutron server" "neutron-server"
        start-stop-daemon -Sbmv --pidfile $PIDFILE --chdir $DAEMON_DIR --exec $DAEMON -- $DAEMON_ARGS
        log_end_msg $?
        ;;
        ...
esac

2. /usr/bin/neutron-server

import sys
from neutron.server import main

if __name__ == "__main__":
    sys.exit(main())

3. neutron.server.main

ef main():
    # the configuration will be read into the cfg.CONF global data structure
    config.init(sys.argv[1:])
    if not cfg.CONF.config_file:
        sys.exit(_("ERROR: Unable to find configuration file via the default"
                   " search paths (~/.neutron/, ~/, /etc/neutron/, /etc/) and"
                   " the ‘--config-file‘ option!"))
    try:
        pool = eventlet.GreenPool()

        # 以协程方式启动Restful API
        neutron_api = service.serve_wsgi(service.NeutronApiService)
        api_thread = pool.spawn(neutron_api.wait)

        # 启动RPC API
        try:
            neutron_rpc = service.serve_rpc()
        except NotImplementedError:
            LOG.info(_("RPC was already started in parent process by plugin."))
        else:
            rpc_thread = pool.spawn(neutron_rpc.wait)

            # api and rpc should die together.  When one dies, kill the other.
            rpc_thread.link(lambda gt: api_thread.kill())
            api_thread.link(lambda gt: rpc_thread.kill())

        pool.waitall()
    except KeyboardInterrupt:
        pass
    except RuntimeError as e:
        sys.exit(_("ERROR: %s") % e)

4. 先看neutron.service.serve_rpc()

neutron.service.serve_rpc()最重要的工作就是启动各个插件的RpcWorker

plugin = manager.NeutronManager.get_plugin()

try:
        rpc = RpcWorker(plugin)

        if cfg.CONF.rpc_workers < 1:
            rpc.start()
            return rpc
        else:
            launcher = common_service.ProcessLauncher(wait_interval=1.0)
            launcher.launch_service(rpc, workers=cfg.CONF.rpc_workers)
            return launcher

而RpcWorker最重要的工作是调用plugin的start_rpc_listeners来监听消息队列:

def start(self):
        # We may have just forked from parent process.  A quick disposal of the
        # existing sql connections avoids producing errors later when they are
        # discovered to be broken.
        session.get_engine().pool.dispose()
        self._servers = self._plugin.start_rpc_listeners()

5. 再来看Rest API部分

service.serve_wsgi(service.NeutronApiService)

def serve_wsgi(cls):

    try:
        service = cls.create()
        service.start()
    except Exception:
        with excutils.save_and_reraise_exception():
            LOG.exception(_(‘Unrecoverable error: please check log ‘
                            ‘for details.‘))

    return service

service.start()即为self.wsgi_app = _run_wsgi(self.app_name),而该函数最重要的工作是从api-paste.ini中加载app并启动

def _run_wsgi(app_name):
    app = config.load_paste_app(app_name)
    if not app:
        LOG.error(_(‘No known API applications configured.‘))
        return
    server = wsgi.Server("Neutron")
    server.start(app, cfg.CONF.bind_port, cfg.CONF.bind_host,
                 workers=cfg.CONF.api_workers)
    # Dump all option values here after all options are parsed
    cfg.CONF.log_opt_values(LOG, std_logging.DEBUG)
    LOG.info(_("Neutron service started, listening on %(host)s:%(port)s"),
             {‘host‘: cfg.CONF.bind_host,
              ‘port‘: cfg.CONF.bind_port})
    return server

6. api-paste.ini

[composite:neutron]
use = egg:Paste#urlmap
/: neutronversions
/v2.0: neutronapi_v2_0

[composite:neutronapi_v2_0]
use = call:neutron.auth:pipeline_factory
noauth = request_id catch_errors extensions neutronapiapp_v2_0
keystone = request_id catch_errors authtoken keystonecontext extensions neutronapiapp_v2_0

[filter:request_id]
paste.filter_factory = neutron.openstack.common.middleware.request_id:RequestIdMiddleware.factory

[filter:catch_errors]
paste.filter_factory = neutron.openstack.common.middleware.catch_errors:CatchErrorsMiddleware.factory

[filter:keystonecontext]
paste.filter_factory = neutron.auth:NeutronKeystoneContext.factory

[filter:authtoken]
paste.filter_factory = keystoneclient.middleware.auth_token:filter_factory

[filter:extensions]
paste.filter_factory = neutron.api.extensions:plugin_aware_extension_middleware_factory

[app:neutronversions]
paste.app_factory = neutron.api.versions:Versions.factory

[app:neutronapiapp_v2_0]
paste.app_factory = neutron.api.v2.router:APIRouter.factory

neutron.api.v2.router:APIRouter.factory针对network、subnet、port三个资源注册了 index、create等2个collection action以及show、update、delete等3个memver action,这些action最终记录在APIRouter._plugin_handlers中:

{‘create‘: ‘create_subnet‘, ‘delete‘: ‘delete_subnet‘, ‘list‘: ‘get_subnets‘, ‘update‘: ‘update_subnet‘, ‘show‘: ‘get_subnet‘}

{‘create‘: ‘create_network‘, ‘delete‘: ‘delete_network‘, ‘list‘: ‘get_networks‘, ‘update‘: ‘update_network‘, ‘show‘: ‘get_network‘}

{‘create‘: ‘create_port‘, ‘delete‘: ‘delete_port‘, ‘list‘: ‘get_ports‘, ‘update‘: ‘update_port‘, ‘show‘: ‘get_port‘}

在请求进入APIRouter之前,会先经过RequestIdMiddleware(请求header中添加 openstack.request_id)、CatchErrorsMiddleware(错误处理)、keystone权限验证以及 plugin_aware_extension_middleware_factory等几个filter的处理,前三个filter比较直 观,plugin_aware_extension_middleware_factory创建了映射到plugin的处理函数:

{‘create‘: ‘create_router‘, ‘delete‘: ‘delete_router‘, ‘list‘: ‘get_routers‘, ‘update‘: ‘update_router‘, ‘show‘: ‘get_router‘}

{‘create‘: ‘create_floatingip‘, ‘delete‘: ‘delete_floatingip‘, ‘list‘: ‘get_floatingips‘, ‘update‘: ‘update_floatingip‘, ‘show‘: ‘get_floatingip‘}

{‘create‘: ‘create_agent‘, ‘delete‘: ‘delete_agent‘, ‘list‘: ‘get_agents‘, ‘update‘: ‘update_agent‘, ‘show‘: ‘get_agent‘}

参考资料

Neutron分析(2)——neutron-server启动过程分析,布布扣,bubuko.com

Neutron分析(2)——neutron-server启动过程分析

标签:blog   http   os   art   for   io   

原文地址:http://www.cnblogs.com/feisky/p/3844636.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!