扫码阅读
手机扫码阅读

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

333 2023-09-07

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时,我们先通过系统配置文件,进入启动程序,再选择不同的类型,执行启动,最后就可以用源码运行啦。

我们想用最简单的方式讲清楚一个复杂的道理~

具体的实现路径及方法原理已奉上,希望有更多的小伙伴能够掌握其中的奥秘,一起构建更好的生态!

想要了解更多,点击 查看原文