文章原創於公眾號:程序猿周先森。本平台不定時更新,喜歡我的文章,歡迎關注我的微信公眾號。
之前已經講過Nginx的基本配置,本篇文章主要對Nginx中Location指令的作用進行介紹。本篇文章主要對Nginx的Location配置原則進行詳細的講述。Location是根據用戶請求的URI來進行不同的定位,定位到不同的處理方式上,匹配成功即進行相關的操作。首先需要先介紹一下Nginx的echo模塊,它可以配置的Location標簽是否正確,是否達到配置的目的。
安裝echo模塊
echo模塊可以在Nginx中用來輸出一些信息,是在調試排錯過程中一個比較好的工具。安裝此模塊后可以在Nginx用echo命令輸出字符到用戶的瀏覽器中,可用於檢測Nginx的配置的正確性。
下載Nginx-echo
cd /usr/local/nginx-1.12.2/
wget https://github.com/openresty/echo-nginx-module/archive/v0.60.tar.gz
解壓文件
tar zxvf v0.60.tar.gz
查看已安裝的模塊
nginx -V
進入Nginx目錄下配置
cd /usr/local/nginx-1.12.2/
./configure --add-module=/usr/local/nginx-1.12.2/echo-nginx-module-0.61 --add-module=/usr/local/nginx-1.12.2/ngx_image_thumb-master
編譯安裝,如果是升級可以使用make upgrade
make && make install
Nginx實際處理請求的模塊是ngxhttpcore_module模塊, 在處理請求時,變量可以通過訪問日志記錄下來,也可以用於echo 模塊進行輸出。我們可以簡單看個例子:
輸出請求參數
請求結果:
[root@VM_0_2_centos ~]# curl www.niyueling.cn/index.html?author=niyueling --header "content-type:text/html;" -H "content-length:200"
query_string: from=jdilong
request_method: GET
content_type: text/html;
content_length: 200
fastcgi_script_name: /index.php
request_uri: /index.php?from=jdilong
document_uri: /index.php
document_root: /application/nginx1.8.1/html
server_protocol: HTTP/1.1
https:
nginx_version: 1.8.1
remote_addr: 192.168.229.196
remote_port: 46786
server_addr: 192.168.229.196
server_port: 80
server_name: www.xyz.com
uri: /index.php
可以看到我們可以通過echo模塊將我們請求中的一系列參數提取打印出來。
echo_sleep定時輸出
location /echo_with_sleep/ {
echo hello;
echo_flush;
echo_sleep 3;
echo world;
}
可以通過echo_sleep設置延遲輸出,單位為秒。
異步訪問其他url
location / {
echo_reset_timer;
echo_location_async /sub1/;
echo_location_async /sub2/;
echo "took $echo_timer_elapsed sec for total.";
}
location /sub1/ {
echo_sleep 2;
echo hello;
}
location /sub2/ {
echo_sleep 1;
echo world;
}
echo_location_async可以異步訪問其他地址,不影響當前函數執行。上述執行結果$echo_timer_elapsed最終輸出值為0。
使用echo有一點需要注意的是,如果echo后邊有配置return 或者配置 proxy_pass,則echo的輸出會被覆蓋,即瀏覽器無法看到echo的內容。
Location配置
Location的語法:
location [=||*|^~] patt { }
Location類型:
location = patt {} [精准匹配]
location patt {} [普通匹配]
location ~ patt {} [正則匹配]
中括號中為修飾符,可以不寫任何參數。此時為一般匹配。
Nginx匹配類型的優先級:
Nginx配置虛擬服務器
server {
listen address[:PORT]|PORT;
server_name SERVER_NAME;
root DOCUMENT_ROOT;
}
通過listen可以對端口進行監聽,有多種設置方案:
listen 192.168.0.100:8000; 監聽192.168.0.100的8000端口
listen 192.168.0.100; 監聽192.168.0.100的80端口
listen 8000; 監聽本地8000端口
listen *:8000; 監聽本地8000端口
listen localhost:8000; 監聽127.0.0.1的80端口
listen [::]:8000; 監聽本地的ipv6的8000端口
listen [::1]; 監聽本地的ipv6地址的80端口
通過server_name設置虛擬服務器名稱,簡單一點來說就是我們在瀏覽器中訪問的域名,如果域名需要設置多個則通過空格隔開,支持*通配任意長度的任意字符。簡單舉個例子:
server_name niyueling.cn www.niyueling.cn
Location配置
Location語法規則:
location [=||*|^~] patt { }
Location命中過程
- 先進行精准匹配,如果命中立即返回結果並結束解析的過程;
- 精准匹配未命中判斷普通匹配,如果命中多個會記錄下"最長的"命中結果,但不會結束解析;
- 繼續判斷正則匹配,按照正則匹配設置的規則正則表達式進行匹配,如果有多個正則匹配由上到下進行匹配,一旦匹配成功一個會立即返回結果並結束解析.
匹配模式及優先級順序:
優先級排序自頂向下,優先級逐步降低。
- location = /uri =開頭表示精確匹配,只有完全匹配上才能生效。
- location ^~ /uri ^~ 開頭對URL路徑進行前綴匹配,並且在正則之前。
- location ~ pattern ~開頭表示區分大小寫的正則匹配。
- location ~* pattern ~*開頭表示不區分大小寫的正則匹配。
- location /uri 不帶任何修飾符,也表示前綴匹配,但是在正則匹配之后。
- location / 通用匹配,任何未匹配到其它location的請求都會匹配到,相當於switch中的default。
簡單舉個例子:
server {
listen 80;
server_name localhost;
location =/text.html
root /var/www/html;
index text.html;
}
location / {
root html;
index default.html;
}
location ~ image {
root /var/www/image;
index index.html;
}
}
第一個location對應精准匹配,瀏覽器輸入127.0.0.1/text.html,定位到服務器/var/www/html/text.html文件。第二個location對應普通匹配,瀏覽器輸入127.0.0.1,定位到服務器/usr/local/nginx/html/default.html文件。第三個location對應正則匹配,瀏覽器輸入127.0.0.1/image,定位到服務器/var/www/html/text.html文件。
注意:
進行前綴匹配時,會先一直找到最長的前綴匹配,然后看該前綴匹配有沒有前置的^~ 修飾符,如果沒有^~ 修飾符就接着去查找正則匹配,查找到匹配正則匹配后執行該location。如果最長前綴匹配有^~修飾符則命中該location,不回去匹配其他的正則匹配location;例子如下:
請求 http://localhost/static/files/test.jpg 命中規則C,如果規則B有 ^~修飾符,則會命中規則B:
location ^~ /static/ {
echo "規則A";
}location /static/files {
echo "規則B";
}location ~ .(gif|jpg|png|js|css)$ {
echo "規則C
}
歡迎關注我的個人公眾號:程序猿周先森。