• Nginx学习之Nginx配置


      Nginx可以用来提供静态资源服务(静态资源文件访问)、反向代理服务(请求转发、负载等)、API服务,可以通过配置文件进行配置来实现Nginx的能力,因此本篇就进行配置文件的详述来进行Nginx使用实践。

    1、Nginx配置概述

      1.1、配置文件结构

      Nginx配置文件结构目录如下图所示:

      

      具体模块功能分工如下:

    • 全局块

      该部分配置主要影响Nginx全局,通常包括下面几个部分:配置运行Nginx服务器用户(组)、worker process数、Nginx进程PID存放路径、错误日志的存放路径配置文件的引入。

    • events块

      该部分配置主要影响Nginx服务器与用户的网络连接,主要包括:设置网络连接的序列化、是否允许同时接收多个网络连接、事件驱动模型的选择、最大连接数的配置。

    • http块

      定义MIMI-Type自定义服务日志、允许sendfile方式、传输文件连接超时时间、单连接请求数上限。

    • server块

      配置网络监听基于名称的虚拟主机配置、基于IP的虚拟主机配置。

    • location块

      location配置请求根目录配置、更改location的URI、网站默认首页配置。

      1.2、配置文件语法

      Nginx的配置语法如下:

    • 配置文件由指令与指令块构成,每条指令以;结尾,
    • 指令与参数间以空格符号分割
    • 指令块以{}大括号将多条指令组织在一起
    • include语句允许组合多个配置文件以提升可维护性
    • 使用#符号添加注释,提供可读性
    • 使用$符号使用变量
    • 部分指令的参数支持正则表达式

      如示例:

       

    2、Nginx详细配置

      2.1、Nginx全局块配置

      配置示例:

    user  nobody nobody;
    worker_processes  3;
    
    error_log  logs/error.log;
    error_log  logs/error.log  notice;
    error_log  logs/error.log  info;
    
    pid        logs/nginx.pid;
    worker_rlimit_nofile 65535;

      2.1.1、配置运行Nginx服务器用户(组)

      指令格式:user user [group];

      user:指定可以运行Nginx服务器的用户

      group:可选项,可以运行Nginx服务器的用户组。

      如果user指令不配置或者配置为user nobody nobody,则默认所有用户都可以启动Nginx进程(window下不指定)。

      2.1.2、worker process数配置

      Nginx服务器实现并发处理服务的关键,指令格式:worker_processes number | auto;

      number:Nginx进程最多可以产生的worker process数。

      auto:Nginx进程将自动检测并设定worker process数。

      worker_processes设置为多少,Nginx的主进程就会创建多少个worker_processes子进程,根据硬件调整,通常worker_process数等于CPU数量或者2倍于CPU。

      2.1.3、Nginx进程PID存放路径

      Nginx进程是作为系统守护进程在运行,需要在某文件中保存当前运行程序的主进程号,Nginx支持该保存文件路径的自定义。

      指令格式:pid file;

      file:指定存放路径和文件名称如果不指定默认置于路径 logs/nginx.pid。

      2.1.4、错误日志的存放路径

      指定格式:error_log file | stderr;

      file:日志输出到某个文件。

      filestderr:日志输出到标准错误输出。

      这个设置可以放入全局块,http块,server块,级别以此为:debug|info|notice|warn|error|crit|alert|emerg。

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

      2.1.5、指定指定进程可以打开的最大描述符

    worker_rlimit_nofile 65535;

      这个指令是指当一个nginx进程打开的最多文件描述符数目,理论值应该是最多打开文件数(ulimit -n)与nginx进程数相除,但是nginx分配请求并不是那么均匀,所以最好与ulimit -n 的值保持一致。

      现在在linux 2.6内核下开启文件打开数为65535,worker_rlimit_nofile就相应应该填写65535。这是因为nginx调度时分配请求到进程并不是那么的均衡,所以假如填写10240,总并发量达到3-4万时就有进程可能超过10240了,这时会返回502错误。

      2.2、events模块配置

      配置示例:

    use epoll;
    accept_mutex on;
    multi_accept on;
    worker_connections  1024;
    keepalive_timeout 60;
    client_header_buffer_size 4k;  
    open_file_cache max=65535 inactive=60s;   
    open_file_cache_valid 80s;
    open_file_cache_min_uses 1;

      2.2.1、指定事件模型

    use epoll;

      使用epoll的I/O 模型。linux建议epoll,FreeBSD建议采用kqueue,window下不指定。

    补充说明:与apache相类,nginx针对不同的操作系统,有不同的事件模型。

    A)标准事件模型

      Select、poll属于标准事件模型,如果当前系统不存在更有效的方法,nginx会选择select或poll。

    B)高效事件模型

      Kqueue:适用于FreeBSD 4.1+, OpenBSD 2.9+, NetBSD 2.0 和 MacOS X。使用双处理器的MacOS X系统使用kqueue可能会造成内核崩溃。

      Epoll:适用于Linux内核2.6版本及以后的系统。

      /dev/poll:适用于Solaris 7 11/99+,HP/UX 11.22+ (eventport),IRIX 6.5.15+ 和 Tru64 UNIX 5.1A+。

      Eventport:适用于Solaris 10。 为了防止出现内核崩溃的问题, 有必要安装安全补丁。

      2.2.2、设置网络连接的序列化

      指令格式:accept_mutex on | off;

      该指令默认为on状态,但在1.11.3的后续版本中默认为off。表示会对多个Nginx进程接收连接进行序列化,防止多个进程对连接的争抢。也就是防止“惊群现象”发生,就Nginx的场景来解释的话大致的意思就是:当一个新网络连接来到时,多个worker进程会被同时唤醒,但仅仅只有一个进程可以真正获得连接并处理之。如果每次唤醒的进程数目过多的话,其实是会影响一部分性能的。

      所以在这里,如果accept_mutex on,那么多个worker将是以串行方式来处理,其中有一个worker会被唤醒;反之若accept_mutex off,那么所有的worker都会被唤醒,不过只有一个worker能获取新连接,其它的worker会重新进入休眠状态。

    Changes with nginx 1.11.3                                        26 Jul 2016
        *) Change: now the "accept_mutex" directive is turned off by default.

      这个值的开关与否其实是要和具体场景挂钩的。 

      2.2.3、是否允许同时接收多个网络连接

      指令格式:multi_accept on | off;

      该指令默认为off状态,意指每个worker process 一次只能接收一个新到达的网络连接。若想让每个Nginx的worker process都有能力同时接收多个网络连接,则需要开启此配置。

      2.2.4、工作进程的最大连接数量

    worker_connections 512;

      每个工作进程的最大连接数量。根据硬件调整,和前面工作进程配合起来用,尽量大,但是别把cpu跑到100%就行。每个进程允许的最多连接数,默认512,理论上每台nginx服务器的最大连接数为:worker_processes*worker_connections。

      2.2.5、其余配置

    keepalive_timeout 60;  #keepalive超时时间。
    #客户端请求头部的缓冲区大小。这个可以根据你的系统分页大小来设置,一般一个请求头的大小不会超过1k,不过由于一般系统分页都要大于1k,所以这里设置为分页大小。
    #分页大小可以用命令getconf PAGESIZE 取得。但也有client_header_buffer_size超过4k的情况,但是client_header_buffer_size该值必须设置为“系统分页大小”的整倍数。 client_header_buffer_size 4k;   #这个将为打开文件指定缓存,默认是没有启用的,max指定缓存数量,建议和打开文件数一致,inactive是指经过多长时间文件没被请求后删除缓存。 open_file_cache max=65535 inactive=60s; #这个是指多长时间检查一次缓存的有效信息。 open_file_cache_valid 80s; #open_file_cache指令中的inactive参数时间内文件的最少使用次数,如果超过这个数字,文件描述符一直是在缓存中打开的,如下例,如果有一个文件在inactive时间内一次没被使用,它将被移除。 open_file_cache_min_uses 1;

      2.3、HTTP全局配置模块

      2.3.1、定义MIME-Type

    #设定mime类型,类型由mime.type文件定义
    include       mime.types;
    #指定默认文件类型,默认为text/plain。MIME-Type指的是网络资源的媒体类型,也即前端请求的资源类型include指令将mime.types文件包含进来
    default_type  application/octet-stream;

      我们通过cat mime.types来查看mime.types文件内容,我们发现其就是一个types结构,里面包含了各种浏览器能够识别的MIME类型以及对应类型的文件后缀名字,如下所示:

      

      2.3.2、自定义服务日志

      指令格式:access_log path [format],适用于HTTP全局模块、Server全局模块。

      path:自定义服务日志的路径 + 名称

      format:可选项,自定义服务日志的字符串格式。

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    log_format  log404 '$status [$time_local] $remote_addr $host$request_uri $sent_http_location';
    
    #用了log_format指令设置了日志格式之后,需要用access_log指令指定日志文件的存放路径; access_log logs/access.log main; access_log logs/host.access.404.log log404;

      日志格式如下所示:

    $remote_addr与$http_x_forwarded_for用以记录客户端的ip地址;
    $remote_user:用来记录客户端用户名称;
    $time_local: 用来记录访问时间与时区;
    $request: 用来记录请求的url与http协议;
    $status: 用来记录请求状态;成功是200,
    $body_bytes_sent :记录发送给客户端文件主体内容大小;
    $http_referer:用来记录从那个页面链接访问过来的;
    $http_user_agent:记录客户浏览器的相关信息;

      注意:通常web服务器放在反向代理的后面,这样就不能获取到客户的IP地址了,通过$remote_add拿到的IP地址是反向代理服务器的iP地址。反向代理服务器在转发请求的http头信息中,可以增加x_forwarded_for信息,用以记录原有客户端的IP地址和原来客户端的请求的服务器地址。

      2.3.3、缓存配置

      open_file_cache max指令指定缓存是否启用,可以适用于在HTTP全局模块、server全局模块以及location模块进行使用,如下所示:

    # 这个将为打开文件指定缓存,默认是没有启用的,max指定缓存数量,建议和打开文件数一致,inactive是指经过多长时间文件没被请求后删除缓存。
    open_file_cache max=65535 inactive=60s;
    
    # 语法:open_file_cache_errors on | off ,默认值:off
    # 配置适用模块:http, server, location,这个指令指定是否在搜索一个文件是记录cache错误。
    open_file_cache_errors on
    
    #语法:open_file_cache_min_uses number 默认值:1 
    # 配置适用模块:http, server, location,这个指令指定了在open_file_cache指令无效的参数中一定的时间范围内可以使用的最小文件数,如果使用更大的值,文件描述符在cache中总是打开状态.
    open_file_cache_min_uses 2
    
    # 语法:open_file_cache_valid time 默认值:60 
    # 配置适用模块:http, server, location 这个指令指定了何时需要检查open_file_cache中缓存项目的有效信息.
    open_file_cache_valid 30s

      2.3.4、允许sendfile方式传输文件

      sendfile参数用于开启高效文件传输模式,也就是基于IO的零拷贝技术,其配置说明如下:

    # sendfile指令指定nginx是否调用sendfile函数(zero copy方式)来输出文件,对于普通应用,必须设为on。
    # 如果用来进行下载等应用磁盘IO重负载应用,可设置为off,以平衡磁盘与网络IO处理速度,降低系统uptime。
    # 默认为off,可以在http块,server块,location块。
    sendfile on | off;  
    # size>0,则Nginx进程的每个worker process每次调用sendfile()传输的数据了最大不能超出此值;若size=0则表示不限制。默认值为0
    sendfile_max_chunk size;  #如100K
    # 在FreeBSD上使用TCP_NOPUSH套接字选项, 在Linux上使用TCP_CORK套接字选项。 在Linux和FreeBSD 4.*上将响应头和正文的开始部分一起发送;此选项仅在使用sendfile的时候使用。
    tcp_nopush on;
    #  这个选项仅在将连接转变为长连接的时候才被启用。将tcp_nopush和tcp_nodelay两个指令设置为on用于防止网络阻塞;
    tcp_nodelay on;

      2.3.5、HttpGzip模块配置

      gzip模块支持在线实时压缩输出数据流,浏览器请求会告诉服务端当前浏览器支持的压缩类型,服务端会将数据根据浏览器支持的压缩类型进行压缩返回。浏览器请求时会附带支持的压缩类型,如下图所示:

      

      配置示例及含义如下:

    # 用于设置开启或者关闭gzip模块,“gzip on”表示开启GZIP压缩,实时压缩输出数据流;
    gzip on;
    # 设置允许压缩的页面最小字节数,页面字节数从header头的Content-Length中获取。默认值是0,不管页面多大都进行压缩。建议设置成大于1K的字节数,小于1K可能会越压越大;
    gzip_min_length 1K
    # 表示申请4个单位为16K的内存作为压缩结果流缓存,默认值是申请与原始数据大小相同的内存空间来存储gzip压缩结果;
    gzip_buffers 4 16k;
    # 用于设置识别HTTP协议版本,默认是1.1,目前大部分浏览器已经支持GZIP解压,使用默认即可;
    gzip_http_version 1.1;
    # 用来指定GZIP压缩比(1~9),1 压缩比最小,处理速度最快;9 压缩比最大,传输速度快,但处理最慢,也比较消耗cpu资源;
    gzip_comp_level 2;
    # 用来指定压缩的类型,无论是否指定,“text/html”类型总是会被压缩的;
    gzip_types text/plain application/json application/x-javascript application/css application/xml application/xml+rss 
        text/javascript application/x-httpd-php image/jpeg image/gif image/png image/x-ms-bmp;
    # 选项可以让前端的缓存服务器缓存经过GZIP压缩的页面,例如用Squid缓存经过Nginx压缩的数据。
    gzip_vary on;

      效果如下所示(原始文件+效果):

      

      

      2.3.6、负载均衡配置

      upstream是Nginx的HTTP Upstream模块,这个模块通过一个简单的调度算法来实现客户端IP到后端服务器的负载均衡。upstream常见参数如下:

    service:反向服务地址 加端口。
    weight:权重。
    max_fails:允许请求失败的次数,默认为1。当超过最大次数时,返回proxy_next_upstream 模块定义的错误;并认为主机已挂掉则,踢出。
    fail_timeout:踢出后重新探测时间,也就是在经历了max_fails次失败后,暂停服务的时间。max_fails可以和fail_timeout一起使用。
    down:表示当前的server暂时不参与负载均衡;
    backup:预留的备份机器。当其他所有的非backup机器出现故障或者忙的时候,才会请求backup机器,因此这台机器的压力最轻;
    max_conns:允许最大连接数。
    slow_start:当节点恢复,不立即加入,而是等待 slow_start 后加入服务对列。

      注意:当负载调度算法为ip_hash时,后端服务器在负载均衡调度中的状态不能是weight和backup。

      upstream支持以下几种负载均衡算法,配置如下所示:

    • 轮询(默认)

      每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。

    upstream backserver {
      server 192.168.0.14;
      server 192.168.0.15;
    }
    • 指定权重

      指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。

    upstream backserver {
      server 192.168.0.14 weight=8;
      server 192.168.0.15 weight=10;
    }
    • ip_hash(IP绑定)

      每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决分布式session的问题。

    upstream backserver {
      ip_hash;
      server 192.168.0.14:8888;
      server 192.168.0.15:8080;
    }
    • least_conn最少连接优先

      把请求转发给连接数较少的后端服务器。轮询算法是把请求平均的转发给各个后端,使它们的负载大致相同;但是有些请求占用的时间很长,会导致其所在的后端负载较高。这种情况下,least_conn这种方式就可以达到更好的负载均衡效果。

    upstream backserver {
        least_conn; #把请求转发给连接数较少的后端服务器
        server localhost:8080 weight=2;
        server localhost:8081;
        server localhost:8082 backup;
        server localhost:8083 max_fails=3 fail_timeout=20s;
    }
    • fair(第三方)

      按后端服务器的响应时间来分配请求,响应时间短的优先分配。

    upstream backserver {
        server server1;
        server server2;
        fair;
    }
    • url_hash(第三方)

      按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存时比较有效。

    upstream backserver {
      server squid1:3128;
      server squid2:3128;
      hash $request_uri;
      hash_method crc32;
    }

      2.3.7、其他配置文件

    server_names_hash_bucket_size 128;
    # 保存服务器名字的hash表是由指令server_names_hash_max_size 和server_names_hash_bucket_size所控制的。
    # 参数hash bucket size总是等于hash表的大小,并且是一路处理器缓存大小的倍数。在减少了在内存中的存取次数后,使在处理器中加速查找hash表键值成为可能。
    # 如果hash bucket size等于一路处理器缓存的大小,那么在查找键的时候,最坏的情况下在内存中查找的次数为2。
    # 第一次是确定存储单元的地址,第二次是在存储单元中查找键 值。因此,如果Nginx给出需要增大hash max size 或 hash bucket size的提示,那么首要的是增大前一个参数的大小。 client_header_buffer_size 4k; # 客户端请求头部的缓冲区大小。这个可以根据你的系统分页大小来设置,一般一个请求的头部大小不会超过1k,不过由于一般系统分页都要大于1k,所以这里设置为分页大小。
    # 分页大小可以用命令getconf PAGESIZE取得。 large_client_header_buffers 
    8 128k; # 客户请求头缓冲大小。nginx默认会用client_header_buffer_size这个buffer来读取header值,如果header过大,它会使用large_client_header_buffers来读取。 client_max_body_size 300m; # 设定通过nginx上传文件的大小。 proxy_connect_timeout 90#后端服务器连接的超时时间_发起握手等候响应超时时间。 proxy_read_timeout 180; # 连接成功后_等候后端服务器响应时间_其实已经进入后端的排队之中等候处理(也可以说是后端服务器处理请求的时间)。 proxy_send_timeout 180; # 后端服务器数据回传时间_就是在规定时间之内后端服务器必须传完所有的数据。 proxy_buffer_size 256k; # 设置从被代理服务器读取的第一部分应答的缓冲区大小,通常情况下这部分应答中包含一个小的应答头。
    # 默认情况下这个值的大小为指令proxy_buffers中指定的一个缓冲区的大小,不过可以将其设置为更小。 proxy_buffers 
    4 256k; # 设置用于读取应答(来自被代理服务器)的缓冲区数目和大小,默认情况也为分页大小,根据操作系统的不同可能是4k或者8k proxy_busy_buffers_size 256k; proxy_temp_file_write_size 256k; # 设置在写入proxy_temp_path时数据的大小,预防一个工作进程在传递文件时阻塞太长 proxy_temp_path /data0/proxy_temp_dir; # proxy_temp_path和proxy_cache_path指定的路径必须在同一分区 proxy_cache_path /data0/proxy_cache_dir levels=1:2 keys_zone=cache_one:200m inactive=1d max_size=30g; # 设置内存缓存空间大小为200MB,1天没有被访问的内容自动清除,硬盘缓存空间大小为30GB。 keepalive_timeout 120; # keepalive超时时间。 client_body_buffer_size 512k; # 如果把它设置为比较大的数值,例如256k,那么,无论使用firefox还是IE浏览器,来提交任意小于256k的图片,都很正常。
    # 如果注释该指令,使用默认的client_body_buffer_size设置,也就是操作系统页面大小的两倍,8k或者16k,问题就出现了。
    # 无论使用firefox4.0还是IE8.
    0,提交一个比较大,200k左右的图片,都返回500 Internal Server Error错误 proxy_intercept_errors on; # 表示使nginx阻止HTTP应答代码为400或者更高的应答。

      2.4、Server全局模块

    listen 80;
    # listen用于指定虚拟主机的服务端口。
    server_name 192.168.8.18 cszhi.com;
    # server_name用来指定IP地址或者域名,多个域名之间用空格分开。
    index index.html index.htm index.php;
    # index用于设定访问的默认首页地址。
    root /wwwroot/www.cszhi.com
    # root指令用于指定虚拟主机的网页根目录,这个目录可以是相对路径,也可以是绝对路径。
    charset gb2312;
    # Charset用于设置网页的默认编码格式。
    access_log logs/www.ixdba.net.access.log main;
    # access_log用来指定此虚拟主机的访问日志存放路径,最后的main用于指定访问日志的输出格式。
    error_page 404 /404.html;
    error_page 500 502 503 504 /50x.html;
    # 错误页,如果返回对应错误码则跳到对应错误页面

      2.5、location模块

      2.5.1、location模块语法

      location URL配置块位于Server模块之内,URL地址匹配是进行Nginx配置中最灵活的部分。 location支持正则表达式匹配,也支持条件判断匹配,用户可以通过location指令实现Nginx对动、静态网页进行过滤处理。使用location URL匹配配置还可以实现反向代理,用于实现PHP动态解析或者负载负载均衡。location语法为是 location[=|~|~*|^~|@]/uri/{……} ,uri前面的方括号中的内容是可选项,解释如下:

    • / 基于uri目录匹配。
    • = 表示把URI作为字符串,以便与参数中的uri做完全匹配。
    • ~ 表示正则匹配URI时是字母大小写敏感的。
    • ~* 表示正则匹配URI时忽略字母大小写问题。
    • ^~ 表示正则匹配URI时只需要其前半部分与uri参数匹配即可。

      2.5.2、正则优先级

      如果根据匹配规则,多条location命中,则按照优先级进行匹配,其流程如下流程图所示:

    优先级:(location =) > (location 完整路径) > (location ^~ 路径) > (location ~,~* 正则顺序) > (location 部分起始路径) > (/)

      

      如下所示示例:

    location = / {  
       return 250; 
    }
    location / {  
       return 251;
    } 
    location /documents/ {  
       return 252;
    }  
    location ~ /documents/Abc {
        return 253;
    }
    location ^~ /images/ {
        return 254;
    }
    location ~* .(gif|jpg|jpeg)$ {
        return 255; 
    }
    location /images/abc {
        return 256;
    }
    location ~ /images/abc/ {
        return 257;
    }

      测试结果如下:

    http://localhost/ -> return 250
    http://localhost/downloads/download.html -> return 251
    http://localhost/images/1.gif -> return 254
    http://localhost/images/abc -> return 256  此处实验和理论结果冲突,理论上该是返回254,欢迎大家实验指正
    http://localhost/images/abc/def -> return 257 此处试验和理论结果冲突,理论上该是返回254,欢迎大家实验指正
    http://localhost/documents/document.html -> return 252
    http://localhost/documents/1.jpg -> return 255
    http://localhost/documents/Abc.jpg -> return 253

      2.5.3、rewrite重定向

      指令语法:rewrite regex replacement[flag];

      应用位置:server、location、if

      rewrite是实现URL重定向的重要指令,他根据regex(正则表达式)来匹配内容跳转到replacement,结尾是flag标记。

      如:

    location /rewrite_to_baidu {
           rewrite ^/ http://www.baidu.com;
    }

      效果如下,访问http://localhost/rewrite_to_baidu,直接跳转到了http://www.baidu.com。

      

      rewrite会用到以下语法。

    • last – 基本上都用这个Flag。
    • break – 中止rewirte,不在继续匹配。
    • redirect – 返回临时重定向的HTTP状态302。
    • permanent – 返回永久重定向的HTTP状态301。

      注:last和break最大的不同在于,break是终止当前location的rewrite检测,而且不再进行location匹配 - last是终止当前location的rewrite检测,但会继续重试location匹配并处理区块中的rewrite规则。

    • last
    1. 结束当前的请求处理,用替换后的URI重新匹配location;
    2. 可理解为重写(rewrite)后,发起了一个新请求,进入server模块,匹配location;
    3. 如果重新匹配循环的次数超过10次,nginx会返回500错误;
    4. 返回302 http状态码 ;
    5. 浏览器地址栏显示重地向后的url。
    • break
    1. 结束当前的请求处理,使用当前资源,不在执行location里余下的语句;
    2. 返回302 http状态码 ;
    3. 浏览器地址栏显示重地向后的url。

      另外,还可以通过if判断进行rewrite,语法如下:

    Syntax:    if (condition) { ... }
    Default:    —
    Context:    server, location

      能作为条件的内容如下:

    • 变量名;如果变量的值为空字符串或“ 0”,则为false;否则为true (在1.0.1版之前,任何以“ 0”开头的字符串都被视为错误值。)
    • 使用“ =”和“ !=”运算符将变量与字符串进行比较
    • 将变量同使用“ ~”(区分大小写的匹配)和“ ~*”(不区分大小写的匹配)的正则表达式进行匹配正则表达式也可以使用占位符用于以后通过$1..$9变量进行填充。也可使用非运算符“ !~”和“ !~*”。如果正则表达式包含“ }”或“ ;”字符,则整个表达式应用单引号或双引号引起来。
    • 使用“ -f”和“ !-f”运算符检查文件是否存在
    • 使用“ -d”和“ !-d”运算符检查目录是否存在
    • 使用“ -e”和“ !-e”运算符检查文件,目录或符号链接是否存在
    • 使用“ -x”和“ !-x”运算符检查可执行文件

      常见参数如下:

    $args #这个变量等于请求行中的参数。
    $content_length #请求头中的Content-length字段。
    $content_type #请求头中的Content-Type字段。
    $document_root #当前请求在root指令中指定的值。
    $host #请求主机头字段,否则为服务器名称。
    $http_user_agent #客户端agent信息
    $http_cookie #客户端cookie信息
    $limit_rate #这个变量可以限制连接速率。
    $request_body_file #客户端请求主体信息的临时文件名。
    $request_method #客户端请求的动作,通常为GET或POST。
    $remote_addr #客户端的IP地址。
    $remote_port #客户端的端口。
    $remote_user #已经经过Auth Basic Module验证的用户名。
    $request_filename #当前请求的文件路径,由root或alias指令与URI请求生成。
    $query_string #与$args相同。
    $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相同。

      示例:

    # 多目录转成参数 abc.domian.com/sort/2 => abc.domian.com/index.php?act=sort&name=abc&id=2
    if ($host ~* (.*).domain.com) {
        set $sub_name $1;   
        rewrite ^/sort/(d+)/?$ /index.php?act=sort&cid=$sub_name&id=$1 last;
    }
    
    # 目录对换 /123456/xxxx -> /xxxx?id=123456
    rewrite ^/(d+)/(.+)/ /$2?id=$1 last;
    
    # 例如下面设定nginx在用户使用ie的使用重定向到/nginx-ie目录下:
    if ($http_user_agent ~ MSIE) {
        rewrite ^(.*)$ /nginx-ie/$1 break;
    }
    
    # 目录自动加“/”
    if (-d $request_filename){
        rewrite ^/(.*)([^/])$ http://$host/$1$2/ permanent;
    }
    
    # 所有路径为 /images/*.png|jpg的请求都转发到/test下,try_files会依次顺序访问接下来的路径,前一个路径不存在则访问下一个。
    # 如下例,要是$arg_file不存在则最后会返回"image not found exception" location / { rewrite '^/images/(.*).(png|jpg)$' /test?file=$1.$2; set $image_file $1; set $image_type $2; } location /test { root html; try_files /$arg_file /image404.html; } location /image404.html { return 404 "image not found exception"; }

      最后一个示例如下所示:

      

      2.5.4、proxy_pass

      proxy_pass主要用作代理转发,相较rewrite,proxy_pass不影响浏览器地址栏的url。在nginx中配置proxy_pass代理转发时,如果在proxy_pass后面的url加/,表示绝对根路径;如果没有/,表示相对路径,把匹配的路径部分也给代理走。

    假设下面四种情况分别用 http://192.168.1.1/proxy/test.html 进行访问。
    # 第一种:代理到URL:http://127.0.0.1/test.html
    location /proxy/ {
        proxy_pass http://127.0.0.1/;
    }
    # 第二种(相对于第一种,最后少一个 / ),代理到URL:http://127.0.0.1/proxy/test.html
        location /proxy/ {
    proxy_pass http://127.0.0.1;
    }
    # 第三种:代理到URL:http://127.0.0.1/aaa/test.html
    location /proxy/ {
        proxy_pass http://127.0.0.1/aaa/;
    }
    # 第四种(相对于第三种,最后少一个 / ),代理到URL:http://127.0.0.1/aaatest.html
    location /proxy/ {
        proxy_pass http://127.0.0.1/aaa;
    }
    
    # 另外可与负载均衡upstream进行配合使用,如下所示,会被负载到:http://30.4.4.4:9999/proxy/test.html或者http://30.4.4.5:8888/proxy/test.html
    upstream apptest {
        server 30.4.4.4:9999;
        server 30.4.4.5:8888;
    }
    location /proxy {
        proxy_pass http://apptest;
        proxy_set_header Host whhealth.org.cn:2005;        
    }

      2.5.5、deny、allow

      Nginx的deny和allow指令是由ngx_http_access_module模块提供,Nginx安装默认内置了该模块。 除非在安装时有指定 --without-http_access_module。

      语法:allow/deny address | CIDR | unix: | all

      它表示,允许/拒绝某个ip或者一个ip段访问.如果指定unix:,那将允许socket的访问。注意:unix在1.5.1中新加入的功能。在nginx中,allow和deny的规则是按顺序执行的。

    # 示例1:这段配置值允许192.168.0.0/24网段和127.0.0.1的请求,其他来源IP全部拒绝。
    location / {
        allow 192.168.0.0/24;
        allow 127.0.0.1;
        deny all;
    }
    # 示例2:访问的uri中包含admin的请求,只允许110.21.33.121这个IP的请求。
    location ~ "admin" {
        allow 110.21.33.121;
        deny all
    }
    # 禁止多个目录
    location ~ ^/(cron|templates)/ {
        deny all;
        break;
    }

      效果如下所示:

      

    3、常见场景配置

      3.1、日常常见操作

    #第一个必选规则是直接匹配网站根,通过域名访问网站首页比较频繁,使用这个会加速处理,官网如是说。  
    #这里是直接转发给后端应用服务器了,也可以是一个静态首页  
    location = / {  
        proxy_pass http://tomcat:8080/index  
    }  
    
    # 第二个必选规则是处理静态文件请求,这是nginx作为http服务器的强项  
    # 有两种配置模式,目录匹配或后缀匹配,任选其一或搭配使用  
    location ^~ /static/ {  
        root /webroot/static/;  
    }  
    location ~* .(gif|jpg|jpeg|png|css|js|ico)$ {  
        root /webroot/res/;  
    }  
    
    # 第三个规则就是通用规则,用来转发动态请求到后端应用服务器  
    # 非静态文件请求就默认是动态请求 
    location / {  
        proxy_pass http://tomcat:8080/  
    }  

      3.2、日志切割

      我们可以通过crontab生成定时任务,定时对nginx日志进行归档。

    # 列出当前用户的定时任务crontab
    crontab -l
    # 编辑crontab
    crontab -e
    # 分 时 日 月 星期 command
    MAILTO=“”
    0 0 * * * sh /usr/local/nginx/logs/rotate.sh
    # 重启crontab
    systemctl restart crond.service
    # 查看crontab状态
    systemctl status crond.service

      编写rotate.sh脚本进行日志归档操作。

    #!/bin/bash
    log_path="/usr/local/nginx/logs/"
    datetime=$(date -d "-1 day" "+%Y%m%d")
    mkdir -p $log_path/history
    mv $log_path/access.log $log_path/history/access.log_$datetime.log
    mv $log_path/error.log $log_path/history/error.log_$datetime.log
    
    # 像Nginx主进程发送USR1信号重新生成日志文件
    kill -USE1 $(cat $log_path/nginx.pid)

      3.3、反向代理

      正向代理,是指客户端与目标服务器之间增加一个代理服务器,客户端直接访问代理服务器,在由代理服务器访问目标服务器并返回客户端并返回 。这个过程当中客户端需要知道代理服务器地址,并配置连接。

    # 正向代理
    location = /baidu.html {
        proxy_pass http://www.baidu.com;
    }

      反向代理,是指客户端访问目标服务器,在目标服务内部有一个统一接入网关将请求转发至后端真正处理 的服务器并返回结果。这个过程当中客户端不需要知道代理服务器地址,代理对客户端而言是透明的。

    # 反向代理
    location = /fox {
        proxy_pass http://127.0.0.1:8080/;
    }

      代理相关参数

    proxy_pass # 代理服务
    proxy_redirect off; # 是否允许重定向
    proxy_set_header Host $host; # 传 header 参数至后端服务
    proxy_set_header X-Forwarded-For $remote_addr; # 设置request header 即客户端IP地址 proxy_connect_timeout 90; # 连接代理服务超时时间
    proxy_send_timeout 90; # 请求发送最大时间
    proxy_read_timeout 90; # 读取最大时间
    proxy_buffer_size 4k;
    proxy_buffers 4 32k;
    proxy_busy_buffers_size 64k;
    proxy_temp_file_write_size 64k;

      3.4、代理缓存

      代理缓存,获取服务器端内容进行缓存,详情可参考官网,http://nginx.org/en/docs/http/ngx_http_proxy_module.html

    #proxy_cache_path 缓存路径
    #levels 缓存层级及目录位数
    #keys_zone 缓存区内存大小
    #inactive 有效期
    proxy_cache_path /tmp/nginx/cache levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m use_temp_path=off;
        server {
            listen 80;
            server_name  localhost *.yuanma.com;
            location / {
              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_pass http://backend/;
            proxy_cache my_cache; #以全路径md5值作为Key
            proxy_cache_key $host$uri$is_args$args;
        }
    }

      缓存参数详细说明:

      

      缓存清除 ,添加ngx_cache_purge模块,步骤如下:

    #下载ngx_cache_purge 模块包
    wget http://labs.frickle.com/files/ngx_cache_purge-2.3.tar.gz
    #查看已安装模块
    ./sbin/nginx -V
    #进入nginx安装包目录 重新构建 --add-module为模块解压的全路径
    ./configure --prefix=/usr/local/nginx --with-http_stub_status_module --with- http_ssl_module --with-debug --add-module=/root/ngx_cache_purge-2.3
    #重新编译
    make
    #热升级
    kill -SIGUSR2 nginx的pid号

      清除缓存配置如下:

    location ~ /clear(/.*) { 
      #允许访问的IP
      allow 192.168.3.1;
      #禁止访问的IP
      deny all; 
      #配置清除指定缓存区和路径(与proxy_cache_key一致)
      proxy_cache_purge my_cache $host$
    1$is_args$args; }

      3.5、下载限速

      3.6、https转http

      生成自签名证书,https://www.cnblogs.com/hnxxcxg/p/7610582.html

    # 使用openssl工具生成一个RSA私钥
    openssl genrsa -des3 -out server.key 1024 # 生成CSR(证书签名请求)
    openssl req -new -key server.key -out server.csr # 删除私钥中的密码
    openssl rsa -in server.key -out server.key
    # 生成自签名证书
    openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt

      配置https服务 : http://nginx.org/en/docs/http/configuring_https_servers.html

    http {
        #监听本机443端口为https协议
        server {
            listen  443 ssl;
            server_name  localhost;
    
            ssl_certificate      cert.pem;    #SSL证书路径
            ssl_certificate_key  cert.key;    #SSL证书key路径
    
            ssl_session_cache    shared:SSL:1m;
            ssl_session_timeout  5m;
    
            ssl_ciphers  HIGH:!aNULL:!MD5;
            ssl_prefer_server_ciphers  on;
    
            location / {
                proxy_pass http://localhost:8080    #将监听443的https服务转发到本机的8080 http服务
            }
       }
    }

      3.7、websocket请求转发

    Stay hungry,stay foolish !
  • 相关阅读:
    微软工具连接
    [转贴]生成缩略图
    突破验证,安装Media Player11.
    【转贴】Sourcecode and Code Snippets
    AppArch(一):User Interface
    【转】中国的OA要走的路还很长
    对WebService的在企业应用中的思考。
    [转贴]按文件类型获取其图标
    信息系统分析方法
    【转】WebService第一次调用正常,第二次调用超时的解决办法。
  • 原文地址:https://www.cnblogs.com/jing99/p/14691414.html
Copyright © 2020-2023  润新知