侧边栏壁纸
博主头像
一朵云的博客博主等级

拥抱生活,向阳而生。

  • 累计撰写 67 篇文章
  • 累计创建 25 个标签
  • 累计收到 7 条评论

目 录CONTENT

文章目录

Nginx -- 基本配置(含缓存应用讲解)

一朵云
2021-12-28 / 0 评论 / 3 点赞 / 8428 阅读 / 15460 字

nginx01.png

Nginx的主要配置

1、nginx文件结构

...              #全局块

events {         #events块
   ...
}

http      #http块
{

    ...   #http全局块
    server        #server块
    { 
        ...       #server全局块
        location [PATTERN]   #location块
        {
            ...
        }
        location [PATTERN] 
        {
            ...
        }
    }
    server
    {
      ...
    }
    ...     #http全局块
}
  • 1、全局块:配置影响nginx全局的指令。一般有运行nginx服务器的用户组,nginx进程pid存放路径,日志存放路径,配置文件引入,允许生成worker process数等。

  • 2、events块:配置影响nginx服务器或与用户的网络连接。有每个进程的最大连接数,选取哪种事件驱动模型处理连接请求,是否允许同时接受多个网路连接,开启多个网络连接序列化等。

  • 3、http块:可以嵌套多个server,配置代理,缓存,日志定义等绝大多数功能和第三方模块的配置。如文件引入,mime-type定义,日志自定义,是否使用sendfile传输文件,连接超时时间,单连接请求数等。

  • 4、server块:配置虚拟主机的相关参数,一个http中可以有多个server。

  • 5、location块:配置请求的路由,以及各种页面的处理情况。

2、nginx.conf 文件内容分析

/etc/nginx/nginx.conf

# 运行用户,默认是nginx,可以不进行设置		
user  nginx;
# Nginx进程,一般设置和cpu核数一样
worker_processes  1;

# 错误日志存放位置
error_log  /var/log/nginx/error.log warn;
# 进程pid存放位置
pid  /var/run/nginx.pid;


events {
    # 单个后台进程的最大并发数
    worker_connections  1024;
}


http {
    # 文件扩展名和类型映射表
    include       /etc/nginx/mime.types;
    # 默认的文件类型
    default_type  application/octet-stream;
    # 设置日志模式(默认的、无须设置的combined日志格式设置)
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    # nginx访问日志的存放位置    
    access_log  /var/log/nginx/access.log  main;

    # 是否开启高效传输模式 on开启 off关闭    
    sendfile        off;
    # 减少网络报文段的数量
    #tcp_nopush     on;

    # 保持连接的时间,也叫超时时间    
    keepalive_timeout  65;

    # 开启gzip压缩模式
    #gzip  on;

    # 包含的子配置项的位置和文件
    include /etc/nginx/conf.d/*.conf;
}

3、常用配置

(1)、一个站点配置多个域名

server {

    listen 80;

    server_name aaa.cn bbb.cn;

}

(2)、反向代理,负载均衡

  将80端口进来的请求代理到192.168.0.1和192.168.0.2的服务上。

    http
    {
        #流的配置,用于负载均衡
        upstream  xxx
        {
            server 192.168.0.1;
            server 192.168.0.2;
        }

        server
        {
             listen       80;
             server_name  域名或IP;
             
             location /
             {
                 root         html;
                 index        hello.html;
		 #配置反向代理
                 proxy_pass   http://xxx;
		 #避免原ip统计不到
		 proxy_set_header  Host  $host;
                 proxy_set_header  X-Real-IP  $remote_addr;
             }     
        }
    }    
    

(3)、动静分离

  存粹的将静态文件部署在一台独立的服务器上,使用单独的域名,与动态请求区分开。(主流推崇)

  当前的目录情况:

  ./conf.d/my_nginx.conf 配置情况:

server
    {
         listen       80;
         server_name  独立的域名或IP;
         #解决目录中文乱码问题    
         charset utf-8,gbk;       

         location /html
         {
             root         /usr/docker/myNginx;
             index        hello.html;
         }  

         location /images
         {
             root         /usr/docker/myNginx;
             #Nginx默认是不允许列出整个目录的,打开需要加上
             autoindex    on;
         }   
    }

测试结果:

  访问图片,ip/imgaes
image.png

  访问网页,ip/html
image.png

(4)、动静分离(指定资源格式 + 缓存)

http缓存概念梳理:

1、强制缓存(无HTTP请求,无需协商):

浏览器在加载资源的时候,会先根据本地缓存资源的header中的信息(Expires 和 Cache-Control)来判断是否需要强制缓存。如果命中的话,则会直接使用缓存中的资源。否则的话,会继续向服务器发送请求。

Http协议的cache-control和expires的常见取值及释义:

  • private(默认): 只能在浏览器中缓存, 只有在第一次请求的时候才访问服务器, 若有max-age, 则缓存期间不访问服务器。
  • public:可以被所有的用户缓存,包括终端用户和 CDN 等中间代理服务器。
  • no-cache: 需要进行协商缓存,发送请求到服务器确认是否使用缓存。
  • no-store:禁止使用缓存,每一次都要重新请求数据。
  • max-age(绝对):指我们的web中的文件被用户访问(请求)后的存活时间,是个相对的值。默认的max-age是由Expires算出来的,单位为秒。
  • expires(相对):头部字段提供一个日期和时间,响应在该日期和时间后被认为失效。

  • 2、协商缓存(有HTTP请求,需协商):

    ①、协商缓存 Last-Modified/if-Modify-Since。

    浏览器第一次发出请求一个资源的时候,服务器会返回一个last-Modify到hearer中 Last-Modify 含义是最后的修改时间。

    当浏览器再次请求的时候,request的请求头会加上 if-Modify-Since,该值缓存的是之前返回的 Last-Modify。 服务器收到if-Modify-Since后,根据资源的最后修改时间(last-Modify)和该值(if-Modify-Since)进行比较。如果相等的话,则命中缓存,返回304,否则, 如果 Last-Modify > if-Modify-Since, 则会给出200响应,并且更新Last-Modify为新的值。

    ②、协商缓存 ETag/if-None-Match。

    web服务器响应请求时,告诉浏览器当前资源在服务器的唯一标识(生成规则由服务器决定),如果给定URL中的资源修改,则一定要生成新的Etag值。

    浏览器再下一次加载的时候会向服务器发送请求,会将上一次返回的ETag值放到request header 里的 if-None-Match里面去,服务器端只要比较客户端传来的if-None-Match值是否和自己服务器上的ETag是否一致,如果一致说明资源未修改过,因此返回304,如果不一致,说明修改过,因此返回200。并且把新的Etag赋值给if-None-Match来更新该值。

      Nginx默认开启last modified特性, 也可以在nginx.conf中添加以下配置, 主动控制:

    location ~ .*\.(js|css)?$ {  
        root /usr/share/nginx/static;
        if_modified_since off/exact/before; #off:关闭;exact:精准匹配才取缓存;before:时间之前的也可取缓存
    }
    

      Nginx1.7.3及以上的版本默认开启Etag特性, 但是和Last-Modified一样, 可以主动配置:

    location ~ .*\.(js|css)?$ {  
        root /usr/share/nginx/static;
        etag off/on;
    }
    

      同时存在Last-modify、etag、expires以及cache-control这个4个属性时, cache-control的优先级是最高的。

      优先级:Cache-Control > Expires > Etag > Last-modify

      max-age=xxx (xxx is numeric) 缓存的内容将在 xxx 秒后失效, 如果和Last-Modified一起使用时, 优先级更高

      Nginx设置cache-control(例如设置max-age为30秒):

    location ~ .*\.(js|css)?$ {  
        root /usr/share/nginx/static;
        add_header  Cache-Control "max-age=30";
    }
    

      通过 expires 参数设置,可以使浏览器缓存过期时间,减少与服务器之前的请求和流量。Expires的定义:是给一个资源设定一个过期时间,也就是说无需去服务端验证,直接通过浏览器自己确认是否过期即可,所以不会产生额外的流量。此方法仅适合不经常变动的资源使用。(不适用于频繁变动的资源)

    #静态资源缓存设置
    location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|ioc|rar|zip|txt|flv|mid|doc|ppt|pdf|xls|mp3|wma)$  {     
        root /usr/share/nginx/static;    #static文件夹在Nginx目录下没有,需创建,和conf文件夹同级  
        expires      30d;
    }          
    location ~ .*\.(js|css)?$ {  
        root /usr/share/nginx/static;
        expires      30d;
    
        #expires 30s; #30秒
        #expires 30m; #30分钟
        #expires 2h;  #2个小时
        #expires 30d; #30天
    }
    

      上述配置中的 30d ,表示在这30天内访问这些后缀的资源时,会发送一个请求,对比服务器该文件最后更新时间有没有变化,没有则不从服务器抓取,直接返回状态码304,如果有修改,则直接从服务器重新下载,返回状态码200。

    (5)、静态缓存场景验证:

    ①、静态资源不缓存,每次都是重新获取。
    location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|ioc|rar|zip|txt|flv|mid|doc|ppt|pdf|xls|mp3|wma)$  {     
                 root        /usr/share/nginx/static;
                
                 add_header  Cache-Control no-store;
           } 
    

    image.png

    ②、静态资源设置 Cache-Control 进行强缓存。
     #静态资源缓存设置
           location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|ioc|rar|zip|txt|flv|mid|doc|ppt|pdf|xls|mp3|wma)$  {     
                 root              /usr/share/nginx/static;    #static文件夹在Nginx目录下没有,需创建,和conf文件夹同级  
                
                 if_modified_since off;
                 etag              off;
                 add_header        Cache-Control  max-age=60; #浏览器进行60s缓存。
           } 
    

      首次加载:
    image.png

      换个浏览器tab页,在首次加载成功后的60s内访问:
    image.png

      超过60s,将需要重新从服务器加载资源。

    ③、静态资源设置 Expires 进行强缓存。
    #静态资源缓存设置
           location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|ioc|rar|zip|txt|flv|mid|doc|ppt|pdf|xls|mp3|wma)$  {     
                 root              /usr/share/nginx/static;    #static文件夹在Nginx目录下没有,需创建,和conf文件夹同级  
                
                 if_modified_since off;
                 etag              off;
                 expires 120s; #浏览器进行120s缓存。
                 
           }
    

    image.png

      在Date和Expires显示的时间(显示的GMT为世界标准时间,而我国是东八区,即GMT+8)范围内,缓存有效,更换浏览器tab窗口访问不会重新加载服务器资源。

      超出时间则会重新加载资源,重新计算Date和Expires。

    ④、静态资源设置 Etag 进行协商缓存。
    #静态资源缓存设置
           location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|ioc|rar|zip|txt|flv|mid|doc|ppt|pdf|xls|mp3|wma)$  {     
                 root              /usr/share/nginx/static;    #static文件夹在Nginx目录下没有,需创建,和conf文件夹同级  
                
                 if_modified_since off;
                 etag              on;
           }
    

      首次加载,从服务器获取资源。

    image.png

      文件内容不变的前提下,第二次加载(etag值相同),读取缓存,响应码304。

    image.png

      文件内容变更后,第三次加载(etag值变更),重新请求服务器加载了服务器资源。

    image.png

    ⑤、静态资源设置 if-Modify-Since 进行协商缓存。
    #静态资源缓存设置
           location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|ioc|rar|zip|txt|flv|mid|doc|ppt|pdf|xls|mp3|wma)$  {     
                 root              /usr/share/nginx/static;    #static文件夹在Nginx目录下没有,需创建,和conf文件夹同级  
                
                 if_modified_since exact; #Last-Modified 和 if-Modify-Since两者相等则取缓存值。
                 etag              off;
           }
    

      首次加载,从服务器获取资源。

    image.png

      图片资源内容未变动的前提下,第二次加载(Last-Modified 和 if-Modify-Since两者相等),读取缓存资源,响应码304。

    image.png

      图片资源内容变动,第三次加载(Last-Modified 和 if-Modify-Since值不同),再次从服务器获取资源,并更新Last-Modified的值。

    image.png

      关于动静分离中使用缓存的思考,这里顺便推荐一篇知乎回答:
    大公司里怎样开发和部署前端代码? - 张云龙的回答 - 知乎

    4、nginx中location的规则

    语法规则:
    location [ = | ~ | ~* | ^~ ] /uri/ {… }

      首先匹配 =,其次匹配^~,其次是按文件中顺序的正则匹配,最后是交给 /通用匹配。当有匹配成功时候,停止匹配,按当前匹配规则处理请求。

    符号含义
    == 开头表示精确匹配
    ^~~ 开头表示uri以某个常规字符串开头,理解为匹配 url路径即可。nginx不对url做编码,因此请求为/static/20%/aa,可以被规则~ /static/ /aa匹配到(注意是空格)
    ~~ 开头表示区分大小写的正则匹配
    ~*~* 开头表示不区分大小写的正则匹配
    !~和!~*!~ 和 !~*分别为区分大小写不匹配及不区分大小写不匹配的正则
    /用户所使用的代理(一般为浏览器)
    @带有@的 location 是用来定义一个命名的 location,这种 location 不参与请求匹配,一般用在内部定向

    匹配规则示例:

    location = / {  
        #规则A  
    }  
    location = /login {  
        #规则B  
    }  
    location ^~ /static/ {  
        #规则C  
    }  
    location ~ \.(gif|jpg|png|js|css)$ {  
        #规则D  
    }  
    location ~* \.png$ {  
        #规则E  
    }  
    location !~ \.xhtml$ {  
        #规则F  
    }  
    location !~* \.xhtml$ {  
        #规则G  
    }  
    location / {  
        #规则H  
    }
    location /test {
        #规则I
        try_files $uri $uri/ @custom
    }
    location @custom {
        #规则I_2
    }  
    

    那么产生的效果如下:

    1. 访问根目录/,比如:http://localhost/ 将匹配规则A

    2. 访问 http://localhost/login 将匹配规则Bhttp://localhost/register 则匹配规则H

    3. 访问 http://localhost/static/a.html 将匹配规则C

    4. 访问 http://localhost/a.gifhttp://localhost/b.jpg 将匹配规则D规则E,但是规则D顺序优先,规则E不起作用,http://localhost/static/c.png 则优先匹配到规则C

    5. 访问 http://localhost/a.PNG 则匹配规则E,而不会匹配规则D,因为规则E不区分大小写。

    6. 访问 http://localhost/a.xhtml 不会匹配规则F规则Ghttp://localhost/a.XHTML 不会匹配规则G,因为不区分大小写。规则F规则G属于排除法,符合匹配规则但是不会被匹配到,属于逆向思维了。

    7. 访问 http://localhost/category/id/1111 则最终匹配到规则H,因为以上规则都不匹配,这个时候应该是nginx转发请求给后端应用服务器,比如FastCGI(php),tomcat(jsp),nginx作为反向代理服务器存在。

    8. 访问 http://localhost/test 则匹配到规则I,并通过@重定向到规则I_2

    3

    评论区