當(dāng)我們所有數(shù)據(jù)庫(kù)的 SQL
語句是通過子查詢方式完成,對(duì)于超時(shí)的控制往往很容易被大家忽略。因?yàn)榇蠹以诖a里看不到任何調(diào)用 set_timeout
的地方。實(shí)際上 PostgreSQL
已經(jīng)為我們預(yù)留好了兩個(gè)設(shè)置。
請(qǐng)參考下面這段配置:
location /postgres {
internal;
default_type text/html;
set_by_lua_block $query_sql {return ngx.unescape_uri(ngx.var.arg_sql)}
postgres_pass pg_server;
rds_json on;
rds_json_buffer_size 16k;
postgres_query $query_sql;
postgres_connect_timeout 1s;
postgres_result_timeout 2s;
}
生產(chǎn)中使用這段配置,遇到了一個(gè)不大不小的坑。在我們的開發(fā)機(jī)、測(cè)試環(huán)境上都沒有任何問題的安裝包,到了用戶那邊出現(xiàn)所有數(shù)據(jù)庫(kù)操作異常,而且是數(shù)據(jù)庫(kù)連接失敗,但手工連接本地?cái)?shù)據(jù)庫(kù),發(fā)現(xiàn)沒有任何問題。同樣的執(zhí)行程序再次 copy 回來后,公司內(nèi)環(huán)境不能復(fù)現(xiàn)問題。考慮到我們當(dāng)次升級(jí)剛好修改了 postgres_connect_timeout
和 postgres_result_timeout
的默認(rèn)值,所以我們嘗試去掉了這兩行個(gè)性設(shè)置,重啟服務(wù)后一切都好了。
起初我們也很懷疑出了什么詭異問題,要知道我們的 nginx
和 PostgreSQL
可是安裝在本機(jī),都是使用 127.0.0.1
這樣的 IP 來完成通信的,難道客戶的機(jī)器在這個(gè)時(shí)間內(nèi)還不能完成連接建立?
經(jīng)過后期排插問題,發(fā)現(xiàn)是客戶的機(jī)器上安裝了一些趨勢(shì)科技的殺毒客戶端,而趨勢(shì)科技為了防止無效連接,對(duì)所有連接的建立均阻塞了一秒鐘。就是這一秒鐘,讓我們的服務(wù)徹底歇菜。
本以為是一次比較好的優(yōu)化,沒想到因?yàn)檫@個(gè)原因沒能保留下來,反而給大家?guī)砺闊?。只能說企業(yè)版環(huán)境復(fù)雜,邊界比較多。但也好在我們一直使用最常見的技術(shù)、最常見的配置解決各種問題,讓我們的經(jīng)驗(yàn)可以復(fù)用到其他公司里。