Nova Data Flow(Newton版)
来源:互联网 发布:单片机连接摄像头 编辑:程序博客网 时间:2024/06/06 19:52
一、简介
- API :进入Nova的HTTP接口;
- Scheduler:从可用池中选择最合适的计算节点(物理机)来创建虚拟机实例;
- Conductor:为数据库的访问提供一层安全保障,避免Compute直接访问数据库;
- Compute:管理虚拟机的生命周期;
- nova-novncproxy:用户可以通过多种方式访问虚机的控制台,该种是基于Web浏览器的VNC访问;
- nova-consoleauth:负责对访问虚机控制台提供Token认证;
- nova-cert:提供x509证书支持
二、API服务
解析参数
具体的实现是:
这里主要是一些参数的初始化设置,同时把nova-api运行时需要的参数传递给cfg,接下来我们逐行分析:
首先看CONF=nova.conf.CONF,在conf/__init__.py中,大致看一眼是什么:
CONF是在oslo.config中定义的一个类,作为参数传入nova,作为在代码各处注册配置项的实例,和上图相似:
CONF实例化后被传入,调用到log库,会注册log相关的一些配置项
这部分通过判断[glance]组下的debug配置线,在log中选择启用glanceclient的报警类别
最终调用到下面这个:
可以看到这个就是设置下cfg文件中的_transport_opts参数,即默认的exchange是叫做nova。
追入代码能够知道该行是设置oslo.middleware的默认配置项,接下来:
其中argv是parse_args方法传入的第一个参数,即sys.argv,作为启动服务时命令行传入的参数,我们依据systemctl start openstack-nova-api的命令追溯到openstack-nova-api的老巢:
很可惜,ExecStart执行的命令后面没有跟--config-file /etc/nova/nova.conf这样预想的内容,所以argv[1:]即对应openstack-nova-api,default_config_files为None,在oslo.config中,实例化CONF时,会判断如果default_config_files为空的时候,会依据目录位置及项目名,找到nova.conf文件,这步将nova的CONF进行实例化。
这两步将rpc和db的配置项进行了初始化。可见参数的解析也有一定内容。
为nova设置logging
进入oslo.log可以看到,setup方法首先判断Nova是否有log相关的配置文件的传入,如果没有传入则使用nova.conf,然后对nova创建异常hook,当nova-api产生异常时,则会被hook,从而进行log的输出。这里不详细分析excepthook如何创建及工作,对应方法为_create_logging_excepthook(product_name)
monkey patch
monkey patch指的是在运行时动态替换,一般是在startup的时候.
用过gevent就会知道,会在最开头的地方gevent.monkey.patch_all();把标准库中的thread/socket等给替换掉.这样我们在后面使用socket的时候可以跟平常一样使用,无需修改任何代码,但是它变成非阻塞的了.
之前做的一个游戏服务器,很多地方用的import json,后来发现ujson比自带json快了N倍,于是问题来了,难道几十个文件要一个个把import json改成import ujson as json吗?
其实只需要在进程startup的地方monkey patch就行了,是影响整个进程空间的。同一进程空间中一个module只会被运行一次,给出一个demo,容易理解:再回到程序中,这里会判断配置文件中是否开启,如果开启了,会读取配置文件中的monkey_patch_modules内容,然后进行替换。默认是不开启的
注册所有的objects
这里也可以撇一眼具体内容:
__import__ 和import功能相同,不同的是作为函数,传入的是字符串格式,将nova.objects下的所有内容import进来
nova/objects目录下每一个类都对应数据库中的一个表,是操作数据库的最终接口,conductor、api操作数据库时都是经过objects
获取服务的启动器
追溯到process_launcher()方法的源头,在oslo.service中:
可以看到这段代码是为了获取一个ProcessLauncher的对象,这个ProcessLancher应该指的就是目前的这个进程,其后它会启动一些worker,并作为这些worker的父进程。这里的信号量主要就是捕获signal.SIGTERM和signal.SIGINT,如果得到了这两个信号的话就会设置ProcessLauncher的running属性为false。
启动对应的api
这里的CONF.enabled_apis对应配置文件的内容:enabled_apis = ec2, osapi_compute, metadata弄清这些是什么之前我们先看看service.WSGIService是什么:
该初始化方法通过paste库生成WSGI的app,不过这里的app只是其一个属性,这里的wsgi.Server会监听对应的端口,也就是说这个时候wsgi app已经起来了,实际在后面真正启动,我们看看刚才的enabled_apis具体是啥(运行代码时调试打印):
name属性即这个WSGIService的名字
manager只有metadata有,在配置文件中进行配置,搜索规则如下:loader是用于解析paste.ini生成的app,在这里都是用的默认的;
app即paste生成的WSGI的app,请求来了都发往这些app
host和port即监听路径及端口
worker则是具体的工作数,一般默认是一个CPU核对应一个,原因后续分析。继续看代码:这个地方比较关键,在__init__中,可以看到paste读取的配置项定义在CONF.wsgi.api_paste_config中,值为api-paste.ini,即load_app方法中会去/etc/nova/api-paste.ini文件中加载对应app,该文件解析不再详述。继续看:
_check_service_base检查传入的service类型是否为ServiceBase,warp为普通结构体,主要初始化了self.service、self.workers、self.children、self.forktimes这些内容,主要看self._start_child()方法:
可以看到,这里主要就是做一个fork的工作。fork的返回值如果是0的话那么当前的上下文就是子进程。否则就是在父进程中。
首先先看父进程的,父进程做的事情比较简单:启动子进程,然后记录一些信息(更新wrap),然后返回子进程的PID。
然后再看子进程的,子进程的话先通过launcher = self._child_process(wrap.service)启动对应的服务,然后就是while循环等待信号。如果有终止的信号量就结束,否则则重新启动进程。所以我们来看下launcher = self._child_process(wrap.service)做了什么吧,这里的service就是我们上面的WSGIService对象(有WSGI app在里边):首先是设置一些信号量,然后定义一个Launcher对象。这个对象和eventlet有关,可以看成就是启动一个线程。其最终会调用WSGIService的start方法(入口在service的add方法中self.tg.add_thread(self.run_service, service, self.done)的self.run_service里面):
self.server.start()即启动了一个WSGI的服务。
这里和普通的多线程模型下的HTTP server有一个很大的不同:普通的HTTP server在启动的时候只有一个线程在那里监听一个端口,来了一个请求才会fork一个线程去做独立的处理(也就是说如果请求很多的话,线程个数也会很多)。但这里由于使用了eventlet的绿化(本质就是协程,可以看这里),因此对于协程来说,一个协程只能运行在一个CPU核上,并且不存在来个请求就fork这种东西,所以这里会根据CPU的核的个数去建立对应的协程(worker)。当一个请求来了过后呢其就会交给某一个协程去处理。不管请求个数多少,协程的个数是固定的。协程在HTTP server方面的效率比较高。监听并服务
代码中,我们知道这里就是看自己的子进程(worker)是否挂了,挂了的话启动起来就行了。当然啦如果是收到了停止的信号量,那么就kill所有的子进程,然后launcher这个父进程也退出循环并结束了。
总结
nova-api的启动过程就是读取配置文件,生成TRANSPORT和NOTIFIER这两个全局对象用于消息操作。同时启动n个wsgi server,每个server对应配置文件中的一个api。另外根据系统的CPU核心数n,每个wsgi server都会有n个worker协程去处理请求。
- Nova Data Flow(Newton版)
- Zaqar Data Flow(Newton 版)
- Cloudkitty Data Flow(Newton版)
- openstack newton:独享宿主物理机(修改默认nova zone)
- OpenStack Newton版本部署----计算服务(nova)
- 数据流程图(Data flow diagram)
- uva 10594 - Data Flow(费用流)
- boot from volume分析(Newton版)
- 3.5 Data Flow任务
- DS5000 Data flow
- loopback interface data flow
- Data Flow Diagrams (DFDs)
- Receiving Module Data Flow
- UVa10594 Data Flow
- uva 10594Data Flow
- llvm:Data Flow Graph
- Spring Cloud Data Flow
- Spring Data Flow
- java IO总结
- 阿里云主机CentOs中Apache开启Rewrite模块
- Python
- 算法文章
- python练习(八)
- Nova Data Flow(Newton版)
- CentOS 6.5通过yum安装 MySQL-5.5
- [LeetCode] Single Number II
- 这是一篇用测试MetaAPI的测试内容2
- 【国家集训队2011】happiness 网络最大流
- jzoj5249 【NOIP2017提高A组模拟8.10】文本编辑器 (序列修改类问题,数据结构)
- 无法导入Jena包的问题机器解决
- 2017杭电多校第六场 1008 Kirinriki(暴力)HDU 6103
- vue.js学习笔记-3