陌上寒

陌上寒个人博客

nginx前端必知必会

nginx前端必知必会

介绍

  • Nginx是异步框架的网页服务器,也可以用作反向代理、负载平衡器和HTTP缓存。该软件由伊戈尔·赛索耶夫创建并于2004年首次公开发布。2011年成立同名公司以提供支持。2019年3月11日,Nginx公司被F5 Networks以6.7亿美元收购。Nginx是免费的开源软件,根据类BSD许可证的条款发布。一大部分Web服务器使用Nginx,通常作为负载均衡器,
    《nginx前端必知必会》

特点

  • Nginx 是一款面向性能设计的 HTTP 服务器,相较于 Apache、lighttpd 具有占有内存少,稳定性高等优势。与旧版本(<=2.2)的 Apache 不同,nginx 不采用每客户机一线程的设计模型,而是充分使用异步逻辑,削减了上下文调度开销,所以并发服务能力更强。整体采用模块化设计,有丰富的模块库和第三方模块库,配置灵活。在 Linux 操作系统下,nginx 使用 epoll 事件模型,得益于此,nginx 在 Linux 操作系统下效率相当高。同时 Nginx 在 OpenBSD 或 FreeBSD 操作系统上采用类似于 epoll 的高效事件模型 kqueue。可大量平行处理。Nginx 在官方测试的结果中,能够支持五万个平行连接,而在实际的运作中,可以支持二万至四万个平行链接。

安装

  • window nginx.exe
  • 通过包管理安装
    shell
    sudo apt-get install nginx #ubuntu
    sudo yum install nginx #centos
    sudo brew install nginx #mac
  • 官网下载源码,安装依赖,编译后安装
  • docker安装 dockerhub

常用命令

  • nginx -v / -V 查看版本 / 查看版本和配置信息(依赖库的本信息)
  • nginx -t 检查配置文件语法状态
  • nginx -s quite 关闭服务(优雅关闭,等待当前已建立的连接完成后关闭服务)
  • nginx -s stop 直接停止服务
  • nginx -s reload 热重载,不停止服务的情况下重新加载配置文件,完成服务重启
  • nginx -s reopen 重新开始日志文件

常用参数

参数 含义
user 指定nginx worker进程运行用户及用户组,Windows下不用指定,默认为nobody账号。403的时候可以查看user是否有项目目录权限
worker_processes 设定工作进程数,通常设定为CPU数量或CPU数量的两倍或auto。
worker_processes 设定工作进程数,通常设定为CPU数量或CPU数量的两倍或auto。
worker_rlimit_nofile nginx 进程最大打开文件数, 通常设置65535。(受限于系统上可用的文件描述符的数量可以通过ulimit -n查看系统的最大打开文件数)
pid nginx的进程号,当我们需要停止nginx时,使用的其中一种方式就可以是通过进程号杀死进程的方式。
worker_connections 设置一个进程可以打开最大连接数,应该小于最大打开文件数。(反向代理的情况下连接数不能只考虑客户端的连接) 理论上每台Nginx服务器的最大连接数为worker_processes*worker_connections。
use 用于指定事件模型,为windows下无需指定事件模型(Nginx针对不同操作系统会使用不同的事件模型)。Nginx可支持的的worktype有以下几种select、poll、kqueue、epoll、rtsig、/dev/poll
include mime.types 文件类型,对应response header中的content-type
default_type 当文件类型未在mime.types中定义时会使用这种方式,一般默认类型设置为octet-stream,表示当文件类型未定义时浏览器认为响应的是普通的文件流,并会提示用户下载文件。
log_format name log_formate是Nginx的httplog模块指令,用于指定Ningx的日志输出格式。name为为此日志格式设置的名字,在下面的access_log指令中使用这个名字,就可以按照这个名字定义的格式进行日志输出。
access_log 设置日志路径,根据路径后跟的名字设置日志格式。
error_log 定义错误日志的存放路径。路径后面的参数为错误日志输出级别,分别有debug、info、notice、warn、error、crit六个级别,其中debug级别输出的错误日志最详细,crit级别输出的错误日志最简略
sendfile 用于开启高效文件传输模式,对于普通应用必须设置为on。如果用来进行下载等应用磁盘IO的重负载引用,可以设置为off,平衡磁盘与网络IO的处理速度,降低系统uptime(负载)。
tcp_nopush 此选项仅在使用sendfile时使用。它的作用是,防止网络拥塞,当tcp_nopush设置为on时,当有数据需要发送时,先不着急立刻发送,而是确保数据包已经装满数据才进行发送,减少网络报文段的数量,避免网络拥塞。
tcp_nodelay 此选项仅在使用sendfile时使用。它的作用同上一个选项tcp_nopush刚好相反,当有数据要发送时,立即发送,确保数据尽快发送,提高数据传输效率,适用每次只发送很少字节的业务场景。
keepalive_timeout 在HTTP请求中,当一个请求完成后会保持这个TCP连接的打开状态,若接收到来自客户端的其他请求,服务端就会利用这个未被关闭的连接,而不需要再建立一个新的连接,这就是keep-alive模式,但是保持打开状态的TCP连接同样会占用资源,当资源占用过多就会影响性能,所以这个选项就是指定每个TCP连接最多可以保持多长时间。
gzip 开启实时gzip压缩输出数据流,减少网络传输。
gzip_min_length gzip压缩起点大小,大于设置大小才进行压缩。
gzip_buffers 设置系统获取几个单位的缓存用于存储gzip的压缩结果数据流。4 16k代表申请4个单位为16k的内存作为压缩结果缓存。
gzip_http_version 设置gzip压缩针对的HTTP协议版本。
gzip_comp_level gzip压缩级别,数字越大压缩效果越好,但CPU处理时间越长。
gzip_types 指定何种类型的文件会被进行压缩。需要和mime.type的content-type中对应
gzip_vary 为响应头添加Vary: Accept-Encoding标头,该标头可以告诉前端的缓存服务器同时缓存通过gzip压缩过的资源和未压缩过的资源,这么做的目的是,当客户端使用的是不支持gizp的低版本浏览器时,缓存也可以向其返回未经gzip压缩过的资源,否则,如果缓存服务器只缓存了压缩过后的资源,那么返回压缩过后的资源会导师老版本浏览器无法解压,出现乱码。
gzip_disable 指定哪些不需要gzip压缩的浏览器
server_name 域名
listen 端口号
root 目录
proxy_pass 设置反向代理服务器

web服务器

《nginx前端必知必会》
+ 静态资源服务器
+ http

http {
    gzip  on;
    gzip_vary on;
    gzip_proxied any;
    gzip_min_length  5k;
    gzip_buffers  4 16k;
    gzip_http_version 1.1;
    gzip_comp_level 4;
    gzip_types  application/javascript text/plain application/x-javascript text/css application/xml application/json text/javascript;
    gzip_disable "MSIE [1-6]\.(?!.*SV1)";

    server {
        server_name baixiaoxu.com www.baixiaoxu.com;
        listen 80;
        root /home/baixx2/project;
        location / {
            index index.htm index.html;
        }
        # vue-router history模式
        location / {
            try_files $uri $uri/ /index.html;
        }
        # 资源设置缓存
        location ~ \.(css|js|woff2|png) {
           #expires 10d;
           add_header Cache-Control max-age=4800;
        }
    }
}  

  • https + http2 (个人网站可以使用Let’s Encrypt的https证书)
    certbot 可以自动生成证书 [certbot]: https://certbot.eff.org/
http {
    # http2 需要nginx >= 1.10.0、openssl >= 1.0.2的版本要求,可以nginx -V查看是否满足
    server {
        server_name: baixiaoxu.com www.baixiaoxu.com;
        listen 443 ssl http2;
        ssl_certificate /etc/letsencrypt/live/baixiaoxu.com/fullchain.pem; 
        # managed by Certbot
        ssl_certificate_key /etc/letsencrypt/live/baixiaoxu.com/privkey.pem; 
        # managed by Certbot
        include /etc/letsencrypt/options-ssl-nginx.conf; 
        # managed by Certbot
        ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
        # managed by Certbot
        root /home/baixx2/project;
        location / {
           http2_push /css/style.css;
           # server push , 文件路径相对root开始填写 
           index index.htm index.html;
        }
    }
}        
  • 资源匹配规则
    • = 表示精确匹配
    • ^~ 表示普通字符匹配,如果该选项匹配,只匹配该选项,不匹配别的选项,一般用来匹配目录。
    • ~ 正则匹配(区分大小写)
    • ~* 正则匹配(不区分大小写)
    • !~ 和!~* 分别为区分大小写不匹配及不区分大小写不匹配的正则
    • / 任何请求都会匹配
    • 首先匹配=, 其次匹配^~ , 其次是按文件中顺序的正则匹配,最后是交给 / 通用匹配。当有匹配成功时候,停止匹配,按当前匹配规则处理请求。
  • 反向代理(正向、反向)
http {
    upstream backend {
        server 192.168.1.110:8080;
        server 192.168.1.111:8080;
    }

    server {
        location /api/ {
            proxy_pass http://backend/; 
            # http://127.0.0.1/api/add ->http://127.0.0.1/add
        }
        location /api/ {
            proxy_pass http://backend; 
            # http://127.0.0.1/api/add ->http://127.0.0.1/api/add
        }
        location /api {
            proxy_pass http://backend/;
            # http://127.0.0.1/api/add ->http://127.0.0.1//add
        }
        location /api {
            proxy_pass http://backend; 
            # http://127.0.0.1/api/add ->http://127.0.0.1/api/add
       }
       // 透传header
       location /api {
          proxy_set_header Referer "";
          proxy_set_header X-Forwarded-For $http_x_forwarded_for;
          proxy_pass http://backend; 
       }
    }
}    
  • 负载均衡
    • 轮询
    • 最少连接数
    • weight
    • ip_hash
    • fair (第三方)
  upstream backend  {
    server 192.168.1.110:8080;
    server 192.168.1.111:8080;
  }
  upstream backend  {
    least_conn;
    server 192.168.1.110:8080;
    server 192.168.1.111:8080;
  }
  upstream backend  {
    server 192.168.1.110:8080 weight=2;
    server 192.168.1.111:8080;
  }
  upstream backend  {
    ip_hash;
    server 192.168.1.110:8080;
    server 192.168.1.111:8080;
  }
  # down 不参与服务
  # backup 备用服务
  upstream backend  {
      server 192.168.1.110:8080 down;
      server 192.168.1.111:8080 backup;
      server 192.168.1.111:8080 max_fails=1 fail_timeout=10s;  # 10s内服务不可用次数为1次后,暂停此服务,间隔10s后进行健康检查,检查通过后允许继续服务。
  }

动手之一步一步配置你的web服务器(演示)

  • 设置正确的端口和root目录指向
    server {
        server_name localhost;
        listen 80;
        root /front;
        location / {
            index index.htm index.html;
        }
    }
    # vue项目并且router使用了history模式 
    # history模式使用的路由在服务器上并没有实际的服务和文件,所以需要返回index.html
    server {
        server_name localhost;
        listen 80;
        root /front;
        location / {
          try_files $uri $uri/ /index.html;
        }
    }
  • 设置资源缓存
    server {
        server_name localhost;
        listen 80;
        root /front;
        location / {
            index index.htm index.html;
        }
        location ~ \.(css|js|woff2|png|jpg) {
            expires 10d;
            #add_header Cache-Control max-age=3600;
        }
    }
  • 发现第一次请求资源体积有点大(开启gzip压缩)
http {
    gzip on;
    gzip_vary on;
    gzip_min_length 5k;
    gzip_proxied any;
    gzip_comp_level 4;
    gzip_buffers 16 8k;
    gzip_http_version 1.1;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

    server {
        server_name localhost;
        listen 80;
        root /front;
        location / {
            index index.htm index.html;
        }
        location ~ \.(css|js|woff2|png|jpg) {
            expires 10d;
            #add_header Cache-Control max-age=3600;
        }
    }
}
  • 后端联调遇到接口跨域
http {
    gzip on;
    gzip_vary on;
    gzip_min_length 5k;
    gzip_proxied any;
    gzip_comp_level 4;
    gzip_buffers 16 8k;
    gzip_http_version 1.1;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

    server {
        server_name localhost;
        listen 80;
        root /front;
        location / {
            index index.htm index.html;
        }
        location ~ \.(css|js|woff2|png|jpg) {
            expires 10d;
            #add_header Cache-Control max-age=3600;
        }
        location /api/ {
            proxy_pass http://127.0.0.1:3000/; 
            # 后端服务地址
        }
    }

    # 如果 你是服务的提供方,那么也可以在nginx中设置请求头,允许跨域
    server {
        // 直接在nginx中设置请求头解决跨域 
        location / {
            location / {
            add_header Access-Control-Allow-Origin *;
            add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
            add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
            if ($request_method = 'OPTIONS') {
                return 200;
            }
            proxy_pass hhttp://127.0.0.1:3000/; 
        } 
    }
}

日志

  • 日志查看
    • cat access.log (直接cat文件,当文件内容太多时可能导致无法定位到具体需要的内容,可以通过grep来过滤内容如: cat access.log | grep ” 404″ > a.log )
    • vi access.log (日志文件较大的情况时不推荐使用)
    • tail -f access.log(实时查看log文件, 可以结合grep来进行使用)
  • 日志的分割
    • mv access.log ./logBak/20190922.log && nginx -s reopen (结合crontab做定时日志切割)

参考

nginx documentation

前端必备!最全nginx技术分析

Nginx 配置文件 nginx.conf 详解

http2 支持情况

  1. 最乐园说道:

    :razz: 老铁你也太厉害了吧!

    1. 陌上寒说道:

      你的网站,好像打不开啊

发表评论

电子邮件地址不会被公开。 必填项已用*标注