Openresty 性能調(diào)優(yōu)案例

對(duì) gateway (commit id = 8ef7a8f2185c41777) 壓測(cè)時(shí)采集火焰圖,壓測(cè)前需配置 lua_code_cache=on,使用網(wǎng)關(guān)默認(rèn)路由,不配置插件,

qps 如下:

image.png

采集得到的火焰圖如下:

image.png

一、找出火焰圖的平頂

火焰圖就是看頂層的哪個(gè)函數(shù)占據(jù)的寬度最大。只要有平頂,就表示該函數(shù)可能存在性能問題

從火焰圖中可以看出,apirouter.lua存在比較耗時(shí)的調(diào)用 lj_str_new, 這一般是由于字符串操作導(dǎo)致的

image.png

逐步注釋字符串相關(guān)代碼進(jìn)行火焰圖分析,發(fā)現(xiàn)是由紅框標(biāo)識(shí)代碼導(dǎo)致,而ngx.re.match函數(shù)本身可以被jit,沒有更優(yōu)的替代方法,

image.png

從另一方面考慮,可能是由于ngx.re.match調(diào)用次數(shù)過多導(dǎo)致,通過代碼統(tǒng)計(jì),因?yàn)槠ヅ涞氖悄J(rèn)路由,這段函數(shù)總計(jì)調(diào)用了270次,

修改代碼直接路由到默認(rèn)路由,得到了如下數(shù)據(jù):

image.png
image.png

從圖中可以看出,相關(guān)耗時(shí)調(diào)用已經(jīng)消失,qps有所增加,但實(shí)際代碼中顯然不能如此修改。

項(xiàng)目使用遍歷所有路由進(jìn)行轉(zhuǎn)發(fā)的算法,算法復(fù)雜度為O(n),比較耗時(shí),關(guān)于路由算法,后面專門進(jìn)行分析。

二、觀測(cè)每個(gè)業(yè)務(wù)函數(shù)的寬度( 基于on-cpu-flame(2) )

從火焰圖中可以看出,耗時(shí)比較長(zhǎng)的調(diào)用有

1、content_by_lua 階段

(1)網(wǎng)關(guān)返回的response

image.png

從中可以看出,存在字符串操作 lj_str_new,由于.. 操作符每次都會(huì)新申請(qǐng)臨時(shí)空間來拼接字符串,利用table.concat去掉所有臨時(shí)空間的申請(qǐng)和GC

image.png
image.png

(2) 網(wǎng)關(guān)轉(zhuǎn)發(fā)至上游的 request 和 response

從圖中可以看出轉(zhuǎn)發(fā)耗時(shí)主要是在發(fā)送和接收中,這也是整個(gè)請(qǐng)求生命周期中最耗時(shí)的操作

image.png

其中每個(gè)請(qǐng)求都對(duì)請(qǐng)求體進(jìn)行json解析比較耗時(shí),這個(gè)后期可以考慮優(yōu)化

image.png

2、log_by_lua 階段

記錄metrics最為耗時(shí),暫沒發(fā)現(xiàn)優(yōu)化空間

記錄log,由于現(xiàn)在是每個(gè)請(qǐng)求的日志都立即記錄,操作過于頻繁,可以累積一定日志后再進(jìn)行記錄

image.png

優(yōu)化后qps明顯提高

image.png

3、rewrite_by_lua 階段

沒有發(fā)現(xiàn)優(yōu)化空間

image.png

4、uuid

生成uuid比較耗時(shí),暫無(wú)優(yōu)化

image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容