Nginx_Rewrite
- 一、介紹
- Rewrite根據nginx提供的全局變量或自己設置的變量,結合正則表達式和標志位實現url重寫和者重定向。
- Rewrite和location類似,都可以實現跳轉,區別是rewrite是在同一域名內更改url,而location是對同類型匹配路徑做控制訪問,或者proxy_pass代理到其他服務器。
- Rewrite和location執行順序:
- 執行server下的rewrite
- 執行location匹配
- 執行location下的rewrite
- 二、語法和參數說明
- rewrite語法格式
rewrite <regex> <replacement> <flag>; 關鍵字 正則表達式 代替的內容 重寫類型 Rewrite:一般都是rewrite Regex:可以是字符串或者正則來表示想要匹配的目標URL Replacement:將正則匹配的內容替換成replacement Flag:flag標示,重寫類型: - last:本條規則匹配完成后,繼續向下匹配新的location URI規則;相當於Apache里德(L)標記,表示完成rewrite,瀏覽器地址欄URL地址不變;一般寫在server和if中; - break:本條規則匹配完成后,終止匹配,不再匹配后面的規則,瀏覽器地址欄URL地址不變;一般使用在location中; - redirect:返回302臨時重定向,瀏覽器地址會顯示跳轉后的URL地址; - permanent:返回301永久重定向,瀏覽器地址欄會顯示跳轉后的URL地址;
server { # 訪問 /last.html 的時候,頁面內容重寫到 /index.html 中,並繼續后面的匹配,瀏覽器地址欄URL地址不變 rewrite /last.html /index.html last; # 訪問 /break.html 的時候,頁面內容重寫到 /index.html 中,並停止后續的匹配,瀏覽器地址欄URL地址不變; rewrite /break.html /index.html break; # 訪問 /redirect.html 的時候,頁面直接302定向到 /index.html中,瀏覽器地址URL跳為index.html rewrite /redirect.html /index.html redirect; # 訪問 /permanent.html 的時候,頁面直接301定向到 /index.html中,瀏覽器地址URL跳為index.html rewrite /permanent.html /index.html permanent; # 把 /html/*.html => /post/*.html ,301定向 rewrite ^/html/(.+?).html$ /post/$1.html permanent; # 把 /search/key => /search.html?keyword=key rewrite ^/search\/([^\/]+?)(\/|$) /search.html?keyword=$1 permanent; # 把當前域名的請求,跳轉到新域名上,域名變化但路徑不變 rewrite ^/(.*) http://www.jd.com/$1 permanent; }
- IF判斷和內置全局環境變量
if (表達式) { } #當表達式只是一個變量時,如果值為空或任何以0開頭的字符串都會當做false直接比較變量和內容時,使用=或!=~正則表達式匹配,~*不區分大小寫的匹配,!~區分大小寫的不匹配
$args :這個變量等於請求行中的參數,同$query_string $content_length : 請求頭中的Content-length字段。 $content_type : 請求頭中的Content-Type字段。 $document_root : 當前請求在root指令中指定的值。 $host : 請求主機頭字段,否則為服務器名稱。 $http_user_agent : 客戶端agent信息 $http_cookie : 客戶端cookie信息 $limit_rate : 這個變量可以限制連接速率。 $request_method : 客戶端請求的動作,通常為GET或POST。 $remote_addr : 客戶端的IP地址。 $remote_port : 客戶端的端口。 $remote_user : 已經經過Auth Basic Module驗證的用戶名。 $request_filename : 當前請求的文件路徑,由root或alias指令與URI請求生成。 $scheme : HTTP方法(如http,https)。 $server_protocol : 請求使用的協議,通常是HTTP/1.0或HTTP/1.1。 $server_addr : 服務器地址,在完成一次系統調用后可以確定這個值。 $server_name : 服務器名稱。 $server_port : 請求到達服務器的端口號。 $request_uri : 包含請求參數的原始URI,不包含主機名,如:”/foo/bar.php?arg=baz”。 $uri : 不帶請求參數的當前URI,$uri不包含主機名,如”/foo/bar.html”。 $document_uri : 與$uri相同。 例子: URL:http://localhost:81/download/stat.php?id=1585378&web_id=1585378 Server_Dir:/var/www/html $host:localhost $server_port:81 $request_uri:/download/stat.php?id=1585378&web_id=1585378 $document_uri:/download/stat.php $document_root:/var/www/html $request_filename:/var/www/html/download/stat.php # 如果文件不存在則返回400 if (!-f $request_filename) { return 400; } # 如果host是www.360buy.com,則301到www.jd.com中 if ( $host != "www.jd.com" ){ rewrite ^/(.*)$ https://www.jd.com/$1 permanent; } # 如果請求類型是POST則返回405,return不能返回301,302 if ($request_method = POST) { return 405; } # 如果參數中有 a=1 則301到指定域名 if ($args ~ a=1) { rewrite ^ http://example.com/ permanent; }
- 文件名及參數重寫 location = /index.html { # 修改默認值為 set $name test; # 如果參數中有 name=xx 則使用該值 if ($args ~* name=(\w+?)(&|$)) { set $name $1; } # permanent 301重定向 rewrite ^ /$name.html permanent; }
- 隱藏真實目錄 server { root /var/www/html; # 用 /html_test 來掩飾 html location / { # 使用break拿一旦匹配成功則忽略后續location rewrite /html_test /html break; } # 訪問真實地址直接報沒權限 location /html { return 403; } }
- 禁止指定IP訪問 location / { if ($remote_addr = 192.168.1.253) { return 403; } }
- 如果請求的文件不存在,則反向代理到localhost 。這里的break也是停止繼續rewrite if (!-f $request_filename){ break; proxy_pass http://127.0.0.1; }
- 對/images/bla_500x400.jpg文件請求,重寫到/resizer/bla.jpg?width=500&height=400地址,並會繼續嘗試匹配location。 rewrite ^/images/(.*)_(\d+)x(\d+)\.(png|jpg|gif)$ /resizer/$1.$4?width=$2&height=$3? last;
Proxy_Pass
- Proxy_pass反向代理,用的是nginx的Proxy模塊。
第一種:
location /proxy/ { proxy_pass http://127.0.0.1/; } 代理到URL:http://127.0.0.1/test.html 第二種: location /proxy/ { proxy_pass http://127.0.0.1; #少/ } 代理到URL:http://127.0.0.1/proxy/test.html 第三種: location /proxy/ { proxy_pass http://127.0.0.1/aaa/; } 代理到URL:http://127.0.0.1/aaa/test.html 第四種(相對於第三種,最后少一個 / ) location /proxy/ { proxy_pass http://127.0.0.1/aaa; } 代理到URL:http://127.0.0.1/aaatest.html
- proxy_set_header Host $host; 作用web服務器上有多個站點時,用該參數header來區分反向代理哪個域名。比如下邊的代碼舉例。
- proxy_set_header X-Forwarded-For $remote_addr; 作用是后端服務器上的程序獲取訪客真實IP,從該header頭獲取。部分程序需要該功能。
- Proxy_pass配合upstream實現負載均衡 http { include mime.types; default_type application/octet-stream; sendfile on; upstream core_tomcat { server 192.168.1.253:80 weight=5 max_fails=3 fail_timeout=30; server 192.168.1.252:80 weight=1 max_fails=3 fail_timeout=30; server 192.168.1.251:80 backup; } server { listen 80; server_name www.jd.com; location /web { proxy_pass http://core_tomcat; proxy_set_header Host $host; } } }
- Nginx負載均衡的幾種模式
- 輪詢:每個請求按時間順序逐一分配到不同的后端服務器,如果后端服務器down掉,就不在分配;
upstream core_tomcat { server 192.168.1.253:80 max_fails=3 fail_timeout=30; server 192.168.1.252:80 max_fails=3 fail_timeout=30; }
- 權重輪詢:根據后端服務器性能不通配置輪詢的權重比,權重越高訪問的比重越高;
upstream core_tomcat { server 192.168.1.253:80 weight=2 max_fails=3 fail_timeout=30; server 192.168.1.252:80 weight=8 max_fails=3 fail_timeout=30; } #假如有十個請求,八個會指向第二台服務器,兩個指向第一台;
- IP_Hash:根據請求的ip地址hash結果進行分配,第一次分配到A服務器,后面再請求默認還是分配到A服務器;可以解決Session失效重新登錄問題;
upstream core_tomcat { ip_hash; server 192.168.1.253:80 max_fails=3 fail_timeout=30; server 192.168.1.252:80 max_fails=3 fail_timeout=30; }
- Fair:按后端服務器的響應時間來分配請求,響應時間短的優先分配;
upstream core_tomcat { fair; server 192.168.1.253:80 max_fails=3 fail_timeout=30; server 192.168.1.252:80 max_fails=3 fail_timeout=30; }
- Url_hash:按訪問url的hash結果來分配請求,使每個url定向到同一個后端服務器,后端服務器為緩存時比較有效;
upstream core_tomcat { hash $request_uri; server 192.168.1.253:80 max_fails=3 fail_timeout=30; server 192.168.1.252:80 max_fails=3 fail_timeout=30; }
參考文檔:
http://www.cnblogs.com/mikeluwen/p/7116967.html
https://www.cnblogs.com/zl0372/articles/nginx.html
https://blog.csdn.net/qq_28602957/article/details/61615876
http://blog.51cto.com/liqilong2010/1837126
https://www.cnblogs.com/likwo/p/6513117.html