對(duì)于一個(gè)Web開發(fā)者來說,504和502問題看上去好像很簡單,每個(gè)人也可能都遇到過,但把問題說清楚并不那么容易,也希望這兩篇文章能夠幫助您。
十年的襄城網(wǎng)站建設(shè)經(jīng)驗(yàn),針對(duì)設(shè)計(jì)、前端、開發(fā)、售后、文案、推廣等六對(duì)一服務(wù),響應(yīng)快,48小時(shí)及時(shí)工作處理。營銷型網(wǎng)站的優(yōu)勢是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動(dòng)調(diào)整襄城建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計(jì),從而大程度地提升瀏覽體驗(yàn)。創(chuàng)新互聯(lián)建站從事“襄城網(wǎng)站設(shè)計(jì)”,“襄城網(wǎng)站推廣”以來,每個(gè)客戶項(xiàng)目都認(rèn)真落實(shí)執(zhí)行。兩臺(tái)設(shè)備只要通過proxy或fastcgi協(xié)議互相通信,都會(huì)遇到504問題,比如Nginx+PHP-FPM會(huì)遇到;代理服務(wù)器連接后端Web服務(wù)也會(huì)遇到。我本次遇到的場景屬于后者,重點(diǎn)講解代理導(dǎo)致的504問題。
問題分析
為了把問題說清楚,先介紹下我單位服務(wù)部署架構(gòu),如下圖:成都服務(wù)器托管
很多讀者看到https訪問,猜測504問題是不是因它而起,實(shí)際上完全沒有關(guān)系,但整個(gè)部署架構(gòu)卻因?yàn)橐肓藄sl,導(dǎo)致系統(tǒng)復(fù)雜化了。未來ssl肯定是主流,如果你這張圖的部署感興趣,可以看看我的新書《深入淺出HTTPS:從原理到實(shí)戰(zhàn)》,里面描述的很詳細(xì),此處也算作個(gè)廣告。
在本文引入這張圖的根本原因是想讓讀者能夠清晰的了解我遇到的問題,如果沒有這張圖,讀者在理解的時(shí)候會(huì)很困難。但也不要想的過于復(fù)雜,簡單理解就是nginx作為代理服務(wù)器連接后端的web服務(wù)器(apache/mod_php)。
接下來描述具體遇到問題,在瀏覽器中訪問https://mail.sina.net/x.php的時(shí)候,該接口上傳文件然后存儲(chǔ)到阿里云OSS上,如果傳輸?shù)奈募浅4螅瑘?zhí)行時(shí)間將會(huì)很長,一旦到20秒到時(shí)候,必然會(huì)出現(xiàn)出現(xiàn)504錯(cuò)誤,具體如下圖:成都服務(wù)器托管
順帶說一下,其他頁面和接口沒有遇到該問題,在那一刻會(huì)懷疑是不是x.php程序處理有問題(大部分人會(huì)這么理解)。
那到底上面是504錯(cuò)誤呢,看下wiki的引用:成都服務(wù)器托管
4 Gateway Timeout
The server was acting as a gateway or proxy and did not receive a timely response from the upstream server
它的意思就是一個(gè)網(wǎng)關(guān)或代理服務(wù)器能夠連接后端服務(wù)器,但在讀取服務(wù)器響應(yīng)的時(shí)候超時(shí)了。遇到504問題一般是后端服務(wù)的問題,比如:成都服務(wù)器托管
解決問題
按照上述可能的兩個(gè)情況,逐一分析。
(1)x.php程序在特定的情況下,確實(shí)運(yùn)行緩慢,但apache的access log在25秒左右的時(shí)候成功記錄了200訪問日志(由于php代碼執(zhí)行結(jié)束后才記錄日志,一開始可能看不到access日志,導(dǎo)致開始誤認(rèn)為是后端程序的問題)。
(2)在x.php程序中記錄應(yīng)用日志,應(yīng)用日志和access log日志一樣,沒有任何異常。
這說明代碼并沒有問題(但程序執(zhí)行時(shí)間過長,有優(yōu)化的空間),雖然在20秒產(chǎn)生504錯(cuò)誤(由nginx處理),后端代碼進(jìn)程仍然繼續(xù)運(yùn)行,并在25秒成功運(yùn)行。
排除這個(gè)問題后,最有可能是代理服務(wù)器覺得后端響應(yīng)過于緩慢,主動(dòng)關(guān)閉了該連接,是不是代理服務(wù)器設(shè)置的超時(shí)時(shí)間過短?由于公司的代理服務(wù)器(ssl nginx)是由專人維護(hù)的,我看不到具體的配置,郵件詢問了同事,得到回復(fù)如下:成都服務(wù)器托管
首先看下 proxy_read_timeout 的官方介紹:成都服務(wù)器托管
介紹的很詳細(xì)了,得到這個(gè)答復(fù)我就很疑惑了,超時(shí)時(shí)間是60秒,但504在20秒的時(shí)候就產(chǎn)生了,大大的問號(hào)懸我腦袋上,又仔細(xì)看了下官方文檔,是不是 proxy_read_timeout 參數(shù)的值寫的不嚴(yán)謹(jǐn),官方寫的是60s,可即使寫錯(cuò)了,nginx 默認(rèn)的超時(shí)時(shí)間也是60秒;是不是nginx 版本默認(rèn)超時(shí)時(shí)間不一致?官方文檔也并沒有對(duì)該指令有特殊的說明。
最后同事將該值修改為:成都服務(wù)器托管
問題最終解決了,肯定是proxy讀取超時(shí)了,但具體的配置仍然讓我疑惑。
進(jìn)一步測試
由于我看不到公司代理服務(wù)器的具體配置,所以我安裝了一個(gè)代理服務(wù)器,感興趣的同學(xué)也可以進(jìn)一步了解nginx的proxy配置,如果沒有特殊的需求,配置非常簡單。
proxy_pass 可以是一個(gè)host、內(nèi)部域名、ip地址,不用是一個(gè)對(duì)外的域名。
如果遇到超時(shí)問題,觀察error.log日志,會(huì)看到以下錯(cuò)誤:成都服務(wù)器托管
最后我不斷調(diào)整nginx的proxy_read_timeout指令和后端x.php程序的執(zhí)行時(shí)間,也沒有遇到工作中遇到的問題(20秒和60秒之間不對(duì)稱的問題),只能后續(xù)繼續(xù)留意了。成都網(wǎng)站建設(shè)公司
總結(jié)
1:網(wǎng)關(guān)和后端的超時(shí)時(shí)間(proxy或fastcgi)必須協(xié)調(diào)一致,在本案例中,apache/mod_php運(yùn)行最長時(shí)間如果是30秒,那么nginx設(shè)置的超時(shí)時(shí)間必須大于30秒,因?yàn)楸仨毧紤]網(wǎng)絡(luò)傳輸延時(shí)時(shí)間(非網(wǎng)絡(luò)包總傳輸時(shí)間);而如果是nginx+php-fpm模式,nginx設(shè)置的超時(shí)時(shí)間相對(duì)簡單,因?yàn)榇蟛糠智闆r下,nginx和php-fpm部署在同一臺(tái)機(jī)器上,網(wǎng)絡(luò)延時(shí)相對(duì)較短,但必須考慮php大執(zhí)行時(shí)間和php-fpm大執(zhí)行時(shí)間,后續(xù)我會(huì)寫一篇關(guān)于php-fpm和php之間協(xié)調(diào)工作的文章。
2:針對(duì)5**錯(cuò)誤,可認(rèn)為都是http錯(cuò)誤碼,都是服務(wù)器端的錯(cuò)誤(相對(duì)于客戶端),在遇到相關(guān)錯(cuò)誤的時(shí)候,我們必須根據(jù)錯(cuò)誤碼判斷可能存在的問題,然后再針對(duì)性的排查,否則排查時(shí)間會(huì)增加很多。
創(chuàng)新互聯(lián)客戶idc服務(wù)中心,提供成都服務(wù)器托管、成都服務(wù)器、成都主機(jī)托管、成都雙線服務(wù)器等業(yè)務(wù)的一站式服務(wù)。通過各地的服務(wù)中心,我們向成都用戶提供優(yōu)質(zhì)廉價(jià)的產(chǎn)品以及開放、透明、穩(wěn)定、高性價(jià)比的服務(wù),資深網(wǎng)絡(luò)工程師在機(jī)房提供7*24小時(shí)標(biāo)準(zhǔn)級(jí)技術(shù)保障。