• nginx配置文件梳理 一介凡人


    一、nginx配置文件的结构

    1、大致结构如下

    ...              #全局块
    
    events {         #events块
       ...
    }
    
    http      #http块
    {
        ...   #http全局块
        server        #server块
        { 
            ...       #server全局块
            location [PATTERN]   #location块
            {
                ...
            }
            location [PATTERN] 
            {
                ...
            }
        }
        server
        {
          ...
        }
        ...     #http全局块
    }

    全局块:配置影响nginx全局的指令。一般有运行nginx服务器的用户组,nginx进程pid存放路径,日志存放路径,配置文件引入,允许生成worker process数等。如:

    user nginx;
    worker_processes auto;
    error_log /var/log/nginx/error.log;
    pid /run/nginx.pid;
    
    include /usr/share/nginx/modules/*.conf;

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

    events
    {
        #参考事件模型,use [ kqueue | rtsig | epoll | /dev/poll | select | poll ]; epoll模型是Linux 2.6以上版本内核中的高性能网络I/O模型,如果跑在FreeBSD上面,就用kqueue模型.
        use epoll;
        #单个进程最大连接数(最大连接数=连接数*进程数)
        worker_connections 1024;    #最大连接数,默认为512
    }

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

    http
    {
        include mime.types; #文件扩展名与文件类型映射表
        default_type application/octet-stream; #默认文件类型
        #charset utf-8; #默认编码
        server_names_hash_bucket_size 128; #服务器名字的hash表大小
        client_header_buffer_size 32k; #上传文件大小限制
        large_client_header_buffers 4 64k; #设定请求缓
        client_max_body_size 8m; #设定请求缓
        keepalive_timeout 65;  #连接超时时间,默认为75s,可以在http,server,location块。
        # 开启目录列表访问,合适下载服务器,默认关闭.
        autoindex on; # 显示目录
        autoindex_exact_size on; # 显示文件大小 默认为on,显示出文件的确切大小,单位是bytes 改为off后,显示出文件的大概大小,单位是kB或者MB或者GB
        autoindex_localtime on; # 显示文件时间 默认为off,显示的文件时间为GMT时间 改为on后,显示的文件时间为文件的服务器时间
        
        sendfile on; # 开启高效文件传输模式,sendfile指令指定nginx是否调用sendfile函数来输出文件,对于普通应用设为 on,如果用来进行下载等应用磁盘IO重负载应用,可设置为off,以平衡磁盘与网络I/O处理速度,降低系统的负载.注意:如果图片显示不正常把这个改成off.
        tcp_nopush on; # 防止网络阻塞
        tcp_nodelay on; # 防止网络阻塞
        
        # FastCGI相关参数是为了改善网站的性能:减少资源占用,提高访问速度.下面参数看字面意思都能理解.
        fastcgi_connect_timeout 300; ## 链接
        fastcgi_send_timeout 300;  ##读取 是指nginx进程向fastcgi进程发送request的整个过程的超时时间
        fastcgi_read_timeout 300;  ##发请求 是指fastcgi进程向nginx进程发送response的整个过程的超时时间
        fastcgi_buffer_size 64k;
        fastcgi_buffers 4 64k;
        fastcgi_busy_buffers_size 128k;
        fastcgi_temp_file_write_size 128k;
        
        # gzip模块设置
        gzip on; #开启gzip压缩输出
        gzip_min_length 1k; #允许压缩的页面的最小字节数,页面字节数从header偷得content-length中获取.默认是0,不管页面多大都进行压缩.建议设置成大于1k的字节数,小于1k可能会越压越大
        gzip_buffers 4 16k; #表示申请4个单位为16k的内存作为压缩结果流缓存,默认值是申请与原始数据大小相同的内存空间来存储gzip压缩结果
        gzip_http_version 1.1; #压缩版本(默认1.1,目前大部分浏览器已经支持gzip解压.前端如果是squid2.5请使用1.0)
        gzip_comp_level 2; #压缩等级.1压缩比最小,处理速度快.9压缩比最大,比较消耗cpu资源,处理速度最慢,但是因为压缩比最大,所以包最小,传输速度快
        gzip_types text/plain application/x-javascript text/css application/xml;
        #压缩类型,默认就已经包含text/html,所以下面就不用再写了,写上去也不会有问题,但是会有一个warn.
        gzip_vary on;#选项可以让前端的缓存服务器缓存经过gzip压缩的页面.例如:用squid缓存经过nginx压缩的数据
        
        #开启限制IP连接数的时候需要使用
        #limit_zone crawler $binary_remote_addr 10m;
        
        ##upstream的负载均衡,四种调度算法

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

    #虚拟主机的配置
        server
        {
            # 监听端口
            listen 80;
            # 域名可以有多个,用空格隔开
            server_name 127.0.0.1;
            # HTTP 自动跳转 HTTPS
            rewrite ^(.*) https://www.baidu.com;
            deny 127.0.0.1;  #拒绝的ip
            allow 172.18.5.54; #允许的ip 
        }
        upstream myserver {   
          server 127.0.0.1:8080;
          server 192.168.24.189:8080 backup;  #热备
        }
        server
        {
            # 监听端口 HTTPS
            listen 443 ssl;
            server_name https://www.baidu.com;
            root /data/www/;
            # 配置域名证书
            ssl_certificate      C:\WebServer\Certs\certificate.crt;
            ssl_certificate_key  C:\WebServer\Certs\private.key;
            ssl_session_cache    shared:SSL:1m;
            ssl_session_timeout  5m;
            ssl_protocols SSLv2 SSLv3 TLSv1;
            ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
            ssl_prefer_server_ciphers  on;
        
            index index.html index.htm index.php;
            
            location ~ .*\.(php|php5)?$
            {
                fastcgi_pass 127.0.0.1:9000;
                fastcgi_index index.php;
                include fastcgi.conf;
            }

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

    # 配置地址拦截转发,解决跨域验证问题
            location /oauth/{
                proxy_pass https://localhost:13580/oauth/;
                proxy_set_header HOST $host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            }
            
            # 图片缓存时间设置
            location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ {
                expires 10d;
            }
            
            # JS和CSS缓存时间设置
            location ~ .*\.(js|css)?$ {
                expires 1h;
            }
    
    # 日志格式设定
            log_format access '$server_name $remote_addr -$remote_user [$time_local] "$request"'
                      '$status $uptream_status $body_bytes_sent "$http_referer"'
                      '"$http_user_agent" "$http_x_forwarded_for" '
                      '$ssl_protocol $ssl_cipher $upstream_addr $request_time $upstream_response_time';
           # 定义本虚拟主机的访问日志
            access_log /var/log/nginx/access.log access;
            
            # 设定查看Nginx状态的地址.StubStatus模块能够获取Nginx自上次启动以来的工作状态,此模块非核心模块,需要在Nginx编译安装时手工指定才能使用
            location /NginxStatus {
                stub_status on;
                access_log on;
                auth_basic "NginxStatus";
                auth_basic_user_file conf/htpasswd;
                #htpasswd文件的内容可以用apache提供的htpasswd工具来产生.
            }
        }
    }
    

    二、location的匹配规则

    1、alias 和 root 两种方式设置nginx虚拟目录

    1. alias指定的目录是准确的,即location匹配访问的path目录下的文件直接是在alias目录下查找的;
    2. root指定的目录是location匹配访问的path目录的上一级目录,这个path目录一定要是真实存在root指定目录下的;
    3. 使用alias标签的目录块中不能使用rewrite的break;另外,alias指定的目录后面必须要加上"/"符号!!
    4. alias虚拟目录配置中,location匹配的path目录如果后面不带"/",那么访问的url地址中这个path目录后面加不加"/"不影响访问,访问时它会自动加上"/";
    5. 但是如果location匹配的path目录后面加上"/",那么访问的url地址中这个path目录必须要加上"/",访问时它不会自动加上"/"。如果不加上"/",访问就会失败!
    6. root目录配置中,location匹配的path目录后面带不带"/",都不会影响访问。
    server {
              listen 80;
              server_name www.wangshibo.com;
              index index.html index.php index.htm;
              access_log /usr/local/nginx/logs/image.log;
    
        location / {
            root /var/www/html;
            }
    
       location /haha {                                          //匹配的path目录haha不需要真实存在alias指定的目录中
           alias /var/www/html/ops/;                       //后面的"/"符号一定要带上
           rewrite ^/opp/hen.php(.*)$ /opp/hen.php?s=$1 last;
        # rewrite ^/opp/(.*)$ /opp/hen.php?s=$1 last;
           }
    
       location /wang {                    //匹配的path目录wang一定要真实存在root指定的目录中(就/var/www/html下一定要有wang目录存在)
          root /var/www/html;
         }
    
     }
    

    2、location匹配顺序

    location 指令是 nginx 中最关键的指令之一,location 指令的功能是用来匹配不同的 URI 请求,进而对请求做不同的处理和响应,这其中较难理解的是多个 location 的匹配顺序

    nginx有两层指令来匹配请求 URI 。

    第一层次: server 指令,它通过域名、ip 和端口来做第一层级匹配
    
    第二层次:当找到匹配的 server 后就进入此 server 的 location 匹配

    location 的匹配并不完全按照其在配置文件中出现的顺序来匹配,请求URI 会按如下规则进行匹配:

    1. 先精准匹配 = ,精准匹配成功则会立即停止其他类型匹配;
    2. 没有精准匹配成功时,进行前缀匹配。先查找带有 ^~ 的前缀匹配,带有 ^~ 的前缀匹配成功则立即停止其他类型匹配,普通前缀匹配(不带参数 ^~ )成功则会暂存,继续查找正则匹配;
    3. = 和 ^~ 均未匹配成功前提下,查找正则匹配 ~ 和 ~* 。当同时有多个正则匹配时,按其在配置文件中出现的先后顺序优先匹配,命中则立即停止其他类型匹配;
    4. 所有正则匹配均未成功时,返回步骤 2 中暂存的普通前缀匹配(不带参数 ^~ )结果

    以上规则简单总结就是优先级从高到低依次为(序号越小优先级越高):

    1. location =    # 精准匹配
    2. location ^~   # 带参前缀匹配
    3. location ~    # 正则匹配(区分大小写)
    4. location ~*   # 正则匹配(不区分大小写)
    5. location /a   # 普通前缀匹配,优先级低于带参数前缀匹配
    6. location /    # 任何没有匹配成功的,都会匹配这里处理

    案例1

    server {
        server_name website.com;
        location /doc {
            return 701; # 用这样的方式,可以方便的知道请求到了哪里
        }
        location ~* ^/document$ {
            return 702; 
    
        }
    }

    测试:匹配到702,说明~*的正则匹配优先级高于普通前缀匹配

    curl -I 192.168.40.132/document
    HTTP/1.1 702 
    Server: nginx/1.20.1
    Date: Thu, 04 Nov 2021 03:13:20 GMT
    Content-Length: 0
    Connection: keep-alive

    案例2

    server {
        server_name website.com;
        location = /document {
            return 701;
        }
        location ~* ^/document$ {
            return 702;
        }
    }

    测试结果:精确匹配高于正则匹配

    #curl -I 192.168.40.132/document
    HTTP/1.1 701 
    Server: nginx/1.20.1
    Date: Thu, 04 Nov 2021 03:21:04 GMT
    Content-Length: 0
    Connection: keep-alive

    案例3

    server {
        server_name website.com;
        location ^~ /doc {
            return 701;
        }
        location ~* ^/document$ {
            return 702;
        }
    }

    测试结果:^~  带参前缀匹配优于正则匹配 ~*(第一个前缀匹配 ^~ 命中以后不会再搜寻正则匹配,所以会第一个命中)

    curl -I 192.168.40.132/document
    HTTP/1.1 701 
    Server: nginx/1.20.1
    Date: Thu, 04 Nov 2021 03:23:59 GMT
    Content-Length: 0
    Connection: keep-alive
    

     案例4

    /
    /index.html
    /documents/document.html
    /documents/abc
    /images/a.gif
    /documents/a.jpg
    

    以下是 location 配置及其匹配情况

    location  = / {
        # 只精准匹配 / 的查询.
      [ configuration A ] 
    }
    # 匹配成功: / 
    
    location / {
        # 匹配任何请求,因为所有请求都是以”/“开始
        # 但是更长字符匹配或者正则表达式匹配会优先匹配
      [ configuration B ] 
    }
    #匹配成功:/index.html
    
    location /documents {
        # 匹配任何以 /documents/ 开头的地址,匹配符合以后,还要继续往下搜索/
        # 只有后面的正则表达式没有匹配到时,这一条才会采用这一条/
      [ configuration C ] 
    }
    # 匹配成功:/documents/document.html
    # 匹配成功:/documents/abc
    
    location ~ /documents/ABC {
        # 区分大小写的正则匹配
        # 匹配任何以 /documents/ 开头的地址,匹配符合以后,还要继续往下搜索/
        # 只有后面的正则表达式没有匹配到时,这一条才会采用这一条/
      [ configuration CC ] 
    }
    
    location ^~ /images/ {
        # 匹配任何以 /images/ 开头的地址,匹配符合以后,立即停止往下搜索正则,采用这一条。/
      [ configuration D ] 
    }
    # 成功匹配:/images/a.gif
    
    location ~* \.(gif|jpg|jpeg)$ {
        # 匹配所有以 .gif、.jpg 或 .jpeg 结尾的请求,不区分大小写
        # 然而,所有请求 /images/ 下的图片会被 [ config D ]  处理,因为 ^~ 到达不了这一条正则/
        [ configuration E ] 
    }
    # 成功匹配:/documents/a.jpg
    
    location /images/ {
        # 字符匹配到 /images/,继续往下,会发现 ^~ 存在/
      [ configuration F ] 
    }
    
    location /images/abc {
        # 最长字符匹配到 /images/abc,继续往下,会发现 ^~ 存在/
        # F与G的放置顺序是没有关系的/
      [ configuration G ] 
    }
    
    location ~ /images/abc/ {
        # 只有去掉 [ config D ] 才有效:先最长匹配 [ config G ] 开头的地址,继续往下搜索,匹配到这一条正则,采用/
        [ configuration H ] 
    }
    

    其他location配置相关

    匹配问号后的参数

    请求 URI 中问号后面的参数是不能在 location 中匹配到的,这些参数存储在 $query_string 变量中,可以用 if 来判断。
    例如,对于参数中带有单引号 ’ 进行匹配然后重定向到错误页面。

    /plus/list.php?tid=19&mid=1124‘
    if ( $query_string ~* “.*[;’<>].*” ){
      return 404;
    }
    

    location URI结尾带不带 /

    关于 URI 尾部的 / 有三点也需要说明一下。第一点与 location 配置有关,其他两点无关。

    1. location 中的字符有没有 / 都没有影响。也就是说 /user/ 和 /user 是一样的。
    2. 如果 URI 结构是 https://domain.com/ 的形式,尾部有没有 / 都不会造成重定向。因为浏览器在发起请求的时候,默认加上了 / 。虽然很多浏览器在地址栏里也不会显示 / 。这一点,可以访问baidu验证一下。
    3. 如果 URI 的结构是 https://domain.com/some-dir/ 。尾部如果缺少 / 将导致重定向。因为根据约定,URL 尾部的 / 表示目录,没有 / 表示文件。所以访问 /some-dir/ 时,服务器会自动去该目录下找对应的默认文件。如果访问 /some-dir 的话,服务器会先去找 some-dir 文件,找不到的话会将 some-dir 当成目录,重定向到 /some-dir/ ,去该目录下找默认文件。可以去测试一下你的网站是不是这样的。

    命名 location

    带有 @ 的 location 是用来定义一个命名的 location,这种 location 不参与请求匹配,一般用在内部定向。用法如下:

    location / {
        try_files $uri $uri/ @custom
    }
    location @custom {
        # ...do something
    }
    

    上例中,当尝试访问 URI 找不到对应的文件就重定向到我们自定义的命名 location(此处为 custom)。

    值得注意的是,命名 location 中不能再嵌套其它的命名 location。

    最全Nginx 配置文件详解及安装 - 知乎 (zhihu.com)

    Nginx虚拟目录alias和root目录 - 散尽浮华 - 博客园 (cnblogs.com)

    一文理清nginx中的location配置(系列一) - 知乎 (zhihu.com)  案例多,分析到位

  • 相关阅读:
    前端HTMLCSS
    jedis 连接池的使用
    win8+安装net3.5步骤与常见错误.
    并行线程的生命周期
    OneNote截图快捷键冲突解决方案
    C#中lsitView如何搜索某个子项
    redis哨兵与集群
    git笔记
    微软官方Hololens开发课程介绍
    Markdown使用入门简介
  • 原文地址:https://www.cnblogs.com/zjz20/p/15483526.html
Copyright © 2020-2023  润新知