• Nginx 配置详解


    ########### 每个指令必须有分号结束。#################
    #user administrator administrators;  #配置用户或者组,默认为nobody nobody。
    #worker_processes 2;  #允许生成的进程数,默认为1
    #pid /nginx/pid/nginx.pid;   #指定nginx进程运行文件存放地址
    error_log log/error.log debug;  #制定日志路径,级别。这个设置可以放入全局块,http块,server块,级别以此为:debug|info|notice|warn|error|crit|alert|emerg
    events {
        accept_mutex on;   #设置网路连接序列化,防止惊群现象发生,默认为on
        multi_accept on;  #设置一个进程是否同时接受多个网络连接,默认为off
        #use epoll;      #事件驱动模型,select|poll|kqueue|epoll|resig|/dev/poll|eventport
        worker_connections  1024;    #最大连接数,默认为512
    }
    http {
        include       mime.types;   #文件扩展名与文件类型映射表
        default_type  application/octet-stream; #默认文件类型,默认为text/plain
        #access_log off; #取消服务日志    
        log_format myFormat '$remote_addr–$remote_user [$time_local] $request $status $body_bytes_sent $http_referer $http_user_agent $http_x_forwarded_for'; #自定义格式
        access_log log/access.log myFormat;  #combined为日志格式的默认值
        sendfile on;   #允许sendfile方式传输文件,默认为off,可以在http块,server块,location块。
        sendfile_max_chunk 100k;  #每个进程每次调用传输数量不能大于设定的值,默认为0,即不设上限。
        keepalive_timeout 65;  #连接超时时间,默认为75s,可以在http,server,location块。
    
        upstream mysvr {   
          server 127.0.0.1:7878;
          server 192.168.10.121:3333 backup;  #热备
        }
        error_page 404 https://www.baidu.com; #错误页
        server {
            keepalive_requests 120; #单连接请求上限次数。
            listen       4545;   #监听端口
            server_name  127.0.0.1;   #监听地址       
            location  ~*^.+$ {       #请求的url过滤,正则匹配,~为区分大小写,~*为不区分大小写。
               #root path;  #根目录
               #index vv.txt;  #设置默认页
               proxy_pass  http://mysvr;  #请求转向mysvr 定义的服务器列表
               deny 127.0.0.1;  #拒绝的ip
               allow 172.18.5.54; #允许的ip           
            } 
        }
    }
    语法规则: location [=|~|~*|^~] /uri/ { … }
    = 开头表示精确匹配
    ^~ 开头表示uri以某个常规字符串开头,理解为匹配 url路径即可。nginx不对url做编码,因此请求为/static/20%/aa,可以被规则^~ /static/ /aa匹配到(注意是空格)。
    ~ 开头表示区分大小写的正则匹配
    ~*  开头表示不区分大小写的正则匹配
    !~和!~*分别为区分大小写不匹配及不区分大小写不匹配 的正则
    / 通用匹配,任何请求都会匹配到。
    多个location配置的情况下匹配顺序为(参考资料而来,还未实际验证,试试就知道了,不必拘泥,仅供参考):
    首先匹配 =,其次匹配^~, 其次是按文件中顺序的正则匹配,最后是交给 / 通用匹配。当有匹配成功时候,停止匹配,按当前匹配规则处理请求。
    upstream prod {
      server localhost:8081 weight=5;
    }
    upstream user {
      server localhost:8082 weight=5;
    }
     
    server {
        listen              80;
        server_name         test.com;
        access_log  "pipe:rollback /data/log/nginx/access.log interval=1d baknum=7 maxsize=1G"  main;
     
        location ^~/prod/ {
            proxy_set_header Host $host;
            proxy_set_header  X-Real-IP        $remote_addr;
            proxy_set_header  X-Forwarded-For  $proxy_add_x_forwarded_for;
            proxy_set_header X-NginX-Proxy true;
     
            proxy_pass http://prod/;
        }
     
        location ^~/user/ {
            proxy_set_header Host $host;
            proxy_set_header  X-Real-IP        $remote_addr;
            proxy_set_header  X-Forwarded-For  $proxy_add_x_forwarded_for;
            proxy_set_header X-NginX-Proxy true;
     
            proxy_pass http://user/;
        }
     
    }

    ^~/prod/表示匹配前缀是prod的请求,proxy_pass的结尾有/, 则会把/prod/*后面的路径直接拼接到后面,即移除user

     

    server {
        listen       80;
        server_name  localhost;  #实际情况可以写域名    
        location / {
             index  index.html index.htm;
             proxy_set_header Host $host:$server_port;
             proxy_pass http://127.0.0.1:9992;
             rewrite ^/(.*)  /index.php?s=$1;    
        }
    }
    
    
     
    代理目录匹配 location
    # 匹配所有根目录location /# 字符串匹配, 表示匹配所有“/static”开头的目录location /static# ~ 匹配符合表达式目录比如代理目录中存在“static/(js|images)”的目录location ~ /static/(js|images)/# ~* 加上 * 表示不区分大小写location ~ /static/(js|images)/# = 表示精确匹配, 只有"/index"路径才会被代理,"/index/test"将不会被代理location = /index

     url重定向规则 rewrite

    包含3个参数:

    rewrite 匹配规则 重定向规则 重定向类型;
    • 规则:可以是字符串或者正则来表示想匹配的目标url
    • 定向路径:表示匹配到规则后要定向的路径,如果规则里有正则,则可以使用$index来表示正则里的捕获分组
    • 重写类型:
      • last :相当于Apache里德(L)标记,表示完成rewrite,浏览器地址栏URL地址不变
      • break;本条规则匹配完成后,终止匹配,不再匹配后面的规则,浏览器地址栏URL地址不变
      • redirect:返回302临时重定向,浏览器地址会显示跳转后的URL地址
      • permanent:返回301永久重定向,浏览器地址栏会显示跳转后的URL地址
     
    作者:aluckdog
    链接:https://www.imooc.com/article/76485
    来源:慕课网

    url重写是指通过配置conf文件,以让网站的url中达到某种状态时则定向/跳转到某个规则,比如常见的伪静态、301重定向、浏览器定向等

    rewrite

    语法

    在配置文件的server块中写,如:

    • server {
    • rewrite 规则 定向路径 重写类型;
    • }
    • 规则:可以是字符串或者正则来表示想匹配的目标url
    • 定向路径:表示匹配到规则后要定向的路径,如果规则里有正则,则可以使用$index来表示正则里的捕获分组
    • 重写类型:
      • last :相当于Apache里德(L)标记,表示完成rewrite,浏览器地址栏URL地址不变
      • break;本条规则匹配完成后,终止匹配,不再匹配后面的规则,浏览器地址栏URL地址不变
      • redirect:返回302临时重定向,浏览器地址会显示跳转后的URL地址
      • permanent:返回301永久重定向,浏览器地址栏会显示跳转后的URL地址

    简单例子

    • server {
    • # 访问 /last.html 的时候,页面内容重写到 /index.html 中
    • rewrite /last.html /index.html last;
    • # 访问 /break.html 的时候,页面内容重写到 /index.html 中,并停止后续的匹配
    • rewrite /break.html /index.html break;
    • # 访问 /redirect.html 的时候,页面直接302定向到 /index.html中
    • rewrite /redirect.html /index.html redirect;
    • # 访问 /permanent.html 的时候,页面直接301定向到 /index.html中
    • rewrite /permanent.html /index.html permanent;
    • # 把 /html/*.html => /post/*.html ,301定向
    • rewrite ^/html/(.+?).html$ /post/$1.html permanent;
    • # 把 /search/key => /search.html?keyword=key
    • rewrite ^/search/([^/]+?)(/|$) /search.html?keyword=$1 permanent;
    • }

    last和break的区别

    因为301和302不能简单的只返回状态码,还必须有重定向的URL,这就是return指令无法返回301,302的原因了。这里 last 和 break 区别有点难以理解:

    • last一般写在server和if中,而break一般使用在location中
    • last不终止重写后的url匹配,即新的url会再从server走一遍匹配流程,而break终止重写后的匹配
    • break和last都能组织继续执行后面的rewrite指令

    location里一旦返回break则直接生效并停止后续的匹配location

    • server {
    • location / {
    • rewrite /last/ /q.html last;
    • rewrite /break/ /q.html break;
    • }
    • location = /q.html {
    • return 400;
    • }
    • }
    • 访问/last/时重写到/q.html,然后使用新的uri再匹配,正好匹配到locatoin = /q.html然后返回了400
    • 访问/break时重写到/q.html,由于返回了break,则直接停止了

    if判断

    只是上面的简单重写很多时候满足不了需求,比如需要判断当文件不存在时、当路径包含xx时等条件,则需要用到if

    语法

    • if (表达式) {
    • }
    • 当表达式只是一个变量时,如果值为空或任何以0开头的字符串都会当做false
    • 直接比较变量和内容时,使用=或!=
    • ~正则表达式匹配,~*不区分大小写的匹配,!~区分大小写的不匹配

    一些内置的条件判断:

    • -f和!-f用来判断是否存在文件
    • -d和!-d用来判断是否存在目录
    • -e和!-e用来判断是否存在文件或目录
    • -x和!-x用来判断文件是否可执行

    内置的全局变量

    • $args :这个变量等于请求行中的参数,同$query_string
    • $content_length : 请求头中的Content-length字段。
    • $content_type : 请求头中的Content-Type字段。
    • $document_root : 当前请求在root指令中指定的值。
    • $host : 请求主机头字段,否则为服务器名称。
    • $http_user_agent : 客户端agent信息
    • $http_cookie : 客户端cookie信息
    • $limit_rate : 这个变量可以限制连接速率。
    • $request_method : 客户端请求的动作,通常为GET或POST。
    • $remote_addr : 客户端的IP地址。
    • $remote_port : 客户端的端口。
    • $remote_user : 已经经过Auth Basic Module验证的用户名。
    • $request_filename : 当前请求的文件路径,由root或alias指令与URI请求生成。
    • $scheme : HTTP方法(如http,https)。
    • $server_protocol : 请求使用的协议,通常是HTTP/1.0或HTTP/1.1。
    • $server_addr : 服务器地址,在完成一次系统调用后可以确定这个值。
    • $server_name : 服务器名称。
    • $server_port : 请求到达服务器的端口号。
    • $request_uri : 包含请求参数的原始URI,不包含主机名,如:”/foo/bar.php?arg=baz”。
    • $uri : 不带请求参数的当前URI,$uri不包含主机名,如”/foo/bar.html”。
    • $document_uri : 与$uri相同。
    gams

    如:

    • 访问链接是:http://localhost:88/test1/test2/test.php
    • 网站路径是:/var/www/html
    • $host:localhost
    • $server_port:88
    • $request_uri:http://localhost:88/test1/test2/test.php
    • $document_uri:/test1/test2/test.php
    • $document_root:/var/www/html
    • $request_filename:/var/www/html/test1/test2/test.php
    stylus

    例子

    • # 如果文件不存在则返回400
    • if (!-f $request_filename) {
    • return 400;
    • }
    • # 如果host不是xuexb.com,则301到xuexb.com中
    • if ( $host != 'xuexb.com' ){
    • rewrite ^/(.*)$ https://xuexb.com/$1 permanent;
    • }
    • # 如果请求类型不是POST则返回405
    • if ($request_method = POST) {
    • return 405;
    • }
    • # 如果参数中有 a=1 则301到指定域名
    • if ($args ~ a=1) {
    • rewrite ^ http://example.com/ permanent;
    • }

    在某种场景下可结合location规则来使用,如:

    • # 访问 /test.html 时
    • location = /test.html {
    • # 默认值为xiaowu
    • set $name xiaowu;
    • # 如果参数中有 name=xx 则使用该值
    • if ($args ~* name=(w+?)(&|$)) {
    • set $name $1;
    • }
    • # 301
    • rewrite ^ /$name.html permanent;
    • }

    上面表示:

    • /test.html => /xiaowu.html
    • /test.html?name=ok => /ok.html?name=ok

    location

    语法

    server块中使用,如:

    • server {
    • location 表达式 {
    • }
    • }

    location表达式类型

    • 如果直接写一个路径,则匹配该路径下的
    • ~ 表示执行一个正则匹配,区分大小写
    • ~* 表示执行一个正则匹配,不区分大小写
    • ^~ 表示普通字符匹配。使用前缀匹配。如果匹配成功,则不再匹配其他location。
    • = 进行普通字符精确匹配。也就是完全匹配。

    优先级

    1. 等号类型(=)的优先级最高。一旦匹配成功,则不再查找其他匹配项。
    2. ^~类型表达式。一旦匹配成功,则不再查找其他匹配项。
    3. 正则表达式类型(~ ~*)的优先级次之。如果有多个location的正则能匹配的话,则使用正则表达式最长的那个。
    4. 常规字符串匹配类型。按前缀匹配。

    例子 - 假地址掩饰真地址

    • server {
    • # 用 xxoo_admin 来掩饰 admin
    • location / {
    • # 使用break拿一旦匹配成功则忽略后续location
    • rewrite /xxoo_admin /admin break;
    • }
    • # 访问真实地址直接报没权限
    • location /admin {
    • return 403;
    • }
    • }

    Nginx location在配置中的优先级

     location表达式类型
    ~ 表示执行一个正则匹配,区分大小写
    ~* 表示执行一个正则匹配,不区分大小写
    ^~ 表示普通字符匹配。使用前缀匹配。如果匹配成功,则不再匹配其他location。
    = 进行普通字符精确匹配。也就是完全匹配。
    @ “@” 定义一个命名的 location,使用在内部定向时,例如 error_page, try_files
    location优先级说明

    在nginx的location和配置中location的顺序没有太大关系。正location表达式的类型有关。相同类型的表达式,字符串长的会优先匹配。
    以下是按优先级排列说明:
    第一优先级:等号类型(=)的优先级最高。一旦匹配成功,则不再查找其他匹配项。
    第二优先级:^~类型表达式。一旦匹配成功,则不再查找其他匹配项。
    第三优先级:正则表达式类型(~ ~*)的优先级次之。如果有多个location的正则能匹配的话,则使用正则表达式最长的那个。
    第四优先级:常规字符串匹配类型。按前缀匹配。

    location = / {
    # 仅仅匹配请求 /
    [ configuration A ]
    }
    location / {
    # 匹配所有以 / 开头的请求。但是如果有更长的同类型的表达式,则选择更长的表达式。如果有正则表达式可以匹配,则
    # 优先匹配正则表达式。
    [ configuration B ]
    }
    location /documents/ {
    # 匹配所有以 /documents/ 开头的请求。但是如果有更长的同类型的表达式,则选择更长的表达式。
    #如果有正则表达式可以匹配,则优先匹配正则表达式。
    [ configuration C ]
    }
    location ^~ /images/ {
    # 匹配所有以 /images/ 开头的表达式,如果匹配成功,则停止匹配查找。所以,即便有符合的正则表达式location,也
    # 不会被使用
    [ configuration D ]
    }
    location ~* .(gif|jpg|jpeg)$ {
    # 匹配所有以 gif jpg jpeg结尾的请求。但是 以 /images/开头的请求,将使用 Configuration D
    [ configuration E ]
    }

    二级域名 和 跨域设置

        server {
            listen       80;
            server_name  admin.expressell.com;
            # include /usr/local/var/www/.htaccess;
            #charset koi8-r;
            
            #add_header Access-Control-Allow-Origin http://1222.com:8085;
         add_header Access-Control-Allow-Origin *;

         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;
            add_header Access-Control-Allow-Methods GET,POST,OPTIONS;
            add_header Access-Control-Allow-Credentials true;
    
            #access_log  logs/host.access.log  main;
            location ~ .(css|js|ico|gif|jpg|jpeg|png|svg)$ {
                root /data/www/expressell_api/public;
                log_not_found off;
                access_log off;
                expires 7d;
                keepalive_timeout 0;
                proxy_cache_valid 200 302 1d;
            }
            location / {
                root   /data/www/expressell_api/public;
                index  index.html index.htm index.php;
    
                if ( !-e $request_filename ){
                    # rewrite ^(.*)$ /index.php?s=$1 last;
                    # break;
            rewrite ^/index.php(.*)$ /index.php?s=$1 last;
                    rewrite ^(.*)$ /index.php?s=$1 last;
    
                }
    
            }        
    
    
            error_page   500 502 503 504  /50x.html;
            location = /50x.html {
                root   html;
            }
    
            location ~ .php$ {
                root           /data/www/expressell_api/public;
                fastcgi_pass   127.0.0.1:9000;
                fastcgi_index  index.php;
                fastcgi_param  SCRIPT_FILENAME  /$document_root$fastcgi_script_name;
                include        fastcgi_params;
            }
    
            # deny access to .htaccess files, if Apache's document root
            # concurs with nginx's one
            #
            #location ~ /.ht {
            #    deny  all;
            #}
        }
    这样是允许所有域名,但是不想这样,那这样就没什么意义了,
    
    add_header Access-Control-Allow-Origin *;
    但是想要指定多个域名,nginx不支持这样写
    
    add_header Access-Control-Allow-Origin http://test.blyoo.com,https://www.blyoo.com;
    可以这样写,多次判断,还要很多N多方法,这只是其中一种
    
     location / {  
         set $cors_origin "";
            if ($http_origin ~* "^http://test.blyoo.com$") {
                    set $cors_origin $http_origin;
            }
            if ($http_origin ~* "^https://www.blyoo.com$") {
                    set $cors_origin $http_origin;
            }
            add_header Access-Control-Allow-Origin $cors_origin;
    }
  • 相关阅读:
    undefined symbol 问题解决记录
    2021年中国数字人民币发展研究报告
    如何画出优秀的架构图
    用SIKT模型,让用户画像效果倍增
    全面总结图表设计
    如何用一周了解一个行业
    未来社区解决方案
    增长4大阶段,实现营销倍增的核心法则
    裂变营销的3个层次,让你实现指数增长
    运营的3个层面,让你轻松获得忠实用户
  • 原文地址:https://www.cnblogs.com/xiondun/p/13563121.html
Copyright © 2020-2023  润新知