放平心态,学会等待
分类:
2012-09-02 23:40:55
原文地址:swift源码分析(一)之swift服务启动 作者:remimin
之前一篇的swift部署,已经详细描述了基于ubuntu11.04版本SAIO的部署,从本篇开始,根据swift部署过程,研究swift详细执行流程。首先下载swift最新代码,查看swift代码的主要包含以下几个目录:
bin——swift主要操作脚本
doc——swift使用文档,可以使用python sphinx工具生成帮助文档,生成结果与官网相同
etc——swift相关配置文件示例
locale——不知道是啥
swift——swift核心代码package,包含account、common、container、obj、proxy 这个几个package。
test——swift测试package,可以进行单元测试、功能测试等
tools——swift安装所依赖的软件
代码主目录下还包含以下几个文件:
README、AUTHOURS、CHANGELOG、LICENSE、MANIFEST.in
包含两个配置文件babel.cfg、setup.cfg
一个脚本setup.py,用于部署swift
还有几个隐藏的脚本.functests .unittests .probetests .converagerc用于测试
.gitigonor .gitreview .mailmap是git代码相关的文件。
swift all in one的部署在《》已经详细描述过了,这里不再重复。
2. swift启动过程swift服务启动命令是swift-init main start
swift启动可见执行的是swift-init脚本命令,那么我的分析则从swift-init开始。
2.1. swift-initswift-init脚本之仅仅执行了一个main函数,main函数执行的内容:
创建了参数解析器,如果输入参数小于2,则输出帮助信息如下:
swift-init使用的方式:swift-init
server可以指定需要启动的服务器类型,account/ container /object/ proxy 中的任何一个,也可以是main/all/rest
l main:'proxy -server', 'account-server', 'container-server' ,’object-server'
l all: 'account-auditor', 'account-server' , 'container-auditor', 'container-replicator', 'container-server', 'container-sync', container-updater', 'object-auditor', 'object-server' , 'object-expirer' , 'object-replicator', 'object-updater', 'proxy -server', account-replicator', 'account-reaper'
l rest:main和all之间的差集
command类型支持:
l force-reload: alias for reload
l no-daemon: start a server interactively
l no-wait: spawn server and return immediately
l once: start server and run one pass on supporting daemons
l reload: graceful shutdown then restart on supporting servers
l restart: stops then restarts server
l shutdown: allow current requests to finish on supporting servers
l start: starts a server
l status: display status of tracked pids for server
l stop: stops a server
swift-init创建了一个Manager对象manage。Mangaer对象主要是管理所有的server,发送server控制命令和获取server的状态信息。
Manager类定义位于swift.common.manage模块中,分析swift.common.manage。
2.1.1. swift.common.manage模块包含两个主要的类Manager和Server。
提供3个功能函数:
setup_env:关于操作系统的设置
command:对Manager类命令函数的封装,返回值均为1或者0,且确保可执行的命令都是public权限
watch_server_pids:获取一段时间内的运行server的情况
两个重要目录
SWIFT_DIR = '/etc/swift' 所有的server配置文件都在此目录下,是在代码里面写死的,因此swift配置时必须在这里防止server配置文件
RUN_DIR = '/var/run/swift' server进程运行后就会生成pid文件放置此目录下。
这里留个问题object-expirer是个什么?
2.1.1.1. Manager类功能:执行server的相关命令,获取server的状态信息
初始化参数:server name列表
Manger支持server的种类:
l ALL_SERVERS = [ 'account-auditor', 'account-server' , 'container-auditor',
'container-replicator', 'container-server', 'container-sync',
'container-updater', 'object-auditor', 'object-server' , 'object-expirer' ,
'object-replicator', 'object-updater', 'proxy -server',
'account-replicator', 'account-reaper']
l MAIN_SERVERS = [ 'proxy -server', 'account-server', 'container-server' ,'object-server']
l REST_SERVERS = [s for s in ALL_SERVERS if s not in MAIN_SERVERS]
也可以是任意指定类型,如object、container、account、proxy
Manager成员变量server
Manager的成员变量servers是Server类型的对象,对于每一个在运行的server创建一个Server类型的对象。
可执行的command
status/start/no_wait/no_daemon/once/stop/shutdown/restart/reload/force_reload/get_commond/list_command/run_command
2.1.1.2. Server类功能:管理单独server的操作或者一组类型相似的server的操作
初始化参数:servername
成员变量:
server = servername-server(例如,object-server container-server,这里仅仅是server的名字)
type = servername(例如,object、container、account、proxy)
cmd = swift-servername-server(swift-object-server……)
procs = [](server的进程信息)
可执行操作
get_pid_file_name:由conf_file获取pid_file
pid_files = /var/run/swift 目录下,所有已pid结尾的文件的包括子文件夹下的所有文件
通过阅读源码发现:
container、accout、object配置的文件的获取过程,
必须从/etc/swift/container-server*/*.conf且conf的名字必须是有序的,因为会返回一个有序的数组,当指定第nthserver的消息时,是通过返回的conf的有序序列的顺序决定的。
subprocess.Popen(args, stdout=re_out, stderr=re_err)
这行代码启动了对应的server
launch函数是server启动的主要函数:
根据server类型或名字读取server相关的多个配置文件(/etc/swift/servername/*.conf),从而得到应该有多少个相关的进程存在或者启动。
根据配置文件转化为pid文件(/var/run/swift/servername/*.pid),得到正在运行的server的pid
将尚未启动的server进行启动,并为server创建对应的pid文件。
真正执行的启动server的是spawn(),返回pid
参数:
conf_file——需要启动的server对应的配置文件绝对路径。
执行过程:
1、 构建启动进程的参数集合args=[self.cmd, conf_file[,option可选参数]]
2、 使用subprocess.Popen()返回启动后的进程消息,server启动完成。
3、 创建server对应的pid文件,将返回的进程pid写入到pid文件中
4、 将proc加入到类全局变量procs集合中。
返回pid。
2.1.1.3. subprocess.Popensubprocess.Popen对象启动了server进程的创建
以object-server为例,在上一节传入的参数是
[swift-objetct-server /etc/swift/object-server/1.conf]
subprocess.Popen则执行上述命令并为之创建新的进程。
使用上述过程启动的进程是根据swift-init server start的参数server相关的。关于server的类型之前已经讨论过了。
2.2. main serverswift的server的种类为proxy、account、object、container四种。
/bin目录下对应的swift-*-server分别作为独立的服务进程处理不同的服务。查看源码发现,内容相似,使用了
swift.common.wsgi模块的run_wsgi主要功能函数,以swift-object-server为例
run_wsgi(conf_file, 'object-server', default_port=6000, **options)
wsgi模块是swift的主要通信组件将在下一节中进行分析。
2.2.1. swift.common.wsigswift.common.wsig描述“WSGI tools for use with swift”
wsgi模块使用了eventlet和paste.deploy。
run_wsgi主要功能:加载配置文件的设置,实例化app,并且运行指定数目的workers(在配置文件中可设置,默认为1)
参数:配置文件路径(符合paste.deploy规则的配置文件)
app_section:App名字从conf文件读取的(这里标注一下:swift代码里面这个是写死的,并不是动态从conf获取的,也就是两者必须保持一致,运行的app和配置文件,以及脚本命令相关部分)
swift.common.wsig使用了eventlet和paste.deploy
执行的过程是:
1. 创建socket绑定,根据配置文件的绑定IP地址与绑定端口的设置,创建socket并监听请求(提供两种方式,普通和ssl)
2. 根据配置文件,启动多个子进程
3. run_server()这部分是关键
run_server关键是启动了wgsi服务器,配置服务器的HTTP协议,事件处理方式“pool”,然后使用enventlet.wsgi.server启动了wgsi服务器,wsgi app即为通过配置文件加载的application。
查看配置文件object-server配置文件object-server/1.conf
[pipeline:main]指定了application为object-server section
[app:object-server]表明了应用程序是swift项目的object,
在swift项目的setup.py中定义了object的入口点:
查看swift.obj.server模块的app_factory,即为swift-object入口的地方。
返回的app_factory对象
2.3. rest server本节主要内容:manager部分定义rest类型的server启动流程
与main server启动不同的是,rest server启动采用的run_daemon函数.
以container-auditro-server为例,swift-container-auditor脚本主要的功能,如下。
ContianerAuditor是导入的类:from swift.obj.auditor import ObjectAuditor
run_daemon位于swift.common.daemon模块中
因此研究container-auditor-server启动流程关键的就是这两个模块
从conf_file路径指定的配置文件中获取配置信息,实例化daemon”kclass”,根据具体的参数**kwargs运行daemon。section_name如果没有提供的话,就从kclass分析提取,例如ObjectReplicator=>object-replicator
如图所示,rest server对象均是Class Daemon的派生类对象,run_deamon和run_forever是rest server的重要实现,分别是服务执行一次完成后退出,还是后台持久运行驻留内存。每个rest server均有logger和conf,用于获取服务的配置信息和记录日志行为。
图 1 swift-object-* Deamon类