轉(zhuǎn)自:http://www.oejia.net/blog/2016/12/16/odoo_static.html
現(xiàn)狀
對(duì)于odoo9、odoo10 部署過(guò)的人可能都知道其依賴(lài)于less環(huán)境,這是因?yàn)閺?odoo9 開(kāi)始 odoo 采用 less 模式來(lái)管理樣式文件,這帶來(lái)的改變的是前端的靜態(tài)請(qǐng)求不再是對(duì)應(yīng)一個(gè)實(shí)際的文件,odoo 會(huì)根據(jù).less 文件的是否改變來(lái)動(dòng)態(tài)編譯出 css 文件。另外 odoo 在非開(kāi)發(fā)模式下的靜態(tài)資源都做了打包合并處理,這同樣導(dǎo)致客戶(hù)端對(duì)幾個(gè)重點(diǎn)js css壓縮文件的請(qǐng)求沒(méi)有對(duì)應(yīng)到文件系統(tǒng)的實(shí)際文件。對(duì)于以上的客戶(hù)端請(qǐng)求 odoo 默認(rèn)是要去查詢(xún) db 得到實(shí)際物理路徑(名稱(chēng)做了 hash 處理,無(wú)法通過(guò) url 直接找到) 這樣導(dǎo)致 odoo 的靜態(tài)請(qǐng)求依賴(lài)于db,消耗了數(shù)據(jù)庫(kù)的性能,而且不方便做靜態(tài)分離,降低了整個(gè)站點(diǎn)承受并發(fā)的能力
本文將要描述的方案便是用來(lái)解決以上問(wèn)題,使我們的 db 查詢(xún)大量減少,并利用外部靜態(tài)化極大提升處理客戶(hù)端并發(fā)的能力,經(jīng)測(cè)試性能在 odoo10 的基礎(chǔ)上再提升60%以上
基本思路:
將odoo動(dòng)態(tài)產(chǎn)生的壓縮js、壓縮 css 以及實(shí)時(shí)編譯出的 css 集中保存到 data_dir 指定目錄下。然后借助 wsgi 的靜態(tài)服務(wù)或者 Nginx 的靜態(tài)location 直接處理客戶(hù)端的靜態(tài)請(qǐng)求,避免數(shù)據(jù)庫(kù)查詢(xún)
具體做法如下:
odoo/addons/base/ir/ir_qweb/assetsbundle.py中,增加如下處理
def write_file(self, url, content):
? ? m_root = tools.config.filestore('')
? ? full_path = os.path.join(m_root, url[1:])
? ? dirname = os.path.dirname(full_path)
? ? if not os.path.isdir(dirname):
? ? ? ? os.makedirs(dirname)
? ? with open(full_path, 'wb') as fp:
? ? ? ? print '>>> [ file ] save:',full_path
? ? ? ? fp.write(content)
在打包合并資源的代碼處添加如下代碼
def save_attachment(self, type, content, inc=None):
? ? # ...
? ? self.write_file(url,content)
? ? return attachment
在編譯出css后的地方添加如下處理
def preprocess_css(self, debug=False):
? ? # ...
? ? try:
? ? ? ? # ...
? ? ? ? self.write_file(url,asset.content)
? ? except psycopg2.Error:
? ? ? ? pass
以上處理即可將一些動(dòng)態(tài)生產(chǎn)的js、css集中到 odoo 工作目錄 的 data_dir/filestore/static 目錄下
在load_addons中加載每個(gè)app模塊時(shí)將模塊的 static 的目錄軟鏈到我們上面的“靜態(tài)集中目錄”下
def load_addons(self):
? ? # ...
? ? statics['/%s/static' % module] = path_static
? ? m_dir = os.path.join(odoo.tools.config['data_dir'],'filestore','common',module)
? ? if not os.path.isdir(m_dir):
? ? ? ? os.makedirs(m_dir)
? ? ? ? os.symlink(path_static,os.path.join(m_dir,'static'))
加載完后將“靜態(tài)集中目錄”路徑加入到 wsgi 靜態(tài)服務(wù)列表
statics['/static'] = os.path.join(odoo.tools.config['data_dir'],'filestore','static')
經(jīng)過(guò)以上處理后基本上css、js的請(qǐng)求都不會(huì)走db查詢(xún)了
為了使用更好的外部靜態(tài)服務(wù)、減少odoo服務(wù)進(jìn)程的請(qǐng)求開(kāi)銷(xiāo)我們可以也強(qiáng)烈建議使用 Nginx 高性能的靜態(tài)承載能力
Nginx的配置實(shí)例如下:
? ? location /static {
? ? ? ? expires 15d;
? ? ? ? root /home/jone/workspace/odoo10/data/filestore;
? ? }
? ? location ~ ^/[^/]+/static/{
? ? ? ? expires 15d;
? ? ? ? root /home/jone/workspace/odoo10/data/filestore/common;
? ? }
以上方案我們主要優(yōu)化了 odoo 的 css、js 等類(lèi)型靜態(tài)資源的請(qǐng)求,事實(shí)上 odoo 的其他(如圖片、附件)等靜態(tài)資源也是采用db檢索模式去查表以響應(yīng)客戶(hù)端請(qǐng)求的,對(duì)于這部分的優(yōu)化,讀者不妨先自行測(cè)試下他們?cè)谟脩?hù)量大的情況下對(duì)odoo服務(wù)性能的影響,筆者將在后續(xù)共享出對(duì)應(yīng)的優(yōu)化方案
Odoo 的性能優(yōu)化是隨著業(yè)務(wù)進(jìn)展、數(shù)據(jù)及用戶(hù)量提升后不得不做的事情,筆者也是致力于此,不斷研究提供一些有價(jià)值的參考方案