nginx資源404問題排查


這篇文章本意是寫給我司現場技術支持的同事的,順手就放上來了。

背景

​ 生產環境經常會出現圖片訪問不到的情況,大部分是由於nginx配置或者說路徑指向不對導致的。

​ 本文檔僅針對網絡正常圖片存在的情況,如果說是網絡故障(ping不通圖片服務器或者說nginx端口未打開)那肯定優先排查網絡相關問題;如果說圖片根本不存在,那么只能從圖片生成的角度去排查問題。

nginx 簡介

​ nginx服務器是一個高性能的http服務器,目前市面上大部分的靜態資源(例如圖片,html文件等)訪問都是通過nginx服務器實現的,下文的圖片無法訪問的排查流程同樣適用於其他通過nginx訪問的靜態資源。簡單來說nginx服務器的作用就是將url轉換為對應服務器上的一個具體的文件路徑,如果url轉換后的路徑和實際的資源路徑不匹配,那么就會發生無法訪問對應資源的情況(例如圖片裂圖,或者直接頁面報錯404)。

​ nginx也可以作為反向代理服務器,但與本文無關,不作展開。

解決方法

​ 本文接下來會詳細講解在nginx配置文件中通過root或alias關鍵字修改路徑指向配置軟鏈接兩種方式來解決問題,這兩種方式比較輕量,當然暴力的將具體資源移動到url對應的路徑下也可以解決問題,但生產環境一般沒有這么理想,所以暫不討論。

​ nginx配置文件指nginx.conf,一般放在/etc/nginx/nginx.conf,如果沒有可以通過find命令查找。

​ 軟鏈接是指linux系統中的一種符號鏈接,這個文件包含了另一個文件的路徑名。可以理解為windows系統中的快捷方式,例如我們在桌面上建立了一個快捷方式,就可以直接通過這個快捷方式進入對應的文件夾,在linux中作用同理,用軟鏈接可以讓我們在不移動具體文件資源的情況下,讓nginx獲得正確的路徑指向。

​ 拋開root和alias兩個關鍵字可以實現路徑轉換,nginx還支持其他更高級的路徑轉換操作,例如rewrite,本文同樣不討論,有興趣自行了解。

排查思路

​ 當出現圖片無法訪問的情況,首先應拿到對應圖片的url(可以通過在瀏覽器頁面上點擊右鍵選擇檢查或者直接復制圖片地址),然后再對比圖片在服務器存放的實際位置,根據二者的差異選擇不同的解決辦法。

判斷ip和端口是否指向正確

​ 例如圖片url為:http://192.168.4.62:50001/ifsrc/engine1/picture/0001/1.jpg,但實際圖片存放路徑為192.168.4.63服務器上的/picture/0001/1.jpg,那么可以通過nginx配置文件中的proxy_pass配置項解決這個問題。

​ proxy_pass:轉發功能,將匹配上的路徑轉發到指定ip路徑。

​ 配置文件如下:

圖中表示192.168.4.62的nginx服務器會將http://192.168.4.62:50001/ifsrc/engine1/picture/0001/1.jpg 轉換為http://192.168.4.63:80/picture/0001/1.jpg然后自動訪問192.168.4.63的nginx服務器。

同時要非常主要圖中箭頭標注的位置的斜杠,如果不包含斜杠,那么最終的轉換結果為http://192.168.4.63:80/ifsrc/engine1/picture/0001/1.jpg

proxy_pass也可以替換路徑,有興趣可以自行了解。

url文件路徑和實際路徑不符

這種情況解決方法有很多種,比較靈活,本文只介紹配置新的location和軟鏈接兩種模式。

配置新的location可以理解為是改變nginx的指向,配置軟鏈接可以理解為是改變了文件的位置。

先簡單提一下nginx配置文件,如上圖,表示監聽192.168.4.62的50001端口,至於location本身支持很多種匹配,詳細情況見最后的location關鍵字詳解,此處只講解location的通用匹配。這里的location /表示默認匹配路徑,root /var/www/html表示默認匹配的根路徑,例如 http://192.168.4.62/1.jpg,其實際訪問的是 /var/www/html/1.jpg這個文件。

比如目前圖片的url為http://192.168.4.62:50001/changkou/changkou1/1.jpghttp://192.168.4.62:50001/changkou/changkou2/2.jpg

假設其實際存放的路徑如下:

/var
	/www
		/html
			/changkou1
				/1.jpg
			/changkou2
				/2.jpg

如果我們直接拿url去訪問,那么其實際訪問的地址為/var/www/html/changkou/changkou1/1.jpg/var/www/html/changkou/changkou2/2.jpg,自然會出現404的情況。

修改nginx配置文件

可以通過下圖中的兩種配置方式來解決。

root或者alias都可以用來配置指向路徑,只不過含義有一點區別。

對於root,nginx實際是將root路徑 + 匹配的location+匹配的location之后的路徑,對於changkou/changkou1/1.jpg這張圖片,那么實際nginx訪問的路徑就是 /var/www/html + /changkou/changkou1 + /1.jpg,與實際文件位置相同,可以正常訪問圖片。

對於alias,nginx實際是將alias路徑 + 匹配的location之后的路徑,對於changkou/changkou2/2.jpg這張圖片,那么實際nginx訪問的路徑是/var/www/html/changkou/changkou2/ + 2.jpg。也能達到相同的效果,可以正常訪問圖片。

配置軟鏈接

同樣是上面的問題,如果想要不改nginx配置文件,那么其里面只有一個通用的匹配規則,也就是任何圖片都會去/var/www/html/這個目錄下面去找,雖然生產環境一般不能直接將文件移動到該位置,但可以通過配置軟鏈接達到相同的效果。

創建軟鏈接的命令為:

sudo ln -s 目標文件夾 軟鏈接名稱

在不改變nginx配置文件的前提下,我們可以配置如下軟鏈接

sudo ln -s /var/www/html/ changkou

最終效果為:

經測試圖片同樣可以正常訪問。

在這種情況下,整個圖片的訪問流程如下

  1. 先根據url http://192.168.4.62:50001/changkou/changkou1/1.jpg,匹配到/var/www/html/changkou/changkou1/1.jpg
  2. 然后去/var/www/html/下面可以找名為 changkou 的軟鏈接或者目錄,實際能找到軟鏈接changkou
  3. 最后再根據changkou的軟鏈接定位到/var/www/html/,最后根據changkou1/1.jpg找到具體文件。

nginx配置文件中 location 關鍵字詳解

location 關鍵字是用來匹配對應的url,以對不同的url進行不同的處理。

location語法規則:

location [=||*|^~] /uri/ { … }

  • = 開頭表示精確匹配
  • ^~ 開頭表示uri以某個常規字符串開頭,理解為匹配 url路徑即可。nginx不對url做編碼,因此請求為/static/20%/aa,可以被規則^~ /static/ /aa匹配到(注意是空格)。以xx開頭
  • ~ 開頭表示區分大小寫的正則匹配 以xx結尾
  • ~* 開頭表示不區分大小寫的正則匹配 以xx結尾
  • !~!~*分別為區分大小寫不匹配及不區分大小寫不匹配 的正則
  • / 通用匹配,任何請求都會匹配到。

對於location匹配規則有興趣可以參考:nginx中location詳解 - 蒼青浪 - 博客園 (cnblogs.com)

官方文檔路徑如下:http核心模塊-Nginx官方文檔


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM