WEB服務-Nginx之5-Server和Location和Include
Server
在開始處理一個http請求時,nginx會取出header頭中的Host變量,按優先級與nginx.conf中的每個server_name進行匹配,以此決定到底由哪一個server來處理這個請求。優先級匹配結果如下:
- 首先選擇所有的字符串完全匹配的server_name。(完全匹配)
- 選擇通配符在前面的server_name,如
*.oldboy.com
www.oldboy.com - 選擇通配符在后面的server_name,如
www.oldboy.*
www.oldboy.com www.oldboy.cn - 最后選擇使用正則表達式匹配的server_name
- 如果全部都沒有匹配到,那么將選擇配置
listen port default_server;
的server塊 - 如果沒有配置
listen port default_server;
的server塊,那么將選擇匹配listen端口的第一個server塊
注意:建議配置相同端口,不同域名,這樣不會出現域名訪問沖突。
創建配置文和站點文件測試
[root@web01 ~]# cat > /etc/nginx/conf.d/server.conf << EOF
server {
listen 80;
server_name linux.test.com;
location / {
root /code;
index server1.html;
}
}
server {
listen 80;
server_name *.test.com;
location / {
root /code;
index server2.html;
}
}
server {
listen 80;
server_name linux.test.*;
location / {
root /code;
index server3.html;
}
}
server {
listen 80;
server_name ~^linux\.(.*)\.com\$;
location / {
root /code;
index server4.html;
}
}
server {
listen 80 default_server;
server_name localhost;
location / {
root /code;
index server5.html;
}
}
EOF
[root@web01 ~]# echo linux.test.com > /code/server1.html
[root@web01 ~]# echo *.test.com > /code/server2.html
[root@web01 ~]# echo linux.test.* > /code/server3.html
[root@web01 ~]# echo '~^linux\.(.*)\.com$' > /code/server4.html
[root@web01 ~]# echo default_server > /code/server5.html
重載添加host解析
[root@web01 ~]# systemctl reload nginx
[root@web01 ~]# echo 10.0.0.7 linux.test.com www.test.com linux.test.cn linux.aaa.com aaa.test.aaa >> /etc/hosts
訪問測試
[root@web01 ~]# curl linux.test.com
linux.test.com
[root@web01 ~]# curl www.test.com
*.test.com
[root@web01 ~]# curl linux.aaa.com
~^linux\.(.*)\.com$
[root@web01 ~]# curl aaa.test.aaa
default_server
# 注釋掉default_server,重載再測試
[root@web01 ~]# systemctl reload nginx
[root@web01 ~]# curl aaa.test.aaa
linux.test.com
Location
Nginx
使用Location
可以控制訪問網站的路徑
官方文檔:http://nginx.org/en/docs/http/ngx_http_core_module.html#location
Location語法示例
Syntax: location [ = | ~ | ~* | ^~ ] uri { ... }
location @name { ... }
Default: —
Context: server, location
uri是用戶請求的字符串,即域名后面的web文件路徑。
Location正則匹配可以使用測試判斷語句
-f # 是否存在文件 -d # 是否存在目錄 -e # 是否存在文件或目錄 -x # 文件是否可執行
Location語法優先級順序
匹配符 | 匹配規則 | 優先級 |
---|---|---|
= | 精確匹配,並停止搜索,不再向下匹配。 | 1 |
^~ | 匹配以某個字符串開頭的查詢,並停止搜索,不再向下匹配。 | 2 |
~ | 區分大小寫的正則匹配 | 3 |
~* | 不區分大小寫的正則匹配 | 4 |
!~ | 區分大小寫不匹配的正則匹配 | 5 |
!~* | 不區分大小寫不匹配的正則匹配 | 6 |
/ | 匹配任何以指定模式開始的查詢,正則表達式與較長的字符串優先。 | 7 |
驗證配置:
server {
listen 80;
location =/ {
return 200 "location =/";
}
location ^~/ {
return 200 "location ^~/";
}
location ~/ {
return 200 "location ~/";
}
location ~*/ {
return 200 "location ~*/";
}
#location / {
# return 200 "location /"; # 和^~語法重復,先注釋下
#}
}
!~
和!~*
屬於排除法,符合匹配規則時不會匹配到,也就是輪到它了也不會執行里面的語句。
驗證測試:
從上往下依次測試,測試一次注釋掉一級,重載Nginx:systemctl reload nginx
# 優先級最高精確匹配=
[root@web01 ~]# curl 127.0.0.1
location =/
# 注釋掉=,重載Nginx
[root@web01 ~]# curl 127.0.0.1
location ^~/
# 注釋掉^~,去掉/的注釋,重載Nginx
[root@web01 ~]# curl 127.0.0.1
location ~/
# 注釋掉~,重載Nginx
[root@web01 ~]# curl 127.0.0.1
location ~*/
Location應用場景
# 通用匹配,任何請求都會匹配到
location / {
...
}
# 嚴格區分大小寫,匹配以.php結尾的都走這個location
location ~ \.php$ {
...
}
# 不區分大小寫匹配,只要用戶訪問.jpg,gif,png,js,css 都走這條location
location ~* \.png$ {
...
}
# 實現資源動靜分離
location ~ \.(php|jsp|asp) {
root /opt/dynamic;
}
location ~* \.(jpg|gif|html|txt|js|css)$ {
root /opt/static;
}
root與alias
root的處理結果是:root路徑+location路徑
alias的處理結果是:使用alias定義的路徑
- alias是目錄別名的定義,如果uri以“/”結束,alias必須要用“/”結束,否則403
location /img/ {
alias /var/www/; # 實際路徑是/var/www/
}
location ~* /img/(.+\.(gif|png|jpeg)) { # location用正則表達式則必須包含捕獲語句(也就是括號())
alias /usr/local/images/$1; # alias則必須要引用這些捕獲值
}
- root是最上層目錄的定義,文件的絕對路徑等於 root+location
location /img/ {
root /var/www; # 實際路徑是/var/www/img/
}
- proxy_pass是反向代理配置,用“/”結束不附加location配置路徑
location /test/ {
proxy_pass http://127.0.0.1:8080; # 實際將請求轉發到http://127.0.0.1:8080/test/
}
location /test/ {
proxy_pass http://127.0.0.1:8080/; # 實際將請求轉發到http://127.0.0.1:8080/
}
- 線上配置
server {
listen 80;
server_name image.oldboy.com;
location / {
root /code;
}
location ~* ^.*\.(png|jpg|gif)$ {
alias /code/images/;
}
}
Include
一台服務器配置多個網站,如果配置都寫在nginx.conf主配置文件中,會導致nginx.conf主配置文件變得非常龐大而且可讀性非常的差。那么后期的維護就變得麻煩。
假設現在希望快速的關閉一個站點,該怎么辦?
- 如果是寫在nginx.conf中,則需要手動注釋,比較麻煩
- 如果是include的方式,那么僅需修改配置文件的擴展名,即可完成注釋,Include包含的作用是為了簡化主配置文件,便於人類可讀。
inlcude /etc/nginx/online/*.conf; # 線上使用的配置
mv /etc/nginx/online/test.conf /etc/nginx/offline/ # 保留配置,不啟用(下次使用再移動到online中)
Include還可以包含其他經常重復的配置文件,比如
inlcude /etc/nginx/conf.c/*.conf; # 四層負載的配置文件
inlcude fastcgi_params; # fastcgi的配置參數,默認在/etc/nginx/下
inlcude rewrite.conf; # rewrite的配置參數
... ...
方便其他配置文件調用。