location的匹配规则
= 表示精确匹配。只有请求的url路径与后面的字符串完全相等时,才会命中。
^~ 表示如果该符号后面的字符是最佳匹配,采用该规则,不再进行后续的查找。
~ 表示该规则是使用正则定义的,区分大小写。
~* 表示该规则是使用正则定义的,不区分大小写。
注意的是,nginx的匹配优先顺序按照上面的顺序进行优先匹配,而且注意的是一旦某一个匹配命中直接退出,不再进行往下的匹配
剩下的普通匹配会按照最长匹配长度优先级来匹配,就是谁匹配的越多就用谁。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 server { server_name website.com; location /document { return 701 ; } location ~* ^/docume.*$ { return 702 ; } location ~* ^/document$ { return 703 ; } } curl -I website.com:8080 /document 702 server { server_name website.com; location ~* ^/docume.*$ { return 701 ; } location ^~ /doc { return 702 ; } location ~* ^/document$ { return 703 ; } } curl http://website.com/documentHTTP/1 .1 702 server { server_name website.com; location /doc { return 702 ; } location /docu { return 701 ; } }
history模式、跨域、缓存、反向代理 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 location / { index index.html index.htm; proxy_set_header Host $host; try_files $uri $uri/ /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访问支付宝的登录页面
1 2 3 4 5 6 7 8 9 server { listen 80 ; server_name taobao.com; index index.html index.htm; location ~ ^/([^\/]+)/(.*)$ { try_files $uri $uri/ /$1 /dist/index.html =404 ; } }
负载均衡(???) 基于upstream做负载均衡,中间会涉及一些相关的策略比如ip_hash、weight
1 2 3 4 5 6 7 8 upstream backserver{ 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来获取变量
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 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" ; 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参数来进行降级指向备用地址
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 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; proxy_intercept_errors on ; error_page 500 501 502 503 504 = @csr_location } location @csr_location { 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 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 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; upstream static_env { server xxx; server xxx; } map $http_accept $webp_suffix { default "" ; "~*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' ; } location = /favicon.ico { log_not_found off ; access_log off ; } location = /robots.txt { log_not_found off ; access_log off ; } location ~* \.(png|jpe?g)$ { if ($webp_suffix ~* webp) { rewrite ^/(.*)\.(png|jpe?g)$ /$1 .webp break ; 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 { rewrite ^/.+$ $request_uri break ; proxy_pass http://static_env; proxy_set_header Host $http_host; expires 7d ; } 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; } } }