经过近几年来的发展,odoo的应用越来越广泛,用户和数据量也越来越大。经过多年的沉淀,系统不可避免的会出现一些性能问题。根据个人多年的踩坑生涯,针对odoo的性能优化问题,整理了一些思路。在此提供给各位odoo人士参考。大家如果在实际业务中,针对性能优化这一块有独家体会的,也欢迎留言讨论,为Odoo的普及添砖加瓦。
在开局之前,我们先看一个草图:
这是一个最简单的odoo环境架构图。
用户通过浏览器发出指令;
浏览器与后台服务器通信,odoo后端程序与PG数据库连接获取数据;
Odoo返回获取的html、js、css、业务数据等内容;
浏览器解析获取的数据,并执行js代码,渲染html。
就是这么简单的一个处理过程。这个过程中有多个会影响性能的瓶颈因素,接下来我们就针对每个有影响的点进行分析。
一、用户的硬件/网络环境
因为Odoo是属于B/S架构的系统,所以网络带宽的因素是必不可少的。网络影响最明显的就是服务器如果是公司内部,速度就会比较快;如果服务器是云主机,访问速度就会变慢。所以有条件的公司可以适当的增加网络带宽。当然现有的网络环境基本上都能满足odoo的使用需要,这个不会是影响我们系统性能的主要因素。
另外现在odoo有近一半的代码是js,而js是由浏览器解释执行的,所以我们选谷歌浏览器来执行odoo系统,这个处理js目前应该是最快的,而且用户电脑的CPU性能也会影响odoo界面的渲染速度。
二、http静态数据优化
在系统使用过程中,会频繁的通过网络交互数据,程序代码越来越多,再优秀的老黄牛也会累趴下。所以我们先考虑把一些css、js、png、jpg等静态文件进行处理。主要方式是压缩、缓存。
非调试模式下,odoo已经对css、js进行了压缩(主要是去空格,去注释),图片内容的话主要是我们自己要留意,比如公司logo,显示的地方就那么大,你上传一个1024*1024的图片上来,浪费网络带宽不说,浏览器适配显示时还要进行缩放,影响展示速度。所以我们上传的图片大小最好就是最后展示出来的效果大小。
在Chrome浏览器的开发环境下,我们可以查看一下odoo系统的网络请求情况:
这里会显示每一个客户端向服务器请求的类型、大小、时间。其中xhr类型是属于odoo业务数据的请求,我们在后面会讲到怎么来优化。这里先主要看script、stylesheet、png、gif这些静态文件。
这里我们再来看一张草图:
这里我们在odoo服务端加了一个Nginx,我们主要用到的是Nginx的反向代理、gzip功能。
原来odoo服务占用的是8069端口,而常用的web服务端口是80、443,所以我们需要用Nginx来接收外部来自80(443)的请求,转发给8069端口的odoo。
这里我们重点讲的是Nginx的压缩(gzip)和缓存功能,根据业界标准,为减少客户端与服务器的数据流量,客户端可以把请求数据压缩后发给服务器,然后服务器也可以把响应数据压缩发给客户端。压缩后的数据量会小很多,在网络上能更快的传输,当然执行效率也会提高。当然这个压缩和解压缩的过程会消耗一定的CPU资源,但基本上与网络传输效率来讲,可以忽略不计。
Nginx开启gzip功能,只要在nginx.conf中修改相应的参数即可。如下图所示:
这里的gzip_types是用来设置你需要压缩的请求数据类型,一般我们是把静态文件类型设置即可。配置好以后重启Nginx,使参数生效,然后我们怎么判断是否真的客户端请求使用了gzip压缩呢?我们同样可以在开发者工具的网络请求中,点开任意一个请求查看详情:
我们会发现这里的请求和响应内容都进行了压缩,而且查请求的数据大小,也会发现比原来的数据要小得多。
好了,解决了数据大小的问题,我们再来看数据重复请求的问题。同一份数据如果反复要从服务器上读取,这样势必会增加服务器的负担,所以我们要对一些数据资源进行缓存。
缓存一般有两种,一种是在客户端浏览器上缓存,另一种是在服务器端Nginx缓存。
如果资源需要在客户端上缓存,则在odoo业务代码中,对返回的资源需要设置一些缓存相关的参数,可以参考http.py中send_file方法的内容。这种情况下相同资源重复请求时,浏览器都不会重新向服务器发起请求,而是直接从缓存中读取数据。
另一种是Nginx的设置,浏览器发起重复请求时,Nginx不会向Odoo请求资源,而是直接从自己的缓存中返回已经缓存好的数据,这种需求要修改Nginx的相关参数,可能不同版本的Nginx参数会有点不一样,这个可以自选测试。
解决好压缩和缓存以后,针对性能方面,我们还有一个地方要注意,就是Odoo使用了很多第三方js库,在所有请求的资源中,我发现有些资源并不是向odoo请求的,而是向第三方服务器请求的,而这些服务器大多在国外,访问效率低,而且有些资源就算是返回404,也不会影响系统运行。所以我们需要修改这些资源的请求链接,用国内的资源来代替,或者删除这些无效的请求。
最后,对于大型互联网应用场景,用户比较分散,访问量也较多的情况下,静态资源也可以考虑用CDN,因为我们ERP主要还是相对集中的用户使用,所以你们自己去判断。
*本来打算用一篇文章讲完所有内容的,但啰啰嗦嗦发现一下就写了好多了,那剩下的就另外再写的,后面大概还有两部分,就是PG的性能优化和Odoo代码的优化。