Nginx配置如何解決瑣碎標(biāo)簽問題
Nginx配置在進(jìn)行Web服務(wù)器配置的時候有很多問題困擾著我們。其中ssi標(biāo)簽寫錯而ssi定義config errmsg為空字符串時,Nginx配置會出現(xiàn)empty reply,接下來我們就看看Nginx配置的相關(guān)問題。
如果ssi機器前面有Nginx代理,代理會打印error_log,并認(rèn)為這臺ssi的機器故障并屏蔽之。在我的環(huán)境中,因為代理upstream中使用了max_fails=0這個參數(shù),這個錯誤不會使Nginx屏蔽掉后端,但Nginx配置出現(xiàn)死循環(huán),負(fù)載升高,***死機。重現(xiàn)此bug:書寫一個有錯誤的,而且用了errmsg為空的html文件。aaa可以看到include中用的引號不小心打成了中文字符,人工去書寫include語句這種錯誤是很難避免的。訪問一下這個html,出現(xiàn)Empty reply from server。
- curl -i http://127.0.0.1/test.html
- curl: (52) Empty reply from server
本來這樣定義errmsg是希望出錯的ssi語句這一段不顯示任何東西,所以這里應(yīng)該顯示aaa,但Nginx配置顯然是出錯了。針對這個問題有幾種方案去解決:
1、換用apache,apache沒有這個問題。
2、讓編輯工作細(xì)心再細(xì)心,不要寫錯ssi標(biāo)簽。
3、將error_log整理后實時發(fā)給相關(guān)人員處理,或直接刪掉該頁。
4、Nginx修正bug。
換用apache的話,雖然解決了bug,但apache本身性能不夠,而且要重新書寫、測試配置;讓編輯細(xì)心這個一直都要求,但人總歸是人;整理error_log這個恐怕是來不及,死機的速度總是很快,死循環(huán)有可能在幾秒鐘之內(nèi)就殺死了Nginx代理;所以***只能通過修改Nginx源碼,把這個bug修復(fù),最為妥善。經(jīng)測試發(fā)現(xiàn),如果不寫errmsg標(biāo)簽,或者errmsg值不為空的話,這個bug是不存在的,只是在errmsg為空字符串時有,所以想辦法讓errmsg永不為空字符串就可以了。這樣的修復(fù)方式是回避問題型思路,事實上真正的bug還是存在的,只是把觸發(fā)它的因素干掉了,那這個bug就不會出來害人。因為真正的bug并沒有消除,所以下次碰到一個更特殊的情況,這個bug或許還會出現(xiàn)的。
修改Nginx配置源碼目錄中src/http/modules/ngx_http_ssi_filter_module.c這個文件,在代碼的2247行(0.7.59版,0.6.36版是2300行),有一個:
- if (value) {
- ctx->errmsg = *value;
- }
這句話的意思是,如果errmsg不是null,意味著有寫config errmsg這句配置,那就把config errmsg傳到ctx類中去。但是這行話沒有判斷value是不是一個空字符串,所以多加一個判斷:
- if (ctx->errmsg.len == 0)
- {
- ctx->errmsg.len = 1;
- ctx->errmsg.data = (u_char *)
- " ";
- }
因為c語言不過關(guān),所以幾行是從Nginx配置的代碼里東湊西拼的一句話,空字符串就是字符串長度為零,如果errmsg長度為零的話,就把errmsg變成一個空格。改完之后,make install,重啟一下Nginx訪問,現(xiàn)在不會出現(xiàn)Empty reply,在出錯的位置會打印一個空格,在一般的html里,多打一個空格不會有特別大的危害。
【編輯推薦】