在日常的工作中,跟nginx打交道的時候挺多的。之前對location的匹配規則是一知半解的,為了搞明白location是如何匹配的,查了些資料總結此文。希望能給大家帶來幫助。
location [ = | ~ | ~* | ^~ ] uri
location @name
語法規則很簡單,乙個location關鍵字,後面跟著可選的修飾符,後面是要匹配的字元,花括號中是要執行的操作。
對請求的url序列化。例如,對%xx等字元進行解碼,去除url中多個相連的/,解析url中的.,…等。這一步是匹配的前置工作。
location有兩種表示形式,一種是使用字首字元,一種是使用正則。如果是正則的話,前面有或*修飾符。
具體的匹配過程如下:
首先先檢查使用字首字元定義的location,選擇最長匹配的項並記錄下來。
如果找到了精確匹配的location,也就是使用了=修飾符的location,結束查詢,使用它的配置。
然後按順序查詢使用正則定義的location,如果匹配則停止查詢,使用它定義的配置。
如果沒有匹配的正則location,則使用前面記錄的最長匹配字首字元location。
基於以上的匹配過程,我們可以得到以下兩點啟示:
使用正則定義的location在配置檔案**現的順序很重要。因為找到第乙個匹配的正則後,查詢就停止了,後面定義的正則就是再匹配也沒有機會了。
使用精確匹配可以提高查詢的速度。例如經常請求/的話,可以使用=來定義location。
接下來我們以乙個例子來具體說明一下匹配過程。
假如我們有下面的一段配置檔案:
location = /
location /
location /user/
location ^~ /images/
location ~* \.(gif|jpg|jpeg)$
請求/精準匹配a,不再往下查詢。
請求/index.html匹配b。首先查詢匹配的字首字元,找到最長匹配是配置b,接著又按照順序查詢匹配的正則。結果沒有找到,因此使用先前標記的最長匹配,即配置b。
請求/user/index.html匹配c。首先找到最長匹配c,由於後面沒有匹配的正則,所以使用最長匹配c。
請求/user/1.jpg匹配e。首先進行字首字元的查詢,找到最長匹配項c,繼續進行正則查詢,找到匹配項e。因此使用e。
請求/images/1.jpg匹配d。首先進行字首字元的查詢,找到最長匹配d。但是,特殊的是它使用了^~修飾符,不再進行接下來的正則的匹配查詢,因此使用d。這裡,如果沒有前面的修飾符,其實最終的匹配是e。大家可以想一想為什麼。
請求/documents/about.html匹配b。因為b表示任何以/開頭的url都匹配。在上面的配置中,只有b能滿足,所以匹配b。
@用來定義乙個命名location。主要用於內部重定向,不能用來處理正常的請求。其用法如下:
location /
location @custom
上例中,當嘗試訪問url找不到對應的檔案就重定向到我們自定義的命名location(此處為custom)。
值得注意的是,命名location中不能再巢狀其它的命名location。
關於url尾部的/有三點也需要說明一下。第一點與location配置有關,其他兩點無關。
location中的字元有沒有/都沒有影響。也就是說/user/和/user是一樣的。
如果url結構是的形式,尾部有沒有/都不會造成重定向。因為瀏覽器在發起請求的時候,預設加上了/。雖然很多瀏覽器在位址列裡也不會顯示/。這一點,可以訪問baidu驗證一下。
如果url的結構是some-dir/。尾部如果缺少/將導致重定向。因為根據約定,url尾部的/表示目錄,沒有/表示檔案。所以訪問/some-dir/時,伺服器會自動去該目錄下找對應的預設檔案。如果訪問/some-dir的話,伺服器會先去找some-dir檔案,找不到的話會將some-dir當成目錄,重定向到/some-dir/,去該目錄下找預設檔案。可以去測試一下你的**是不是這樣的。
location的配置有兩種形式,字首字元和正則。查詢匹配的時候,先查詢字首字元,選擇最長匹配項,再查詢正則。正則的優先順序高於字首字元。
正則的查詢是按照在配置檔案中的順序進行的。因此正則的順序很重要,建議越精細的放的越靠前。
使用=精準匹配可以加快查詢的順序,如果根網域名稱經常被訪問的話建議使用=。
一文弄懂 C vector
c 標準模板庫的核心包括以下三個元件 元件描述 容器 containers 容器是用來管理某一類物件的集合。c 提供了各種不同型別的容器,比如 deque list vector map 等。演算法 algorithms 演算法作用於容器。它們提供了執行各種操作的方式,包括對容器內容執行初始化 排序...
一文弄懂Hbase基本架構
7 hbase的容錯性 注 一張hbase表在剛剛建立的時候,預設只有乙個region。所以多有關於這張表的請求都被路由到同乙個region server,不管集群中有多少region server。這也就是為什麼hbase表在剛剛建立的階段不能充分利用整個集群的吞吐量的原因。如果想開始就用到集群的...
一文讀懂Nginx
問 nginx的負載均衡演算法有什麼?預設是什麼演算法?答 1 輪詢 按請求的時間輪詢查空閒的後端伺服器 2 指定輪詢機率 機率的原因是後端伺服器的效能不均勻,好的多分點,差的少分點 3 固定ip繫結固定伺服器 預設是加權輪詢,就是優先訪問權重高的伺服器 問 nginx是單執行緒的嗎?答 是單執行緒...