Odoo的启动过程是怎么样的?

Odoo
神州数码云基地
在 Odoo 上的尝试、调研与分享
本期作者
黄华信
后端开发工程师
一个幻想
01改变世界的中二青年
当Odoo启动的那一刻,到底发生了什么?
在早期odoo的源码研读中,我们粗浅的了解了odoo前后端交互的流程:【Odoo框架源码研读一:前后端交互】
而对于odoo在启动过程中的细节以及相关设计还缺乏细致的了解。
这次,我们想从odoo启动的那一刻开始,逐步了解odoo的整个生命周期以及其中细节,最终实现从0开始构建一套完整的odoo框架。
本期将会从odoo的启动命令说起,至web服务器的创建结束,详细了解odoo的启动过程~
#Odoo启动时
系统有哪些准备?
Odoo启动时,会调用主函数。
Odoo启动时,通过Odoo-bin启动文件启动,会调用command.py中的main函数,这里是Odoo启动的最初源头,是一切开始的地方。
这里可以看到server命令正准备执行,main方法的作用是分析命令行中的参数,匹配正确的命令,执行对应的操作。因为默认的命令是server,因此默认情况下,我们就启动了odoo的主服务进程
看过command的定义之后,可以确定这七个command其实是Odoo提供的工具命令:
help: 帮助
cloc: 用来统计代码行数和字数的工具
deploy: 发布模块的工具
scaffold: 创建第三方模块脚手架程序
populate: 自动化生成测试数据的工具
server: 启动的默认方法,启动主程序
shell: odoo的shell环境
start: 快速启动odoo服务器的命令
#Odoo的启动方式
server是Odoo的主程序 ,也是我们研究的重点。其主要的核心文件就是cli模块下的server.py文件。
odoo-bin文件启动过后,会执行server.py中的main函数。
这里可以看到,主程序启动过后,主要会检查启动用户是否是root用户以及postgres用户,继而检查csv文件大小不能超过500M。检查完这些之后,程序会根据workers配置项来启动server服务器。
server主程序的启动类型主要分为三种,这三种都继承于CommonServer:
类型一:ThreadedServer
多线程模式驱动的进程。
类型二:GeventServer
使用Gevent协程的Server。
类型三:PreforkServer
Gunicorn驱动的多进程实例。
接下来我们会详细为大家介绍一下不同类型的启动方式。
1、ThreadedServer模式下的启动
默认情况下,系统是以ThreadedServer方式启动。即:
线程模式下的启动会同时启动HttpServer和定时任务线程CronThread。
仔细看下cron_spawn()方法,我们可以看出,此处是根据 max_cron_threads这个配置参数来确定开启线程的数量。
在方法start中新开了一个线程来执行self.http_thread。
而http_thread()则创建了一个ThreadedWSGIServerReloadable对象。
传入的app即是前面说过的
openerp.service.wsgi_server.application。
通过代码可以知道:
ThreadedWSGIServerReloadable源于
werkzeug.serving.ThreadedWSGIServer。
接着调用server_forever()启动服务,监听请求。当请求来临时,根据WSGI协议:
openerp.service.wsgi_server.application方法会被调用。
2、Gevent模式下的启动
Gevent模式下同样使用的是WSGISever,不同的是使用gevent协程方式启动。
Gevent模式默认工作在8072端口,也就是长连接端口。顾名思义,GeventServer是用来处理长连接请求的服务,单进程模式下一般不使用此模式。
3、 PreforkServer 模式下的启动
PreforkServer模式下,进程会fork出多个进程,然后将多个进程的父进程指定为第一个进程,再调用worker的run方法启动。
PreforkServer采用gunicorn驱动,启动之后处理完进程信号、僵死进程、超时进程之后开始孵化新的进程。在孵化新进程过程中,会创建一个GeventServer用来处理长连接的任务。
#当Odoo启动后
主进程启动之后,odoo就进入到了监听模式。odoo处理HTTP请求的入口是http.py文件中的Root类。
我们来看一下Root的核心方法:
从中我们可以看出,odoo会判断当前进程是否加载的addons模块,没有加载则启动加载程序,最后再进入监听模式。
Root类的核心是dispatch方法,它负责给请求挂载session、绑定数据库、设置语言环境,以及处理一些请求中的异常。
接下来的部分就是我们很熟悉的Request部分的内容了。
#回顾整个流程
经过上文的讲解,我们再来回顾一下整个流程,以便更好地理解:
通过这个流程,可以一目了然的看到在启动Odoo时,我们先通过系统配置文件,进入启动程序,再选择不同的类型,执行启动,最后就可以用源码运行啦。

