Nginx location的使用

Nginx是一款自由的、開源的、高性能的HTTP服務器和反向代理服務器,此文主要是記錄一下在Nginx配置時,location應該如何配置。html

http區塊

Nginx的HTTP配置主要包括三個區塊,結構以下:nginx

http { //這個是協議級別
  include mime.types;
  default_type application/octet-stream;
  keepalive_timeout 65;
  gzip on;
    server { //這個是服務器級別
      listen 80;
      server_name localhost;
        location / { //這個是請求級別
          root html;
          index index.html index.htm;
        }
      }
}

location區塊

location是Nginx服務器很是核心的配置,用於匹配指定的uri(請求uri不包含查詢字符串,如http://localhost:8080/test?id=10,請求uri是/test)。通常在修改Nginx配置時,大部分也是圍繞着location這個配置進行修改。正則表達式

不部分狀況下實際上是不須要很複雜的配置的,作個動靜分離已經能知足絕大多數單體服務的;而在分佈式環境下,某個server中一般須要配置不少location,來將請求分發到不一樣的微服務下,此時你必須很是熟悉location 的配置和匹配規則,不然真是無從下手。express

下面來看一下一個簡單的location配置:服務器

location / {
     root   home/;
     index  index.html;
}

基本語法

location [ = | ~ | ~* | ^~ | @] uri {...}app

意思是能夠用 = ~ ~ *或 ^~ @ 符號爲前綴,固然也能夠沒有前綴(由於 [A] 是表示可選的 A ; A|B 表示 A 和 B 選一個,上面的樣例就屬於沒有符號前綴的例子),緊接着是 uri ,再接着是{…} 指令塊,整個意思是對於知足這樣條件的 uri 適用指令塊 {…} 的指令。分佈式

匹配模式

全部的模式能夠分爲兩種,匹配順序也是基於這兩種模式來進行處理的:微服務

  • 普通字符串(literal strings) ,是以無前綴、 = ^~ 三種模式的 uri;
  • 正則表達式(regular expression),是以 ~ ~* 前綴兩種模式的uri;

匹配順序

  1. 普通字符 = 精確匹配。若是發現精確匹配,nginx中止搜索其餘匹配
  2. 其餘普通字符匹配,先匹配全部普通字符串,將最精確(命中長度)的匹配暫時存儲;
  3. 若是第2步中有 ^~ 命中的,則跳過第4步,直接到第5步;
  4. 按照配置文件中的聲明順序進行正則表達式匹配,只要匹配到一條正則表達式,則中止匹配,取正則表達式爲匹配結果;
  5. 若是全部正則表達式都匹配不上,則取以前普通字符串中存儲的結果;
  6. 若是普通字符串和正則表達式都匹配不上,則報404 NOT FOUND。

總結一下就是: 普通命中順序無所謂,由於是按命中精準度來肯定的 ;正則命中區分順序,由於是從前日後命中的,命中一個後就不會繼續匹配下一個正則。性能

example

  1. 無前綴表示:必須以指定模式開始:代理

    server {
      listen 80;
      server_name localhost;
      location /abc {
        ……
      }
    }
    那麼,以下是對的:
    http://baidu.com/abc
    http://baidu.com/abc?p1
    http://baidu.com/abc/
    http://baidu.com/abcde
  2. ^~ 表示:相似於無前綴修飾符的行爲,區別是,若是此模式匹配,是會中止搜索正則匹配的,可是會繼續搜索普通模式。
  3. =表示:必須與指定的uri精確匹配

    server {
      listen 80;
      server_name localhost;
      location = /abc {
        ……
      }
    }
    那麼,以下是對的:
    http://baidu.com/abc
    http://baidu.com/abc?p1
    以下是錯的:
    http://baidu.com/abc/
    http://baidu.com/abcde
  4. ~ 表示:指定的正則表達式要區分大小寫

    server {
      listen 80;
      server_name localhost;
               location    ~   ^/abc$ {
        ……
      }
    }
    那麼,以下是對的:
    http://baidu.com/abc
    http://baidu.com/abc?p1=11&p2=22
    以下是錯的:
    http://baidu.com/ABC
    http://baidu.com/abc/
    http://baidu.com/abcde
  5. ~* 表示:指定的正則表達式不區分大小寫

    server {
      listen 80;
      server_name localhost;
            location ~* ^/abc$ {
        ……
      }
    }
    那麼,以下是對的:
    http://baidu.com/abc
    http://baidu..com/ABC
    http://baidu..com/abc?p1=11&p2=22
    以下是錯的:
    http://baidu..com/abc/
    http://baidu..com/abcde
  6. @表示:這些location區段客戶端不能訪問,只能夠由內部產生的請求來訪問,如try_files或error_page等,以error_page爲例:

        server {
      listen 80;
      server_name localhost;
      error_page 404 @fallback
          
              location /abc {
                 //檢測文件4.html和5.html,若是存在正常顯示,不存在就去查找@qwe值  
                try_files    /4.html        /5.html      @fallback;      
               }   
              location @fallback  {
                 proxy_pass http://www.baidu.com;    --跳轉到百度頁面
          }
      }

    當uri匹配上/abc時,會按順序檢測文件的存在性,而且返回找到的第一個文件,最後一項就是跳轉到百度,這種寫法能夠替代本來經常使用的rewrite,貌似能夠提升解析效率;

root&alias區別

Nginx指定文件路徑有兩種方式root和alias,兩種指令有不一樣的使用方法和做用域,root能夠配置在http、server、location、if區塊中,可是alias只能配置在location區塊中。

root與alias主要區別在於Nginx如何解釋location後面的uri,這會使二者分別以不一樣的方式將請求映射到服務器文件上。

  • root的處理結果是:root路徑+location路徑

    location ^~ /appImg/{
        root /home/nginx;
    }

    這個location至關於訪問服務器上的文件路徑: /home/nginx/appImg/abc.jpg

  • alias的處理結果是:使用alias路徑替換location路徑

    location ^~ /appImg/{
        alias /home/nginx/;
    }

    這個location至關於訪問服務器上的文件目錄:/home/nginx/abc.jpg(即alias不會使用location後面配置的路徑),並且若是alias 指定的是目錄,後面必定要加上 /,不然會找不到文件。

相關文章
相關標籤/搜索