nginx 详解

Posted on Posted in nginx

nginx 详解

需要的包

安装

groupadd nginx
useradd -s `which nologin` -g nginx nginx

# 相应的路径,解压上面的包,进行一一对应
./configure \
--user=nginx \
--group=nginx \
--prefix=/usr/local/nginx \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_stub_status_module \
--with-pcre=/usr/local/src/pcre-8.42 \
--with-http_gzip_static_module \
--with-stream \
--with-stream_ssl_module \
--with-openssl=/usr/local/src/openssl-1.0.2o \
--with-http_realip_module \
--add-module=/usr/local/src/ngx_cache_purge-2.3 \
--add-module=/usr/local/src/echo-nginx-module-0.61 \
--with-google_perftools_module

make && make install

tar zxvf libunwind-1.2.tar.gz
cd libunwind-1.2
CFLAGS=-fPIC ./configure
make CFLAGS=-fPIC
make CFLAGS=-fPIC install

tar zxvf gperftools-2.7.tar.gz
cd gperftools-2.7
./configure && make && make install
ldconfig
ln -sf /usr/local/lib/libtcmalloc* /usr/lib/

/etc/sysctl.conf

  • net.ipv4.netfilter.ip_conntrack_tcp_timeout_established = 1800

  • net.ipv4.ip_conntrack_max = 16777216 # 如果使用默认参数,容易出现网络丢包

  • net.ipv4.netfilter.ip_conntrack_max = 16777216 # 设置系统对最大跟踪的TCP连接数的限制

  • net.ipv4.tcp_max_syn_backlog = 65536 #表示SYN队列长度,默认1024,65536可以容纳更多等待连接的网络连接数。

  • net.core.netdev_max_backlog = 32768 #该参数决定了,网络设备接收数据包的速率比内核处理这些包的速率快时,允许送到队列的数据包的最大数目。

  • net.core.somaxconn = 32768 #Linux kernel参数,表示socket监听的backlog(监听队列)上限

  • net.core.wmem_default = 8388608 #定义默认的发送窗口大小;对于更大的 BDP 来说,这个大小也应该更大。

  • net.core.rmem_default = 8388608 #指定了接收套接字缓冲区大小的缺省值(以字节为单位)。

  • net.core.rmem_max = 16777216 #指定了接收套接字缓冲区大小的最大值(以字节为单位)。

  • net.core.wmem_max = 16777216 #定义发送窗口的最大大小;对于更大的 BDP 来说,这个大小也应该更大。

  • net.ipv4.tcp_timestamps = 0 #关闭TCP时间戳

  • net.ipv4.tcp_synack_retries = 2

  • net.ipv4.tcp_syn_retries = 1 #在内核放弃建立连接之前发送SYN包的数量。

  • net.ipv4.tcp_tw_recycle = 1 #表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。

  • net.ipv4.tcp_tw_reuse = 1 #表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭;

  • #确定 TCP 栈应该如何反映内存使用;每个值的单位都是内存页(通常是 4KB)。

  • #第一个值是内存使用的下限。

  • #第二个值是内存压力模式开始对缓冲区使用应用压力的上限。

  • #第三个值是内存上限。在这个层次上可以将报文丢弃,从而减少对内存的使用。对于较大的 BDP 可以增大这些值(但是要记住,其单位是内存页,而不是字节)。

  • net.ipv4.tcp_mem = 94500000 915000000 927000000

  • net.ipv4.tcp_max_orphans = 3276800

  • net.ipv4.ip_local_port_range = 1024 65535 #表示用于向外连接的端口范围。缺省情况下很小:32768到61000,改为1024到65000。

  • net.core.optmem_max = 10000000 #该参数指定了每个套接字所允许的最大缓冲区的大小

  • net.ipv4.conf.all.rp_filter = 1

  • net.ipv4.conf.default.rp_filter = 1 #严谨模式 1 (推荐) #松散模式 0

  • net.ipv4.tcp_congestion_control = bic #默认推荐设置是 htcp

  • net.ipv4.tcp_window_scaling = 0 #关闭tcp_window_scaling #启用 RFC 1323 定义的 window scaling;要支持超过 64KB 的窗口,必须启用该值。

  • net.ipv4.tcp_ecn = 0 #把TCP的直接拥塞通告(tcp_ecn)关掉

  • net.ipv4.tcp_sack = 1 #关闭tcp_sack #启用有选择的应答(Selective Acknowledgment), #这可以通过有选择地应答乱序接收到的报文来提高性能(这样可以让发送者只发送丢失的报文段); #(对于广域网通信来说)这个选项应该启用,但是这会增加对 CPU 的占用。

  • net.ipv4.tcp_max_tw_buckets = 10000 #表示系统同时保持TIME_WAIT套接字的最大数量

  • net.ipv4.tcp_syncookies = 1 #表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭;

  • net.ipv4.tcp_timestamps = 1 #开启TCP时间戳 #以一种比重发超时更精确的方法(请参阅 RFC 1323)来启用对 RTT 的计算;为了实现更好的性能应该启用这个选项。

  • net.ipv4.tcp_fin_timeout = 10 #表示如果套接字由本端要求关闭,这个参数决定了它保持在FIN-WAIT-2状态的时间。

  • net.ipv4.tcp_keepalive_time = 1800 #表示当keepalive起用的时候,TCP发送keepalive消息的频度。缺省是2小时,改为30分钟。

  • net.ipv4.tcp_keepalive_probes = 3 #如果对方不予应答,探测包的发送次数

  • net.ipv4.tcp_keepalive_intvl = 15 #keepalive探测包的发送间隔

  • net.ipv4.tcp_rmem #与 tcp_wmem 类似,不过它表示的是为自动调优所使用的接收缓冲区的值。

  • net.ipv4.tcp_wmem = 30000000 30000000 30000000 #为自动调优定义每个 socket 使用的内存。 #第一个值是为 socket 的发送缓冲区分配的最少字节数。 #第二个值是默认值(该值会被 wmem_default 覆盖),缓冲区在系统负载不重的情况下可以增长到这个值。 #第三个值是发送缓冲区空间的最大字节数(该值会被 wmem_max 覆盖)。

  • net.ipv4.netfilter.ip_conntrack_max=204800 #设置系统对最大跟踪的TCP连接数的限制

  • net.ipv4.tcp_slow_start_after_idle = 0 #关闭tcp的连接传输的慢启动,即先休止一段时间,再初始化拥塞窗口。

  • net.ipv4.route.gc_timeout = 100 #路由缓存刷新频率,当一个路由失败后多长时间跳到另一个路由,默认是300。

  • net.ipv4.tcp_syn_retries = 1 #在内核放弃建立连接之前发送SYN包的数量。

  • net.ipv4.icmp_echo_ignore_broadcasts = 1 # 避免放大攻击

  • net.ipv4.icmp_ignore_bogus_error_responses = 1 # 开启恶意icmp错误消息保护

  • net.inet.udp.checksum=1 #防止不正确的udp包的攻击

  • net.ipv4.conf.default.accept_source_route = 0 #是否接受含有源路由信息的ip包。参数值为布尔值,1表示接受,0表示不接受。 #在充当网关的linux主机上缺省值为1,在一般的linux主机上缺省值为0。 #从安全性角度出发,建议你关闭该功能。

nginx.conf

user  nginx nginx;
worker_processes  1; # 一般cpu数量

#error_log  logs/error.log;
error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

pid        logs/nginx.pid;
# mkdir /tmp/tcmalloc && chown nginx:nginx /tmp/tcmalloc
google_perftools_profiles /tmp/tcmalloc; # 写在pid下面
worker_rlimit_nofile 100000; # 更改 worker 进程的最大打开文件数限制。如果没设置的话,这个值为操作系统的限制。设置后你的操作系统和 Nginx 可以处理比“ulimit -a”更多的文件,所以把这个值设高,这样 nginx 就不会有
“too many open files”问题了。


events {
    worker_connections  2048; # 一个进程能处理 1024 个请求。设置可由一个 worker 进程同时打开的最大连接数。如果设置了上面提到的worker_rlimit_nofile,我们可以将这个值设得很高。记住,最大客户数也由系统的可用 socket 连接数限制(~ 64K),所以设置不切实际的高没什么好处。
    multi_accept on; # 告诉 nginx 收到一个新连接通知后接受尽可能多的连接。
    use epoll; # 设置用于复用客户端线程的轮询方法。如果你使用 Linux 2.6+,你应该使用 epoll。如果你使用*BSD,你应该使用 kqueue。
}

stream { # tcp 端口转发
    server {
        listen  8022;
        proxy_pass  127.0.0.1:22;
        proxy_connect_timeout 1h;
        proxy_timeout 1h;
    }
}

http {
    include       mime.types;
    default_type  application/octet-stream;
    charset UTF-8;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  logs/access.log  main;
    rewrite_log on;
    open_log_file_cache max=1000 inactive=60s;
    sendfile        on; # 可以让 sendfile()发挥作用。sendfile()可以在磁盘和 TCP socket 之间互相拷贝数据(或任意两个文件描述符)。Pre-sendfile 是传送数据之前在用户空间申请数据缓冲区。之后用 read()将数据从文件拷贝到这个缓冲区,write()将缓冲区数据写入网络。sendfile()是立即将数据从磁盘读到 OS 缓存。因为这种拷贝是在内核完成的,sendfile()要比组合 read()和 write()以及打开关闭丢弃缓冲更加有效(更多有关于sendfile)
    tcp_nopush     on; # 告诉 nginx 在一个数据包里发送所有头文件,而不一个接一个的发送
    tcp_nodelay on; # 告诉 nginx 不要缓存数据,而是一段一段的发送–当需要及时发送数据时,就应该给应用设置这个属性,这样发送一小块数据信息时就不能立即得到返回值。

    keepalive_timeout  65; # 给客户端分配 keep-alive 链接超时时间。服务器将在这个超时时间过后关闭链接。我们将它设置低些可以让 ngnix 持续工作的时间更长。

    gzip  on;
    gzip_disable "msie6";  # 为指定的客户端禁用 gzip 功能。我们设置成 IE6 或者更低版本以使我们的方案能够广泛兼容。
    gzip_static on; # 告诉 nginx 在压缩资源之前,先查找是否有预先 gzip 处理过的资源。
    gzip_proxied any; #  允许或者禁止压缩基于请求和响应的响应流。我们设置为 any,意味着将会压缩所有的请求。
    gzip_min_length  1k; 设置对数据启用压缩的最少字节数。如果一个请求小于 1k,我们最好不要压缩它,因为压缩这些小的数据会降低处理此请求的所有进程的速度
    gzip_buffers     4 16k;
    gzip_http_version 1.1;
    gzip_comp_level 4; # 设置数据的压缩等级。这个等级可以是 1-9 之间的任意数值,9 是最慢但是压缩比最大的。我们设置为 4,这是一个比较折中的设置
    gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript; # 需要压缩的数据格式
    gzip_vary on;
    autoindex off;

    open_file_cache max=100000 inactive=20s;    #  打开缓存的同时也指定了缓存最大数目,以及缓存的时间。我们可以设置一个相对高的最大时间,这样我们可以在它们不活动超过 20 秒后清除掉。
    open_file_cache_valid 30s;  # 在 open_file_cache 中指定检测正确信息的间隔时间。
    open_file_cache_min_uses 2; # 定义了 open_file_cache 中指令参数不活动时间期间里最小的文件数
    open_file_cache_errors on;  # 指定了当搜索一个文件时是否缓存错误信息,也包括再次给配置中添加文件。我们也包括了服务器模块,这些是在不同文件中定义的。如果你的服务器模块不在这些位置,你就得修改这一行来指定正确的位置。

    server_tokens off; # 关闭版本显示
    
    server_names_hash_bucket_size 128;
    
    client_max_body_size 50m; # #缓冲区代理缓冲用户端请求的最大字节数,可以理解为保存到本地再传给用户
    client_body_buffer_size 256k;   # 增加缓冲区代理缓冲客户端请求的最大字节数
    client_header_timeout 3m;   # client_header_timeout 和  client_body_timeout 设置请求头和请求体(各自)的超时时间
    client_body_timeout 3m;
    reset_timeout_connection  # 告诉 nginx 关闭不响应的客户端连接。这将会释放那个客户端所占有的内存空间。
    client_header_buffer_size 32k;
    large_client_header_buffers 4 32k;
    send_timeout 3m; # 指定客户端的响应超时时间。这个设置不会用于整个转发器,而是在两次客户端读取操作之间。如果在这段时间内,客户端没有读取任何数据,nginx 就会关闭连接。

    limit_conn_zone $binary_remote_addr zone=addr:5m; # 设置用于保存各种 key(比如当前连接数)的共享内存的参数。5m 就是 5 兆字节,这个值应该被设置的足够大以存储(32K*5)32byte 状态或者(16K*5)64byte 状态
    limit_conn addr 100; # 为给定的 key 设置最大连接数。这里 key 是 addr,我们设置的值是 100,也就是说我们允许每一个 IP 地址最多同时打开有 100 个连接
    
    proxy_connect_timeout 300s; # nginx 跟后端服务器连接超时时间(代理连接超时)
    proxy_send_timeout   900;   # 增加后端服务器发送数据超时时间
    proxy_read_timeout   900;   # 连接成功后,后端服务器响应时间(代理接收超时
    proxy_buffer_size    32k;   # 增加代理请求缓存区大小
    proxy_buffers     4 32k;    # 设置代理服务器(nginx)保存用户头信息的缓冲区大小
    proxy_temp_file_write_size 64k; # 高负荷下缓冲大小(proxy_buffers*2)
    proxy_busy_buffers_size 64k;    # proxy_buffers 缓冲区,网页平均在 32k 以下的话,这样设置
    proxy_ignore_client_abort on;   #设定缓存文件夹大小,大于这个值,将从 upstream 服务器传递请求,而不缓冲到磁盘
    proxy_redirect     off;
    proxy_set_header   Host $host;
    proxy_hide_header  Vary;
    proxy_set_header   Accept-Encoding '';
    proxy_set_header   Host   $http_host;
    proxy_set_header   Referer $http_referer;
    proxy_set_header   Cookie $http_cookie;
    proxy_set_header   X-Real-IP  $remote_addr;
    proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header   X-Forwarded-Proto $scheme;
    
    proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_404;   #增加故障转移,如果后端的服务器返回502、504、执行超时等错误,自动将请求转发到upstream负载均衡池中的另一台服务器,实现故障转移。

    server {
        listen       80;
        server_name  localhost;

        charset utf-8;

        access_log  logs/host.access.log  main;

        location / {
            echo    "/";
            #root   html;
            #index  index.html index.htm;
        }
        location =/ { # http://192.168.213.130/
            echo    "=/";
        }
        location =/nginx { # http://192.168.213.130/nginx
            echo    "=/nginx";
        }
        location ~ \.(gif|jpg|png|js|css) {
            echo    "some gif jpg png";
        }
        location ~* \.png$ { # http://192.168.213.130/xxx/123.PNG, 注意是大写
            echo    "all-png";
        }
        location ^~ /static/ { # http://192.168.213.130/static/123.png
            echo    "static";
        }
        location ~* .*\.(js|css)?$ {
            expires 7d; # 7天过期
            access_log off; # 不保存日志
        }
        location ~* .*\.(png|jpg|jpeg|ico)?$ {
            expires 7d;
            access_log off; # 不保存日志
        }
        location ~* .*\.(zip|rar|exe|msi)?$ {
            deny all; # 禁止这些文件下载
        }
        location ~ ^/html { # http://192.168.213.130/html/index.html   访问路径 /usr/local/nginx/html/html/index.html
            root html;
            autoindex on;
        }
        location ^~ /htmlalias { # alias 与 root 的区别是,root会带路径,alias不会
            alias htmlalias/; # 使用alias 后面一定要加 /, 只能位于 location 下
        }

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        #    proxy_pass   http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        #location ~ \.php$ {
        #    root           html;
        #    fastcgi_pass   127.0.0.1:9000;
        #    fastcgi_index  index.php;
        #    fastcgi_param  SCRIPT_FILENAME  /scripts$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;
        #}
    }


    # another virtual host using mix of IP-, name-, and port-based configuration
    #
    #server {
    #    listen       8000;
    #    listen       somename:8080;
    #    server_name  somename  alias  another.alias;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}


    # HTTPS server
    #
    #server {
    #    listen       443 ssl;
    #    server_name  localhost;

    #    ssl_certificate      cert.pem;
    #    ssl_certificate_key  cert.key;

    #    ssl_session_cache    shared:SSL:1m;
    #    ssl_session_timeout  5m;

    #    ssl_ciphers  HIGH:!aNULL:!MD5;
    #    ssl_prefer_server_ciphers  on;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}

}

nginx 变量参数

http://192.168.213.130/index.html?site=liuhonghe.me
  • $arg_PARAMETER => liuhonghe.me
  • $args => site=liuhonghe.me&width=400&height=200
  • $binary_remote_addr 二进制格式的客户端地址。例如:\x0A\xE0B\x0E
  • $body_bytes_sent 表示在向客户端发送的 http 响应中,包体部分的字节数
  • $content_length 表示客户端请求头部中的 Content-Length 字段
  • $content_type 表示客户端请求头部中的 Content-Type 字段
  • $cookie_COOKIE 表示在客户端请求头部中的 cookie 字段
  • $document_root =>/usr/local/nginx/html
  • $uri => /index.html
  • $document_uri 与$uri 含义相同
  • $request_uri =>/index.html?site=liuhonghe.me&width=400&height=200 ,表示客户端发来的原始请求 URI,带完整的参数。$uri 和$document_uri 未必是用户的原始请求,在内部重定向后可能是重定向后的 URI,而$request_uri 永远不会改变,始终是客户端的原始 URI.
  • $host => 192.168.213.130, 表示客户端请求头部中的 Host 字段。如果 Host 字段不存在,则以实际处理的 server(虚拟主机)名称代替。如果 Host 字段中带有端口,如 IP:PORT,那么$host 是去掉端口的,它的值为 IP。$host是全小写的。这些特性与 http_HEADER 中的 http_host 不同,http_host 只取出 Host 头部对应的值。
  • $hostname => ubuntu, 表示 Nginx 所在机器的名称,与 gethostbyname 调用返回的值相同
  • $http_HEADER 表示当前 HTTP 请求中相应头部的值。HEADER 名称全小写。例如,示请求中 Host 头部对应的值 用 $http_host 表
  • $sent_http_HEADER 表示返回客户端的 HTTP 响应中相应头部的值。HEADER 名称全小写。例如,用 $sent_http_content_type 表示响应中 Content-Type 头部对应的值
  • $is_args =>?, 表示请求中的 URI 是否带参数,如果带参数,$is_args 值为 ?,如果不带参数,则是空字符串
  • $limit_rate =>0, 表示当前连接的限速是多少,0 表示无限速
  • $nginx_version => 1.14.0, 表示当前 Nginx 的版本号
  • $query_string =>site=liuhonghe.me&width=400&height=200, 请求 URI 中的参数,与 $args 相同,然而 $query_string 是只读的不会改变

nginx log 参数

  • $remote_addr => 192.168.213.1, 表示客户端的地址, 我这个是虚拟机网关
  • $remote_port => 54234, 表示客户端连接使用的端口
  • $remote_user 表示使用 Auth Basic Module 时定义的用户名
  • $request_filename => /usr/local/nginx/html/index.html, 表示用户请求中的 URI 经过 root 或 alias 转换后的文件路径
  • $request_body 表示 HTTP 请求中的包体,该参数只在 proxy_pass 或 fastcgi_pass 中有意义
  • $request_body_file 表示 HTTP 请求中的包体存储的临时文件名
  • $request_completion 当请求已经全部完成时,其值为 “ok”。若没有完成,就要返回客户端,则其值为空字符串;或者在断点续传等情况下使用 HTTP range 访问的并不是文件的最后一块,那么其值也是空字符串。
  • $request_method => GET,表示 HTTP 请求的方法名,如 GET、PUT、POST 等
  • $scheme => http, 表示 HTTP scheme,如在请求 https://nginx.com/中表示 https
  • $server_addr => 192.168.213.130,表示服务器地址
  • $server_name => localhost ,表示服务器名称
  • $server_port => 80, 表示服务器端口
  • $server_protocol => HTTP/1.1, 表示服务器向客户端发送响应的协议,如 HTTP/1.1 或 HTTP/1.0
  • $remote_addr, $http_x_forwarded_for 记录客户端 IP 地址
  • $remote_user 记录客户端用户名称
  • $request 记录请求的 URL 和 HTTP 协议
  • $status 记录请求状态
  • $body_bytes_sent 发送给客户端的字节数,不包括响应头的大小; 该变量与 Apache 模块 mod_log_config 里的 "%B"参数兼容。
  • $bytes_sent 发送给客户端的总字节数。
  • $connection 连接的序列号。
  • $connection_requests 当前通过一个连接获得的请求数量。
  • $msec 日志写入时间。单位为秒,精度是毫秒。
  • $pipe 如果请求是通过 HTTP 流水线(pipelined)发送,pipe 值为“p”,否则为“.”。
  • $http_referer 记录从哪个页面链接访问过来的
  • $http_user_agent 记录客户端浏览器相关信息
  • $request_length 请求的长度(包括请求行,请求头和请求正文)。
  • $request_time 请求处理时间,单位为秒,精度毫秒; 从读入客户端的第一个字节开始,直到把最后一个字符发送给客户端后进行日志写入为止。
  • $time_iso8601 ISO8601 标准格式下的本地时间。
  • $time_local 通用日志格式下的本地时间。

open_log_file_cache 指令

语法: open_log_file_cache max=N [inactive=time] [min_uses=N] [valid=time];
open_log_file_cache off;
默认值: open_log_file_cache off;
配置段: http, server, location
对于每一条日志记录,都将是先打开文件,再写入日志,然后关闭。可以使用 open_log_file_cache 来设置日志
文件缓存(默认是 off),格式如下:
参数注释如下:
max:设置缓存中的最大文件描述符数量,如果缓存被占满,采用 LRU 算法将描述符关闭。
inactive:设置存活时间,默认是 10s
min_uses:设置在 inactive 时间段内,日志文件最少使用多少次后,该日志文件描述符记入缓存中,默认是 1 次
valid:设置检查频率,默认 60s
off:禁用缓存
实例如下:
open_log_file_cache max=1000 inactive=20s valid=1m min_uses=2;

rewrite log

语法: rewrite_log on | off;
默认值: rewrite_log off;
配置段: http, server, location, if
启用时将在 error log 中记录 notice 级别的重写日志。

rewrite 模块指令

break

语法:break
默认值:none
使用字段:server, location, if
完成当前设置的重写规则,停止执行其他的重写规则。

if

语法:if (condition) { … }
默认值:none
使用字段:server, location
注意:尽量考虑使用 trp_files 代替。

判断的条件可以有以下值:

  1. 一个变量的名称:空字符传""或者一些"0"开始的字符串为 false。
  2. 字符串比较:使用=或!=运算符
  3. 正则表达式匹配:使用~(区分大小写)和~(不区分大小写),取反运算!~和!~
  4. 文件是否存在:使用-f 和!-f 操作符
  5. 目录是否存在:使用-d 和!-d 操作符
  6. 文件、目录、符号链接是否存在:使用-e 和!-e 操作符
  7. 文件是否可执行:使用-x 和!-x 操作符

return

停止处理并为客户端返回状态码。非标准的 444 状态码将关闭连接,不发送任何响应头。可以使用的状态码有:
204,400,402-406,408,410, 411, 413, 416 与 500-504。如果状态码附带文字段落,该文本将被放置在响应
主体。相反,如果状态码后面是一个 URL,该 URL 将成为 location 头补值。没有状态码的 URL 将被视为一个 302
状态码。

语法:return code
默认值:none
使用字段:server, location, if

rewrite

语法:rewrite regex replacement flag
默认值:none
使用字段:server, location, if
按照相关的正则表达式与字符串修改 URI,指令按照在配置文件中出现的顺序执行。可以在重写指令后面添加标
记。
注意:如果替换的字符串以 http://开头,请求将被重定向,并且不再执行多余的 rewrite 指令。
尾部的标记(flag)可以是以下的值:
last – 停止处理重写模块指令,之后搜索 location 与更改后的 URI 匹配。
break – 完成重写指令。
redirect – 返回 302 临时重定向,如果替换字段用 http://开头则被使用。
permanent – 返回 301 永久重定向。

set

语法:set variable value
默认值:none
使用字段:server, location, if
为给定的变量设置一个特定值。
uninitialized_variable_warn
语法:uninitialized_variable_warn on|off
默认值:uninitialized_variable_warn on
使用字段:http, server, location, if
控制是否记录未初始化变量的警告信息。

重写规则组成部分

任何重写规则的第一部分都是一个正则表达式

^/images/([a-z]{2})/([a-z0-9]{5})/(.*)\.(png|jpg|gif)$
  • $1 是两个小写字母组成的字符串
  • $2 是由小写字母和 0 到 9 的数字组成的 5 个字符的字符串
  • $3 将是个文件名,
  • $4 是 png、jpg、gif 中的其中一个

重写规则的第二部分是 URI

请求被改写。该 URI 可能包含正则表达式中的捕获的位置参数或这个级别下的 nginx 任何配置变量。如:

/data?file=$3.$4

如果这个 URI 不匹配 nginx 配置的任何 location,那么将给客户端返回 301(永久重定向)或 302(临时重定向)的状态码来表示重定向类型。该状态码可以通过第三个参数来明确指定。

重写规则的第三部分

第三部分也就是尾部的标记(flag)。 last 标记将导致重写后的 URI 搜索匹配 nginx 的其他 location,最多可循
环 10 次。如:

rewrite '^/images/([a-z]{2})/([a-z0-9]{5})/(.*)\.(png|jpg|gif)$' /data?file=$3.$4 last;

break 指令可以当做自身指令。如:

if ($bwhog) {
limit_rate 300k;
break;
}

另一个停止重写模块处理指令是 return, 来控制主 HTTP 模块处理请求。 这意味着,nginx 直接返回信息给客户端,与 error_page 结合为客户端呈现格式化的 HTML 页面或激活不同的模块来完成请求。如果状态码附带文字段落,该文本将被放置在响应主体。相反,如果状态码后面是一个 URL,该 URL 将成为 location 头补值。没有状态码的 URL 将被视为一个 302 状态码。如:

location = /image404.html {
return 404 "image not found\n";
}

例子

http {
    # 定义 image 日志格式
    log_format imagelog '[$time_local] ' $image_file ' ' $image_type ' ' $body_bytes_sent ' ' $status;
    # 开启重写日志
    rewrite_log on;
    server {
        root /home/www;
        location / {
        # 重写规则信息
        error_log logs/rewrite.log notice;
        # 注意这里要用‘’单引号引起来,避免{}
        rewrite '^/images/([a-z]{2})/([a-z0-9]{5})/(.*)\.(png|jpg|gif)$' /data?file=$3.$4;
        # 注意不能在上面这条规则后面加上“last”参数,否则下面的 set 指令不会执行
        set $image_file $3;
        set $image_type $4;
    }
    location /data {
        # 指定针对图片的日志格式,来分析图片类型和大小
        access_log logs/images.log mian;
        root /data/images;
        # 应用前面定义的变量。判断首先文件在不在,不在再判断目录在不在,如果还不在就跳转到最后一个 url 里
        try_files /$arg_file /image404.html;
    }
    location = /image404.html {
        # 图片不存在返回特定的信息
        return 404 "image not found\n";
    }
}

创建新的重新规则

例子1

要将 home 目录重定向到主页面上,目录结构如下:

/
/home
/home/
/home/index
/home/index/
/index
/index.php
/index.php/

重写规则如下:

rewrite ^/(home(/index)?|index(\.php)?)/?$ $scheme://$host/ permanent;

指定$scheme 和$host 变量,因为要做一个永久重定向并希望 nginx 使用相同的参数来构造 URL

实例2

当重写规则导致内部重定向或指示客户端调用该规则本身被定义的 location 时,必须采取特殊的动作来
避免重写循环。如:在 server 配置段定义了一条规则带上 last 标志,在引用 location 时,必须使用 break 标

server {
    rewrite ^(/images)/(.*)\.(png|jpg|gif)$ $1/$3/$2.$3 last;
        location /images/ {
        rewrite ^(/images)/(.*)\.(png|jpg|gif)$ $1/$3/$2.$3 break;
    }
}

实例3

作为重写规则的一部分,传递新的查询字符串参数是使用重写规则的目标之一

rewrite ^/images/(.*)_(\d+)x(\d+)\.(png|jpg|gif)$ /resizer/$1.$4?width=$2&height=$3? last;

nginx 重写规则说起来挺简单的,做起来就难,重点在于正则表达式,同时,还需要考虑到 nginx 执行顺序。

nginx 逻辑运算

nginx 的配置中不支持 if 条件的逻辑与&& 逻辑或|| 运算 ,而且不支持 if 的嵌套语法,只能单条件

set $flag 0;
if ($uri ~ ^/thumb/[0-9]+_160.jpg$){
set $flag "${flag}1";
}
if ($arg_unitid = 42012){
set $flag "${flag}1";
}
if ($flag = "011"){
echo "www.ttlsa.com";
}

配置 proxy_cache

mkdir -p  /home/proxy_temp_dir     #proxy_temp_dir与proxy_cache_dir这两个文件夹必须在同一个分区
mkdir -p  /home/proxy_cache_dir    #proxy_cache_dir与proxy_temp_dir这两个文件夹必须在同一个分区
chown www.www -R  proxy_cache_dir  proxy_temp_dir  #设置目录所有者
chmod -R 777  proxy_cache_dir  proxy_temp_dir    #设置目录权限

在 http 范围增加

proxy_temp_path   /home/proxy_temp_dir;   #指定临时文件目录
proxy_cache_path  /home/proxy_cache_dir levels=1:2 keys_zone=cache_one:50m inactive=1d max_size=1g;
#设置Web缓存区名称为cache_one,内存缓存为50MB,自动清除1天内没有被访问的文件,硬盘缓存为1GB。
proxy_cache cache_one;

server

 location /    
 {    
 proxy_cache cache_one; //根keys_zone后的内容对应    
 proxy_cache_valid  200 304 301 302 10d;   //哪些状态缓存多长时间    
 proxy_cache_valid  any 1d;    //其他的缓存多长时间    
 proxy_cache_key $host$uri$is_args$args;   //通过key来hash,定义KEY的值    
    
 proxy_pass http://myselfxtajmd;    
 proxy_redirect                      off;    
 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 ~ .*\.(php|jsp|cgi)?$    
 {    
 proxy_set_header Host  $host;    
 proxy_set_header X-Forwarded-For  $remote_addr;    
 proxy_pass http://myselfxtajmd;    
 }  
# 正常访问 http://liuhonghe.me/images/123.png
# 清楚缓存 http://liuhonghe.me/purge/images/123.png
location ~ /purge(/.*)   #用于清除缓存 ,最好放在最前面
{
allow            127.0.0.1;
allow            192.168.21.0/24;   #设置只允许指定的IP或IP段才可以清除URL缓存。
deny            all;
proxy_cache_purge    cache_one   $host$1$is_args$args;
}
» 转载请注明来源:若我若鱼 » nginx 详解

Leave a Reply

Your email address will not be published. Required fields are marked *

3 × one =