今天在刷新公司項目頁面時發現有個板塊一直刷新不出數據,最后發現接口報錯(504 Gateway Time-out)
通過查看代碼發現有個sql語句,如下,特別慢
select `vdc1`,
`vdc2`,
`vdc3`,
`vdc4`,
`vdc5`,
`vdc6`,
`vdc7`,
`vdc8`,
`idc1`,
`idc2`,
`idc3`,
`idc4`,
`idc5`,
`idc6`,
`idc7`,
`idc8`,
`pdc1`,
`pdc2`,
`pdc3`,
`pdc4`,
`pdc5`,
`pdc6`,
`pdc7`,
`pdc8`,
`record_time`
from `t_inverter_dc_side_data`
where `inverter_code`= '7d006910-cce1-11e6-8c15-67da3e10436c'
and `record_time` like '2018-01-17%'
order by `record_time` desc
limit 1
用explain分析如下
其實是用到了索引,但是剛好這條sql語句在inverter_code和record_time這兩個條件下沒有根據索引找到數據,最終相當於沒有根據索引去找數據(explain中的rows統計信息是估算的並非精確值),導致接口響應時間超過了PHP腳本執行的限定時間。
(推薦一篇關於explain的博客
http://www.cnblogs.com/xuanzhi201111/p/4175635.html)
解決方法
方法一.在代碼業務邏輯中添加如下條件,先去判斷是否存在數據
select exists(select id from `t_inverter_dc_side_data` where `inverter_code` = '7d006910-cce1-11e6-8c15-67da3e10436c' and `record_time` like '2018-01-17%') as `exists`
方法二.添加inverter_code和record_time組合索引(效果特別明顯)
添加組合索引之后的explain結果如下:
方法三.網上關於修改服務器相關軟件參數提供的一些建議(沒試過不知道是否有效)
情況一:
由於nginx默認的fastcgi進程響應緩沖區太小造成, 這種情況下導致fastcgi進程被掛起,如果fastcgi服務隊這個掛起處理不是很好的話,就可能提示“504 Gateway Time-out”錯誤。
情況一解決辦法:
默認的fastcgi進程響應的緩沖區是8K,我們可以設置大一點,在nginx.conf里,加入:fastcgi_buffers 8 128k, 這表示設置fastcgi緩沖區為8塊128k大小的空間。
情況一解決辦法(改進):
在上述方法修改后,如果還是出現問題,我們可以繼續修改nginx的超時參數,將參數調大一點,如設置為60秒:
send_timeout 60;
經過這兩個參數的調整,結果沒有再提示“504 Gateway Time-out”錯誤,說明效果還是挺不錯的,問題基本解決。
情況二:PHP環境的配置問題
這里我們需要對php-fpm和nginx進行配置修改。因為這種情況下,也會出現“504 Gateway Time-out”錯誤提示。
情況二解決辦法( php-fpm配置修改):
將max_children由之前的10改為30,這樣操作是為了保證有充足的php-cgi進程可以被使用。
將request_terminate_timeout由之前的0秒改成60秒,這樣使php-cgi進程處理腳本的超時時間提高到60秒,可以防止進程被掛起以提高利用效率。
情況二解決辦法(nginx配置修改):
為了減少fastcgi的請求次數,盡量維持buffers不變,我們要更改nginx的幾個配置項,如下:
將fastcgi_buffers由4 64k改為2 256k;
將fastcgi_buffer_size 由64k改為128k;
將fastcgi_busy_buffers_size由128k改為256k;
將fastcgi_temp_file_write_size由128k改成256k。
情況二解決辦法修改完,我們需要重新加載php-fpm和nginx的配置,然后再進行測試。之后就沒有發現“504 Gateway Time-out”錯誤,效果也還是不錯的!
補充:
各種以5開頭的服務器相關錯誤提示:
一:500錯誤
1、500 Internal Server Error 內部服務錯誤:顧名思義500錯誤一般是服務器遇到意外情況,而無法完成請求。
2、500出錯的可能性:
a、編程語言語法錯誤,web腳本錯誤
b、並發高時,因為系統資源限制,而不能打開過多的文件
3、一般解決思路:
a、查看nginx、php的錯誤日志文件,從而看出端倪
b、如果是too many open files,修改nginx的worker_rlimit_nofile參數,使用ulimit查看系統打開文件限制,修改/etc/security/limits.conf,還是出現too many open files,那就要考慮做負載均衡,把流量分散到不同服務器上去了
c、如果是腳本的問題,則需要修復腳本錯誤,優化代碼
二:502、504錯誤
1、502 Bad Gateway錯誤、504 Bad Gateway timeout 網關超時
2、502、504出現的可能性
web服務器故障、程序進程不夠
3、一般解決思路
a、使用nginx代理,而后端服務器發生故障;或者php-cgi進程數不夠用;php執行時間長,或者是php-cgi進程死掉;已經fastCGI使用情況等都會導致502、504錯誤。
b、502 是指請求的php-fpm已經執行,但是由於某種原因而沒有執行完畢,最終導致php-fpm進程終止。一般來說,與php-fpm.conf的設置有關,也與php的執行程序性能有關,網站的訪問量大,而php-cgi的進程數
偏少。針對這種情況的502錯誤,只需增加 php-cgi的進程數。具體就是修改/usr/local/php/etc/php-fpm.conf文件,將其中的max_children值適當增加。這個數據要依據你的服務器的配置進行設置。
一般一個php-cgi進程占20M內存,你可以自己計算下,適量增多。
/usr/local/php/sbin/php-fpm reload 然后重啟一下.
c、504 表示超時,也就是客戶端所發出的請求沒有到達網關,請求沒有到可以執行的php-fpm。與nginx.conf的配置也有關系。
501 服務器不具備完成請求的功能。例如,服務器無法識別請求方法時可能會返回此代碼。
503 服務器目前無法使用(由於超載或停機維護)。通常,這只是暫時狀態。(服務不可用)
505 服務器不支持請求中所用的 HTTP 協議版本。(HTTP 版本不受支持)
來源: