前端 Nginx 知识分享

58 阅读3分钟

基本

  • 本地路径 /usr/local/etc/nginx
  • nginx 命令
    • nginx 启动
    • nginx -t 测试配置文件
    • nginx -s (stop, quit, reopen, reload)
  • cat /dev/null > /data/logs/k12.log 删除日志文件
  • 指定文件路径有 root/alias 方式
    • root(推荐)访问时,实际路径是带着匹配到的虚拟路径
      • 规则/web {root /data/html/}访问路径a.cn/web实际访问地址/data/html/web
      • 可以直接配置在server下,直接改变下面所有location的路径
    • alias是别名,所以不带虚拟路径的;
      • :文件路径需要/结尾
      • 规则/web/ {alias /data/html/}访问路径xxx/weba实际访问地址/data/html/a
    • 注意: 建议在server下直接配置root /data/web;整个nginx的默认root地址
  • 关于 403 forbiddennginx.conf开始处加user root owner;
  • nginx.conf 的目录结构
    • main nginx的全局配置,对全局生效
    • events 配置影响nginx服务器或与用户的网络连接
    • http 可以嵌套多个server,配置代理,缓存,日志定义等绝大多数功能和第三方模块的配置
      • 在这配置的 log 是包含全部的
      • upstream 配置后端服务器具体地址,负载均衡配置不可或缺的部分
      • server 配置虚拟主机的相关参数
        • location 配置请求的路由,以及各种页面的处理情况
          • log 每个location里可以单独配置
    • :所以访问都会记录在 access.log 中
  • gzip压缩是可以单独配置在某个server
# 开启gzip 压缩
gzip on;
# 读取已经压缩的为 .gz 的文件
gzip_static on;
# 设置gzip所需的http协议最低版本 (HTTP/1.1, HTTP/1.0)
gzip_http_version 1.0;
# 设置压缩级别,压缩级别越高压缩时间越长  (1-9)
gzip_comp_level 2;
# 设置压缩的最小字节数, 页面Content-Length获取
gzip_min_length 1k;
# 禁止ie
gzip_disable "MSIE [1-6]\.";
# 设置压缩文件的类型  (text/html)
gzip_types text/plain text/javascript application/javascript application/x-javascript application/xml text/css image/jpeg image/gif image/png;
# 
gzip_buffers 4 16k;
  • add_header name value [always]命令可添加请求头
  • 禁止favicon.ico日志
location = /favicon.ico {
    log_not_found off;
    access_log off;
}
  • 可以使用try_files进行文件查找内部重定向
    • 例:try_files $uri $uri/ /index.php?$query_string;先去找/root/abc文件,未找到再去找/root/abc/目录,最后进行内容 URL 查找
location ^~ /test-tj {
		# 注:root 目录下放散文件,alias 目录下直接放的 dist 文件夹;
    # root /data/web;
    alias /data/web/test-tj/dist/;
    index index.html index.htm;
    try_files $uri $uri/ /test-tj/index.html;
    
    # 会对该目录下所有内容生效
    add_header Cache-Control 'no-cache';
  }
  • 内置变量 链接
  • client_max_body_size设置可传输的 body 体大小(在外侧)

匹配规则

  • 语法格式[=|~|~*|^~|@] pattern {...}
    • = 表示精确匹配。只有URL路径与后面的字符串完全相等时才会命中(优先级最高);非正则。
      • :该匹配会忽略 /a/?a=1&b=2 请求参数
    • ^~ 前缀匹配。匹配中了就不再进行后续的检测(第二优先)非正则
    • ~ 表示该规则是使用正则定义的_区分大小写;后面跟的要是 正则 公式_
    • ~* 表示该规则是使用正则定义的_不区分大小写;后面跟的要是 正则 公式_
    • @用于表示内部跳转
    • 什么都不写的是普通匹配location /abc {...}
  • 注: 在配置文件书写的顺序也会影响结果

404 页面配置

error_page 404 /404.html;
location = /404.html {
	root /data/web;
}

代理配置

  • proxy_set_header 详解 link
  • proxy_intercept_errors: on; 代理的 404 监听配置
server {
    listen 80;
    server_name cj.test.com;
    
    location / {
        root   /Users/chisecj/Documents/projectCode;
        index  index.html index.php;
    }

    location ^~ /api/ {
        # 路径重写
        rewrite ^/api/(.*)$ /$1 break; // 重写路径,去除/api/目录
        proxy_pass http://127.0.0.1:8085;
        
        # 请求host传给后端 如果有问题可以去掉这个
        proxy_set_header Host $http_host; // $host 是只有ip,$http_host 是ip+port,或者 $proxy_host
        # 请求协议传给后端
        proxy_set_header X-Scheme $scheme;
        # 记录代理路径(包含真实ip) 传给后端(主要的)
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        # 最后的访问ip(可能是真实,可能是代理) 传给后端
        #proxy_set_header X-Real-IP $remote_addr;
        # ip(可能是真实,可能是代理) 传给后端(不用)
        #proxy_set_header Remote_Addr $remote_addr;
    }
    
    location ^~ /proxy/ {
        proxy_pass http://localhost:8000/; // 这样写可以自动去除虚拟目录,注意这里结尾的/
    }
}

跨域的头信息

  • 可以添加在http、server、location
  • 如果报错说Access-Control-Allow-Origin必须唯一,估计是不同的中间件上都配置了跨域头导致的
  • Access-Control-Allow-Headers(发送)
  • Access-Control-Expose-Headers(使用)只需配置自定义了,公共的不用配置
  • 如果请求没有命中任何路由,并且没有配置默认返回状态;浏览器还是回提示未配置跨域头
  • 可配置在 nginx 或 node 等服务里
    • :在 nginx 上时,如果没有命中服务并且没有配置默认的 2xx 返回,还是会提示跨越问题
    • :在 node 上,如果使用 .all() 全局添加 header 那么即使没命中也不会在提示跨域问题
# corsHost cors允许访问的域名 不能放在 server 里
map $http_origin $cors_origin {
    default 0;
    "~https://qsmxtop.com" https://qsmxtop.com;
    "~https://random.mtcop.com" https://random.mtcop.com;
}

# 添加请求头
# 添加 always 即使非 200 也是强制添加头信息,解决上面 注1
add_header 'Access-Control-Allow-Origin' $cors_origin always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS';
add_header 'Access-Control-Allow-Headers' '*';
add_header 'Access-Control-Allow-Credentials' 'true';

# 不一定要加,解决非简单请求的预请求问题(方式为 PUT、DELETE;或类型为 applicatioon/json 及有自定义头)
# 其实就是让预期在中间件中直接返回,不进入实际服务中;如:tomcat nodejs
if ($request_method = 'OPTIONS') {
    add_header 'Access-Control-Allow-Origin' $cors_origin;
    # 本次 options 有效时间,浏览器关了缓冲会失效
    add_header 'Access-Control-Max-Age' 1728000;
    add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE';
    add_header 'Access-Control-Allow-Headers' '*';
    # add_header 'Access-Control-Allow-Credentials' 'true';
    # add_header 'Content-Type' 'text/plain charset=UTF-8';
    add_header 'Content-Length' 0;
    # 这里添加返回,请求就不会进入实际的服务中;204 表示空请求
    return 204;
}

负载均衡

  • 当服务器有限,而请求服务的客户端很多时。就需要一个工具或者策略来帮助我们将请求合理的分配到每个服务器上,以达到资料的充分利用;
    • 轮询策略 (默认方式)
      • 最小连接数策略least_conn
      • 最快响应时间策略fair
      • 客户端ip绑定ip_hash;可防止session登录问题
http {
    upstream backend {
        # 这里可以配置上面几种方式,默认:轮询
        ip_hash;
        # server 127.0.0.1:3000 weight=number / down / backup; 配置权重/不参与/备份
        server 127.0.0.1:3000 down; // 改节点不参与负载
        server 127.0.0.1:3001;
        server 127.0.0.1:3002;
        server 127.0.0.1:3002 backup; // 其他非 backup 的节点,忙时访问该节点
    }

    server {
        listen      9000;
        server_name localhost;
        
        location / {
            proxy_set_header Host $http_host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Scheme $scheme;
            
            proxy_pass backend; 
        }
    }
}

缓存设置

  • cache-control 强缓存
    • no-cache 缓存但重新验证。每次发送请求到服务器验证,按照响应304/200判断使用
    • no-store 完全不缓存
    • max-age 相对过期时间(
    • must-revalidate 缓存过期后(配置 max-age),必须再次校验。过期之前不校验
    • public/private 私有和公共缓存
  • Etag/Last-Modified 缓存验证(协商缓存)
    • Etag 强校验器
    • Last-Modified 弱校验器
  • expires 按绝对时间进行缓存。如expires -1/1d/h/m/y
  • proxy_cache_path link link
    • 通过代理缓存,更高效的实现缓存。与浏览器缓存不同,使用了代理缓存,即使是不同的浏览器,也可以快速的获取内容
location /xxx {
  # 相当于设置了 cache-control: max-age=1年
  expires 1y;
  # 设置响应头信息,add_header 优先级高于 expires
  add_header Cache-Control xxxx;
}

https 简单配置

# http 跳 https
server {
    listen 80;
    server_name xxx;
    # 将所有http请求通过rewrite重定向到https。
    rewrite ^(.*)$ https://$host$1 permanent;
}

server {
    listen 443 ssl;
    server_name localhost;
    
    # 证书文件
    ssl_certificate     example.com.crt;
    # 私钥文件
    ssl_certificate_key example.com.key;
    # 配置共享会话缓存大小 (该配置可放在 http 下作为共享配置)
    ssl_session_cache shared:SSL:5m;
    # 配置会话超时时间 (该配置可放在 http 下作为共享配置)
    ssl_session_timeout 5m;
    ssl_prefer_server_ciphers on;
    # 限制请求协议
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    # 定义算法 ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
    ssl_ciphers HIGH:!aNULL:!MD5;
}