location的匹配規則
-
= 表示精確匹配。只有請求的url路徑與后面的字符串完全相等時,才會命中。
-
^~ 表示如果該符號后面的字符是最佳匹配,采用該規則,不再進行后續的查找。
-
~ 表示該規則是使用正則定義的,區分大小寫。
-
~* 表示該規則是使用正則定義的,不區分大小寫。
注意的是,nginx的匹配優先順序按照上面的順序進行優先匹配,而且注意的是一旦某一個匹配命中直接退出,不再進行往下的匹配
剩下的普通匹配會按照最長匹配長度優先級來匹配,就是誰匹配的越多就用誰。
server?{ ????server_name?website.com; ????location?/document?{ ????????return?701; ????} ????location?~*?^/docume.*$?{ ????????return?702; ????} ????location?~*?^/document$?{ ????????return?703; ????} } curl?-I??website.com:8080/document?702 #?匹配702?因為正則的優先級更高,而且正則是一旦匹配到就直接退出?所以不會再匹配703
server?{ ????server_name?website.com; ????location?~*?^/docume.*$?{ ????????return?701; ????} ????location?^~?/doc?{ ????????return?702; ????} ????location?~*?^/document$?{ ????????return?703; ????} } curl?http://website.com/document HTTP/1.1?702 #?匹配702?因為?^~精確匹配的優先級比正則高?也是匹配到之后支持退出
server?{ ????server_name?website.com; ????location?/doc?{ ????????return?702; ????} ????location?/docu?{ ????????return?701; ????} } #?701?前綴匹配匹配是按照最長匹配,跟順序無關
history模式、跨域、緩存、反向代理
#?html設置history模式 location?/?{ ????index?index.html?index.htm; ????proxy_set_header?Host?$host; ????#?history模式最重要就是這里 ????try_files?$uri?$uri/?/index.html; ????#?index.html文件不可以設置強緩存?設置協商緩存即可 ????add_header?Cache-Control?'no-cache,?must-revalidate,?proxy-revalidate,?max-age=0'; } #?接口反向代理 location?^~?/api/?{ ????#?跨域處理?設置頭部域名 ????add_header?Access-Control-Allow-Origin?*; ????#?跨域處理?設置頭部方法 ????add_header?Access-Control-Allow-Methods?'GET,POST,DELETE,OPTIONS,HEAD'; ????#?改寫路徑 ????rewrite?^/api/(.*)$?/$1?break; ????#?反向代理 ????proxy_pass?http://static_env; ????proxy_set_header?Host?$http_host; } location?~*?.(?:css(.map)?|js(.map)?|gif|svg|jfif|ico|cur|heic|webp|tiff?|mp3|m4a|aac|ogg|midi?|wav|mp4|mov|webm|mpe?g|avi|ogv|flv|wmv)$?{ ????#?靜態資源設置七天強緩存 ????expires?7d; ????access_log?off; }
以目錄去區分多個history單文件
因為不可能每一個項目開啟一個域名,僅僅指向通過增加路徑來劃分多個網站,比如:
-
www.taobao.com/tmall/login訪問天貓的登錄頁面
-
www.taobao.com/alipay/login訪問支付寶的登錄頁面
server?{ ????listen?80; ????server_name?taobao.com; ????index?index.html?index.htm; ????#?通過正則來匹配捕獲?[tmall|alipay]中間的這個路徑 ????location?~?^/([^/]+)/(.*)$?{ ????????try_files?$uri?$uri/?/$1/dist/index.html?=404; ????} }
負載均衡
基于upstream做負載均衡,中間會涉及一些相關的策略比如ip_hash、weight
upstream?backserver{? ????#?哈希算法,自動定位到該服務器?保證唯一ip定位到同一部機器?用于解決session登錄態的問題 ????ip_hash;? ????server?127.0.0.1:9090?down;?(down?表示單前的server暫時不參與負載)? ????server?127.0.0.1:8080?weight=2;?(weight?默認為1.weight越大,負載的權重就越大)? ????server?127.0.0.1:6060;? ????server?127.0.0.1:7070?backup;?(其它所有的非backup機器down或者忙的時候,請求backup機器)? }
灰度部署
如何根據headers頭部來進行灰度,下面的例子是用cookie來設置
如何獲取頭部值在nginx中可以通過$http_xxx來獲取變量
upstream?stable?{ ????server?xxx?max_fails=1?fail_timeout=60; ????server?xxx?max_fails=1?fail_timeout=60; ?} upstream?canara?{ ???server?xxx?max_fails=1?fail_timeout=60; } server?{ ????listen?80; ????server_name??xxx; ????#?設置默認 ????set?$group?"stable"; ????#?根據cookie頭部設置接入的服務 ????if?($http_cookie?~*?"tts_version_id=canara"){ ????????set?$group?canara; ????} ????if?($http_cookie?~*?"tts_version_id=stable"){ ????????set?$group?stable; ????} ????location?/?{ ????????proxy_pass?http://$group; ????????proxy_set_header???Host?????????????$host; ????????proxy_set_header???X-Real-IP????????$remote_addr; ????????proxy_set_header???X-Forwarded-For?$proxy_add_x_forwarded_for; ????????index??index.html?index.htm; ????} }
優雅降級
常用于ssr的node服務掛了返回500錯誤碼然后降級到csr的cos桶或者nginx中
優雅降級主要用error_page參數來進行降級指向備用地址。
upstream?ssr?{ ????server?xxx?max_fails=1?fail_timeout=60; ????server?xxx?max_fails=1?fail_timeout=60; ?} upstream?csr?{ ????server?xxx?max_fails=1?fail_timeout=60; ????server?xxx?max_fails=1?fail_timeout=60; } location?^~?/ssr/?{ ????proxy_pass?http://ssr; ????#?開啟自定義錯誤捕獲?如果這里不設置為on的話?會走向nginx處理的默認錯誤頁面 ????proxy_intercept_errors?on; ????#?捕獲500系列錯誤?如果500錯誤的話降級為下面的csr渲染 ????error_page?500?501?502?503?504?=?@csr_location ????#?error_page?500?501?502?503?504?=?200?@csr_location ????#?注意這上面的區別?等號前面沒有200?表示?最終返回的狀態碼已?@csr_location為準?加了200的話表示不管@csr_location返回啥都返回200狀態碼 } location?@csr_location?{ ????#?這時候地址還是帶著/ssr/的要去除 ????rewrite?^/ssr/(.*)$?/$1?break; ????proxy_pass?http://csr; ????rewrite_log?on; }
webp根據瀏覽器自動降級為png
這套方案不像常見的由nginx把png轉為webp的方案,而是先經由圖床系統(node服務)上傳兩份圖片:
-
一份是原圖png
-
一份是png壓縮為webp的圖片(使用的是imagemin-webp)
接著,使用nginx檢測請求頭中是否支持webp格式,若支持則返回webp圖片,否則返回原圖。在這過程中還進行了錯誤攔截,以便在COS桶中缺失WebP圖像且瀏覽器支持WebP的情況下,能夠降級為PNG格式
http?{ ??include???????/etc/nginx/mime.types; ??default_type??application/octet-stream; ??#?設置日志格式 ??log_format??main??'$remote_addr?-?$remote_user?[$time_local]?"$request"?' ??'$status?$body_bytes_sent?"$http_referer"?' ??'"$http_user_agent"?"$http_x_forwarded_for"' ??'"$proxy_host"?"$upstream_addr"'; ??access_log??/var/log/nginx/access.log??main; ??sendfile????????on; ??keepalive_timeout??65; ??#?開啟gzip ??gzip?on; ??gzip_vary?on; ??gzip_proxied?any; ??gzip_comp_level?6; ??gzip_types?text/plain?text/css?text/xml?application/json?application/javascript?application/rss+xml?application/atom+xml?image/svg+xml; ??#?負載均衡?這里可以是多個cos桶地址即可 ??upstream?static_env?{ ????server?xxx; ????server?xxx; ??} ??#?map?設置變量映射?第一個變量指的是要通過映射的key值?Accpet?第二個值的是變量別名 ??map?$http_accept?$webp_suffix?{ ????#?默認為?空字符串 ????default???""; ????#?正則匹配如果Accep含有webp字段?設置為.webp值 ????"~*webp"??".webp"; ??} ??server?{ ????listen?8888; ????absolute_redirect?off;????#取消絕對路徑的重定向 ????#網站主頁路徑。此路徑僅供參考,具體請您按照實際目錄操作。 ????root?/usr/share/nginx/html; ????location?/?{ ??????index?index.html?index.htm; ??????proxy_set_header?Host?$host; ??????try_files?$uri?$uri/?/index.html; ??????add_header?Cache-Control?'no-cache,?max-age=0'; ????} ????#?favicon.ico ????location?=?/favicon.ico?{ ??????log_not_found?off; ??????access_log?off; ????} ????#?robots.txt ????location?=?/robots.txt?{ ??????log_not_found?off; ??????access_log?off; ????} ????#? ????location?~*?.(png|jpe?g)$?{ ??????#?Pass?WebP?support?header?to?backend ??????#?如果header頭部中支持webp ??????if?($webp_suffix?~*?webp)?{ ????????#?先嘗試找是否有webp格式圖片 ????????rewrite?^/(.*).(png|jpe?g)$?/$1.webp?break; ????????#?找不到的話?這里捕獲404錯誤?返回原始錯誤?注意這里的=號?代表最終返回的是@static_img的狀態嗎 ????????error_page?404?=?@static_img; ??????} ??????proxy_intercept_errors?on; ??????add_header?Vary?Accept; ??????proxy_pass?http://static_env; ??????proxy_set_header?Host?$http_host; ??????expires?7d; ??????access_log?off; ????} ????location?@static_img?{ ??????#set?$complete?$schema?$server_addr?$request_uri; ??????rewrite?^/.+$?$request_uri?break; ??????proxy_pass?http://static_env; ??????proxy_set_header?Host?$http_host; ??????expires?7d; ????} ????#?assets,?media ????location?~*?.(?:css(.map)?|js(.map)?|gif|svg|jfif|ico|cur|heic|webp|tiff?|mp3|m4a|aac|ogg|midi?|wav|mp4|mov|webm|mpe?g|avi|ogv|flv|wmv)$?{ ??????proxy_pass?http://static_env; ??????proxy_set_header?Host?$http_host; ??????expires?7d; ??????access_log?off; ????} ????error_page???500?502?503?504??/50x.html; ????location?=?/50x.html?{ ??????root???/usr/share/nginx/html; ????} ??} }
為什么要用nginx,nginx有什么特點?
nginx的特點:
-
核心特點:高并發請求的同時保持高效的服務
-
熱部署
-
低內存消耗
-
處理響應請求很快
-
具有很高的可靠性
同時,nginx也可以實現高效的反向代理、負載均衡。
前端可以用nginx做些什么?
-
搭建靜態資源服務器
-
反向代理分發后端服務(可以和nodejs搭配實現前后端分離)和跨域問題
-
根據User Agent來重定向站點
-
開發環境或測試環境切換(切換host)
-
url重寫,使用rewrie規則本地映射
-
資源內容篡改
-
獲取cookie做分流
-
資源合并
-
gzip壓縮
-
壓縮圖片
-
sourceMap調試