2013-09-30 31 views
5

我有3個不同的存儲區域:「化身」,「文章」,「趨勢」,我存儲我的圖像。Nginx:從不同的根和位置發送JPG圖像

我想將URL「/trends/123.jpg」鏈接到趨勢文件夾,「/avatars/23.jpg」鏈接到頭像等等。

配置1:

server 
{ 
    listen 8089; 
    server_name localhost; 

    root /var/www; 

    location /trends/ 
    { 
      alias /var/storage/hottrend/; 
    } 

    location ~* ^.+\.(jpeg|gif|png|jpg) 
    { 
      add_header Cache-control "public"; 
      access_log off; 
      expires  90d; 
    } 
} 

配置1: 「GET /trends/123.jpg」 永遠比不上/趨勢/位置,爲什麼呢?

配置2:

server 
{ 
    listen 8089; 
    server_name localhost; 

    root /var/www; 

    location ~ ^/trends/(.*)\.jpg$ 
    { 
      rewrite ^/trends/(.*)$ /$1 break; 

      root /var/storage/hottrend; 
    } 

    location ~* ^.+\.(jpeg|gif|png|jpg) 
    { 
      add_header Cache-control "public"; 
      access_log off; 
      expires  90d; 
    } 
} 

配置2:與緩存的東西最後一個規則不匹配。什麼是從不同的位置/根服務器JPG文件的最佳途徑?

+0

有多種原因可能導致位置不匹配。你能列出其他位置(他們的內容不需要)嗎? –

+0

由於nginx遵循符號鏈接,您還可以使用諸如'trends - >/var/storage/trends'這樣的符號鏈接來獲得期望的效果。 –

+0

@KevinA.Naudé我不想使用符號鏈接,因爲所有代碼都必須運行在不同的「環境」上。(儘管這是最簡單的解決方案;-( –

回答

21

兩個配置中的任何其他位置確保location ~\.jpg$出現有不同但相關的問題。這兩個問題是:

  1. 在地點的順序匹配;和
  2. 當地點匹配時會發生什麼情況。

我會先解釋它是如何工作的,然後我將討論您的配置。

它是如何工作

位置的匹配

你可以找到關於此nginx wiki page的細節,但我一直覺得措辭是混亂的。 (它在行爲描述中混合實現細節。)它的意思是,位置按以下順序匹配:像location = /robots.txt

  • 渴望非正則表達式的前綴等location ^~ /trends/
  • 正則表達式像location ~* \.(jpg|png)相匹配時,或區分大小寫

    1. 精確匹配location ~ \.(jpg|png)
    2. 惰性非正則表達式前綴如location /trends/location /

    如果多個regul ar表達式匹配,然後第一場比賽擊敗其他人。如果多個非正則表達式匹配,我認爲它選擇了最具體的匹配 - 我會檢查並更新。

    位置行爲

    的匹配位置是負責服務於指定的內容。它還負責提供緩存控制標題等。您可以擁有與特定網址格式相匹配的位置來應用特定的標頭,但該位置也必須提供內容。如果它無法提供內容,則很可能會收到404錯誤 - 它不會查找其他匹配的位置。

    最後,如果你有一個位置內重寫要格外小心。內部重定向可能比某些指令更早發生,在這種情況下,那些指令可能在重定向導致位置再次被搜索之前不適用。

    配置1

    您的趨勢位置是一個懶惰的非正則表達式的前綴,因此,如果正則表達式的位置不匹配,將只匹配。您可以通過使用渴望的非正則表達式匹配來修復此問題,例如

    location ^~ /trends { 
        ... 
    } 
    

    但是,這樣做會突出顯示其他配置問題。

    配置2

    您有可能匹配的jpg文件的兩個位置。只有一個會成功。如果第一個匹配,則第二個位置的緩存控件將不會被應用。如果第二個匹配,那麼別名不會生效。

    的解決方法是,確保所需的所有指令都是相匹配的位置內應用。你可以是明確的在一個文件中,如

    location ^~ /trends 
    { 
        alias /var/storage/hottrend; 
    
        add_header Cache-control "public"; 
        access_log off; 
        expires  90d; 
    } 
    
    location ~* ^.+\.(jpeg|gif|png|jpg) 
    { 
        add_header Cache-control "public"; 
        access_log off; 
        expires  90d; 
    } 
    

    管理必須應用到多個位置的指示更合適的解決方案是將這些細節因素到另一個文件,然後include它在這兩個位置。 (穆罕默德阿布沙迪在他的例子中是這樣做的)。類似這樣的:

    # Inside your main .conf 
    location ^~ /trends 
    { 
        alias /var/storage/hottrend; 
        include image-headers.conf; 
    } 
    
    location ~* ^.+\.(jpeg|gif|png|jpg) 
    { 
        include image-headers.conf; 
    } 
    
    # Inside image-headers.conf 
    add_header Cache-control "public"; 
    access_log off; 
    expires  90d; 
    
  • +0

    感謝您花時間做出真正的解釋,您知道一個好的博客或文檔,我可以提高我的nginx嗎? –

    +0

    @ThomasDecaux不客氣。維基是當前最好的信息來源,但需要仔細閱讀。也可以偶爾從更改日誌中獲取有用的信息。 –

    2

    好吧,我通常不使用別名,但我認爲這是一個很好的例子來使用別名,你可以把你的緩存設置在/etc/nginx/image_caching.conf。如果trends僅用於圖像,我不會嘗試將正則表達式複雜化,並假設它總是有圖像

    location /trends { 
        alias /var/storage/trends; 
        include /etc/nginx/image_caching.conf; 
    } 
    

    併爲您的示例配置,你應該還沒有添加/trendsroot /var/storage/trends;,因爲它的位置已經使用,所以我覺得它會顯示404,原因是其在尋找/var/storage/trends/trends/123.jpg

    +0

    Thomas將'rewrite'與'root'組合起來,不需要修復 - 它和'alias'的解決方案具有相同的效果,但是他說它不工作,所以必須有一些東西在周圍的配置,優先於這個「位置」 –

    +0

    謝謝,所以我必須包括每個匹配JPG文件的位置conf,我不能有另一個規則匹配所有靜態文件(JPG,CSS,JS ...)做緩存的東西,而不是? –

    +0

    關於編輯的問題config1,將第二個位置移動到第一個位置,看看是否有效,或者'trends'只用於圖像,然後只是將2個位置合併爲1 –

    0

    Nginx的檢查定義爲它們出現在配置文件中,並與第一個匹配的表達式使用位置的順序正則表達式的位置。

    因此,你應該之前定義爲正則表達式

    相關問題