1、启动cinder-api服务

当你通过cinder-api命令(如:/usr/bin/cinder-api --config-file /etc/cinder/cinder.conf)启动api服务时,执行的实际上是
cinder/cmd/api.py/main()函数, 如下:

  1. [root@xgto02n010027244133 ~]# cat /usr/bin/cinder-api
  2. #!/usr/bin/python2
  3. # PBR Generated from u'console_scripts'
  4. import sys
  5. from cinder.cmd.api import main
  6. if __name__ == "__main__":
  7. sys.exit(main())

cinder/cmd/api.py/main()函数,内容如下:

  1. def main():
  2.  
  3. objects.register_all() #加载辅助对象,封装与数据库相关的操作
  4. gmr_opts.set_defaults(CONF) #oslo_reports模块,用于生成错误报告,如内存泄漏等
  5. CONF(sys.argv[1:], project='cinder',
  6. version=version.version_string())
  7. config.set_middleware_defaults()
  8. logging.setup(CONF, "cinder")
  9. python_logging.captureWarnings(True)
  10. utils.monkey_patch() # monkey-patch,替换库比如socket、thread等,不改变import的行为,改变的是操作的指向函数
  11.  
  12. gmr.TextGuruMeditation.setup_autorun(version, conf=CONF)
  13. """初始化rpc:
  14. 设置全局Transport和Notifier,Transport是
  15. oslo_messaging/transport.py/Transport实例,我采用的是默认的
  16. rpc_backend=rabbit,所以Transport采用的driver=oslo_messaging/
  17. _drivers/impl_rabbit.py/RabbitDriver;Notifier是一个通知消息发
  18. 送器,它借助Transport将通知发送发送给ceilometer
  19. """
  20. rpc.init(CONF)
  21. #通过服务启动器启动WSGI服务(`osapi_volume`)并等待服务启动成功
  22. #在初始化WSGI服务时,会设置路由映射以及加载WSGI应用程序
  23. #在启动WSGI服务时,会启动http监听
  24. launcher = service.process_launcher()
  25. server = service.WSGIService('osapi_volume') #创建一个名为`osapi_volume`的`WSGIService`服务对象 ,2里面详解
  26. launcher.launch_service(server, workers=server.workers)
  27. launcher.wait()

2、创建 WSGIService 服务对象

  1. from oslo_service import wsgi
  2. from cinder import service
  3. cinder/service.py:class WSGIService(service.ServiceBase):
  4. class WSGIService(service.ServiceBase):
  5. """Provides ability to launch API from a 'paste' configuration."""
  6.  
  7. def __init__(self, name, loader=None):
  8. """Initialize, but do not start the WSGI server.
  9. 初始化,但是并不启动wsgi server服务
  10. :param name: The name of the WSGI server given to the loader.
  11. :param loader: Loads the WSGI application using the given name.
  12. :returns: None
  13.  
  14. """
  15. self.name = name #服务名`osapi_volume`
  16. self.manager = self._get_manager() #加载名为(`osapi_volume_manager`)的管理器,返回值为None)
  17. #创建WSGI应用加载器,并根据配置文件(`cinder.conf`)设置应用配置路径,config_path` = `/etc/cinder/api-paste.ini‘
  18. self.loader = loader or wsgi.Loader(CONF) #该函数会寻找cinder.conf文件中 api_paste_config 参数对应的配置文件,并保存到变量中
  19. self.app = self.loader.load_app(name) #加载WSGI应用并设置路由映射,return paste.urlmap.URLMap
  20.  
  21. """
  22. 根据配置文件(`cinder.conf`)设置监听地址及工作线程数
  23. 如果未指定监听ip及端口就分别设置为`0.0.0.0`及`0`
  24. 如果为指定工作线程数就设置为cpu个数
  25. 如果设置的工作线程数小于1,则抛异常
  26. """
  27. self.host = getattr(CONF, '%s_listen' % name, "0.0.0.0")
  28. self.port = getattr(CONF, '%s_listen_port' % name, 0)
  29. self.use_ssl = getattr(CONF, '%s_use_ssl' % name, False)
  30. self.workers = (getattr(CONF, '%s_workers' % name, None) or
  31. processutils.get_worker_count())
  32. if self.workers and self.workers < 1:
  33. worker_name = '%s_workers' % name
  34. msg = (_("%(worker_name)s value of %(workers)d is invalid, "
  35. "must be greater than 0.") %
  36. {'worker_name': worker_name,
  37. 'workers': self.workers})
  38. raise exception.InvalidInput(msg)
  39.  
  40. """如果CONF.profiler.enabled = True就开启性能分析
  41. 创建一个类型为`Messaging`的通知器(`_notifier`),将性能数据发送给
  42. ceilometer
  43. """
  44. setup_profiler(name, self.host)
  45. ##创建WSGI服务器对象
  46. self.server = wsgi.Server(CONF,
  47. name,
  48. self.app,
  49. host=self.host,
  50. port=self.port,
  51. use_ssl=self.use_ssl)

在cinder.conf配置文件中与cinder api服务有关的参数
# File name for the paste.deploy config for api service (string value)
api_paste_config = /etc/cinder/api-paste.ini
在初始化WSGIService服务对象过程中,主要完成了如下操作:
1)加载WSGI Application(Python Paste Deployment)
2)设置路由映射(Python Routes)
3)创建WSGI服务器对象并完成初始化

2.1 对wsgi的使用

  1. oslo_service/wsgi.py
  2. class Loader(object):
  3. """Used to load WSGI applications from paste configurations."""
  4.  
  5. def __init__(self, conf):
  6. """Initialize the loader, and attempt to find the config.
  7. :param conf: Application config
  8. :returns: None
  9. """
  10. conf.register_opts(_options.wsgi_opts)
  11. self.config_path = None
  12.  
  13. config_path = conf.api_paste_config
  14. if not os.path.isabs(config_path):
  15. self.config_path = conf.find_file(config_path)
  16. elif os.path.exists(config_path):
  17. self.config_path = config_path
  18.  
  19. if not self.config_path:
  20. raise ConfigNotFound(path=config_path)
  21.  
  22. def load_app(self, name):
  23. """Return the paste URLMap wrapped WSGI application.
  24. :param name: Name of the application to load.
  25. :returns: Paste URLMap object wrapping the requested application.
  26. :raises: PasteAppNotFound
  27. """
  28. try:
  29. LOG.debug("Loading app %(name)s from %(path)s",
  30. {'name': name, 'path': self.config_path})
  31. return deploy.loadapp("config:%s" % self.config_path, name=name)
  32. except LookupError:
  33. LOG.exception("Couldn't lookup app: %s", name)
  34. raise PasteAppNotFound(name=name, path=self.config_path)

配置文件api-paste.ini内容如下

  1. [composite:osapi_volume]
  2. use = call:cinder.api:root_app_factory
  3. /: apiversions
  4. /v1: openstack_volume_api_v1
  5. /v2: openstack_volume_api_v2
  6. /v3: openstack_volume_api_v3
  7.  
  8. [composite:openstack_volume_api_v1]
  9. use = call:cinder.api.middleware.auth:pipeline_factory
  10. noauth = cors http_proxy_to_wsgi request_id faultwrap sizelimit osprofiler noauth apiv1
  11. keystone = cors http_proxy_to_wsgi request_id faultwrap sizelimit osprofiler authtoken keystonecontext apiv1
  12. keystone_nolimit = cors http_proxy_to_wsgi request_id faultwrap sizelimit osprofiler authtoken keystonecontext apiv1
  13.  
  14. [composite:openstack_volume_api_v2]
  15. use = call:cinder.api.middleware.auth:pipeline_factory
  16. noauth = cors http_proxy_to_wsgi request_id faultwrap sizelimit osprofiler noauth apiv2
  17. keystone = cors http_proxy_to_wsgi request_id faultwrap sizelimit osprofiler authtoken keystonecontext apiv2
  18. keystone_nolimit = cors http_proxy_to_wsgi request_id faultwrap sizelimit osprofiler authtoken keystonecontext apiv2
  19.  
  20. cinder.conf文件中的api启动的配置
  21. 这三个参数控制的是api 版本的控制
  22. # DEPRECATED: Deploy v1 of the Cinder API. (boolean value)
  23. # This option is deprecated for remoervice_down_timeal.
  24. # Its value may be silently ignored in the future.
  25. #enable_v1_api = false--------不加载v1对应的app
  26.  
  27. # DEPRECATED: Deploy v2 of the Cinder API. (boolean value)
  28. # This option is deprecated for removal.
  29. # Its value may be silently ignored in the future.
  30. #enable_v2_api = True------------加载v2对应的app
  31.  
  32. # Deploy v3 of the Cinder API. (boolean value)
  33. enable_v3_api = True-------------加载v3对应的app
  34.  
  35. # The strategy to use for auth. Supports noauth or keystone. (string value)
  36. # Allowed values: noauth, keystone
  37. auth_strategy = keystone----------这个参数控制的api-paste.ini中选择哪一种认证方式

  

  

  

  

  

cinder api启动过程源码分析的更多相关文章

  1. Spark(五十一):Spark On YARN(Yarn-Cluster模式)启动流程源码分析(二)

    上篇<Spark(四十九):Spark On YARN启动流程源码分析(一)>我们讲到启动SparkContext初始化,ApplicationMaster启动资源中,讲解的内容明显不完整 ...

  2. Spark(四十九):Spark On YARN启动流程源码分析(一)

    引导: 该篇章主要讲解执行spark-submit.sh提交到将任务提交给Yarn阶段代码分析. spark-submit的入口函数 一般提交一个spark作业的方式采用spark-submit来提交 ...

  3. Android系统默认Home应用程序(Launcher)的启动过程源码分析

    在前面一篇文章中,我们分析了Android系统在启动时安装应用程序的过程,这些应用程序安装好之后,还须要有一个Home应用程序来负责把它们在桌面上展示出来,在Android系统中,这个默认的Home应 ...

  4. Android Content Provider的启动过程源码分析

    本文參考Android应用程序组件Content Provider的启动过程源码分析http://blog.csdn.net/luoshengyang/article/details/6963418和 ...

  5. Flume-NG启动过程源码分析(二)(原创)

    在上一节中讲解了——Flume-NG启动过程源码分析(一)(原创)  本节分析配置文件的解析,即PollingPropertiesFileConfigurationProvider.FileWatch ...

  6. 10.4 android输入系统_框架、编写一个万能模拟输入驱动程序、reader/dispatcher线程启动过程源码分析

    1. 输入系统框架 android输入系统官方文档 // 需FQhttp://source.android.com/devices/input/index.html <深入理解Android 卷 ...

  7. Activity启动过程源码分析(Android 8.0)

    Activity启动过程源码分析 本文来Activity的启动流程,一般我们都是通过startActivity或startActivityForResult来启动目标activity,那么我们就由此出 ...

  8. Netty入门一:服务端应用搭建 & 启动过程源码分析

    最近周末也没啥事就学学Netty,同时打算写一些博客记录一下(写的过程理解更加深刻了) 本文主要从三个方法来呈现:Netty核心组件简介.Netty服务端创建.Netty启动过程源码分析 如果你对Ne ...

  9. Spring启动过程源码分析基本概念

    Spring启动过程源码分析基本概念 本文是通过AnnotationConfigApplicationContext读取配置类来一步一步去了解Spring的启动过程. 在看源码之前,我们要知道某些类的 ...

随机推荐

  1. Day01_WebCrawler(网络爬虫)

    学于黑马和传智播客联合做的教学项目 感谢 黑马官网 传智播客官网 微信搜索"艺术行者",关注并回复关键词"webcrawler"获取视频和教程资料! b站在线视 ...

  2. PHP date_time_set() 函数

    ------------恢复内容开始------------ 实例 设置时间: <?php$date=date_create("2013-05-01");date_time_ ...

  3. PHP mysqli_refresh() 函数

    定义和用法 mysqli_refresh() 函数刷新表或缓存,或者重置复制服务器信息.高佣联盟 www.cgewang.com 语法 mysqli_refresh(connection,option ...

  4. 5.15 牛客挑战赛40 B 小V的序列 关于随机均摊分析 二进制

    LINK:小V的序列 考试的时候 没想到正解 于是自闭. 题意很简单 就是 给出一个序列a 每次询问一个x 问序列中是否存在y 使得x^y的二进制位位1的个数<=3. 容易想到 暴力枚举. 第一 ...

  5. CF 633 div1 1338 B. Edge Weight Assignment 构造

    LINK:Edge Weight Assignment 这场当时没打 看到这个B题吓到我了 还好当时没打. 想了20min才知道怎么做 而且还不能证明. 首先考虑求最小. 可以发现 如果任意两个叶子节 ...

  6. 5073 [Lydsy1710月赛]小A的咒语

    LINK:[Lydsy1710月赛]小A的咒语 每次给定两个串 要求从a串中选出x段拼成B串 能否做到.T组数据. \(n\leq 100000,m\leq 100000,T\leq 10,x\leq ...

  7. 每日一道 LeetCode (5):最长公共前缀

    前文合集 每日一道 LeetCode 前文合集 代码仓库 GitHub: https://github.com/meteor1993/LeetCode Gitee: https://gitee.com ...

  8. springMVC请求路径 与实际资源路径关系

    个人理解: 请求路径可以分为两部分:不通过springmvc转发的url:通过springmvc转发的url: 通过特定的配置,告诉springmvc哪些url需要从springmvc处理,处理后再跳 ...

  9. 实验04——java保留小数的两种方法、字符串转数值

    package cn.tedu.demo; import java.text.DecimalFormat; /** * @author 赵瑞鑫 E-mail:1922250303@qq.com * @ ...

  10. vue中模块局部刷新

    父组件: 一. 父组件中引入子组件           data中定义变量 二. 定义provide函数 三.写reload方法 需要刷新的那个子组件: 一.引入                   ...