注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

itoedr的it学苑

记录从IT文盲学到专家的历程

 
 
 

日志

 
 

nginx配置分级详解(整理)  

2014-07-27 23:44:16|  分类: nginx缓存加速 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

Nginx配置及应用场景之基本配置

一、nginx.conf配置说明

主模块常用指令

  1. daemon

     含义:设置是否以守护进程模式运行
     语法:daemon on|off
     缺省:on
     示例:daemon off
     注意:生产环境(production mode)中不要使用daemon指令,这些选项仅
     用于开发测试(development mode)。
    
  2. debug_points

     含义:断点调试
     语法:debug_points [stop|abort]
     缺省:none
     示例:debug_points stop;
     注意:在Nginx内有一些assert断言,这些断言允许Nginx,配合调试器中断程序运行、
     停止或创建core文件。
    
  3. master_process

     含义:设置是否启用主进程
     语法:master_process on|off
     缺省:on
     示例:master_process off;
     注意:
     不要在生产环境(production mode)中使用master_process指令,
     这些选项仅用于开发测试(development mode)。
    
  4. error_log

     含义:指定错误日志文件
     语法:error_log file [debug|info|notice|warn|error|crit]
     缺省:${prefix}/logs/error.log
     示例:
     error_log /data/nginx/logs/error.log debug
     注意:   
     该命令并非只有在测试(或称为开发)模式下才可以使用,而是在编译时添加了--with-debug参数时,
     则可以使用error_log指令的额外参数,即:
     error_log file [debug_core|debug_alloc|debug_mutex|debug_event|
     debug_http|debug_imap];
    
  5. include

    含义:指定所要包含的Nginx配置文件
    
    语法:include <file|*>
    缺省:none
    示例:include vhosts/*.conf 或 include /home/michael/nginx/conf/nginx-main.conf
    注意:
    (1)include命令可以指定包含一个文件,比如第二个示例。也可以指定包含一个目录下的所有文件,
        比如第一个示例。    
    (2)指定的文件路径的基路径,由编译选项--prefix决定,如果编译时没有指定,
        则默认的路径是/usr/local/nginx。
    
  6. pid

     含义:指定存储进程ID(即PID)的文件。
     语法:pid <file>
     缺省:compile-time option Example
     示例:pid /var/log/nginx.pid;
     注意:可以使用命令kill -HUP cat /var/log/nginx.pid\ 对Nginx进行进程ID文件的重新加载。
    
  7. user

     含义:指定可以使用Nginx的用户   
     语法:user <user> [group]    
     缺省:nobody nobody(第一个nobody是user,第二个nobody是group)    
     示例:user spd spdev;
    
  8. worker_processes

     含义:指定worker进程数
     语法:worker_processes <number>  
     缺省:1      
     示例:worker_processes 4;    
     注意:最大用户连接数=worker进程数×worker连接数,
          即max_clients=worker_processes*worker_connections。
    
  9. worker_cpu_affinity

     含义:为worker进程绑定CPU。        
     语法:worker_cpu_affinity cpumask [cpumask...]       
     缺省:none
     示例:
     (1)如果有4个CPU,并且指定4个worker进程,则:
         worker_processes 4;
         worker_cpu_affinity 0001 0010 0100 1000;
     (2)如果有4个CPU,并且指定2个worker进程,则:
         worker_processes 2;
         worker_cpu_affinity 0101 1010;
    

    注意:只有Linux平台上才可以使用该指令。

  10. worker_rlimit_nofile

    含义:worker进程的file descriptor可以打开的最大文件数,最好与与ulimit -n的值保持一致。
    语法:worker_rlimit_nofile <number>;
    

事件模块(events)常用指令

  1. use

    语法:use [kqueue | rtsig | epoll | /dev/poll | select | poll | eventport];
    注意:如果在./configure的时候指定了不止一种事件模型,那么可以设置其中一个,告诉Nginx使用
    哪种事件模型。默认情况下,Nginx会在./configure时找出最适合系统的事件模型。
    
  2. worker_connections

    语法:worker_connection <number>;
    最大连接数的计算公式如下: 
    max_clients = worker_processes * worker_connections;
    
  3. accept_mutex

    含义:设置是否使用连接互斥锁进行顺序的accept()系统调用。
    语法:accept_mutex <on|off>;
    缺省:on
    示例:accept_mutex off;
    
  4. accept_mutex_delay

    含义:设置获得互斥锁的最少延迟时间。  
    语法:accpet_mutex_delay <number of millisecs>       
    缺省:500ms      
    示例:accpet_mutex_delay 1000ms;
    
  5. debug_connection

    含义:设置指定的clients产生debug日志。     
    语法:debug_connection [ip|CIDR];    
    缺省:none       
    示例:debug_connection 172.16.44.96; 
    一段较完整的事件模块代码如下:   
    error_log /data/nginx/log/error.log;
    events {    
        debug_connection172.16.44.96;   
    }
    

HTTP模块常用指令

  1. alias

    含义:指定location使用的路径,与root类似,但不改变文件的跟路径,仅适用文件系统的路径。
    语法:alias <file-path | directory-path>     
    缺省:N/A        
    作用域:http.server.location    
    示例:       
    location /i/ {
        alias /home/michael/web/i/;     
    }       
    则请求 /i/logo.png 则返回 /home/michael/web/i/logo.png。 
    注意:   
    (1)替换路径时,可以使用变量。  
    (2)alias无法在正则的location中使用。如果有这种需求,则必须使用rewrite和root。
    
  2. client_body_in_file_only

    含义:指定是否将用户请求体存储到一个文件里。  
    语法:client_body_in_file_only <on | off>    
    缺省:off    
    作用域:http.server.location        
    示例:client_body_in_file_only on;   
    注意:   
    (1)该指令为on时,用户的请求体会被存储到一个文件中,但是请求结束后,该文件也不会被删除;
    (2)该指令一般在调试的时候使用。
    
  3. client_body_buffer_size

    含义:指定用户请求体所使用的buffer的最大值
    语法:client_body_buffer_size <size> 
    缺省:两个page的大小,一般为8k或16k    
    作用域:http.server.location    
    示例:client_body_buffer_size 512k;  
    注意:如果用户请求体超过了buffer的大小,则将全部内容或部分内容存储到一个临时文件中。
    
  4. client_body_temp_path

    含义:设置存储用户请求体的文件的目录路径
    语法:client_body_temp_path <directory path> [level1 | level2 | level3]      
    作用域:http.server.location        
    示例:client_body_temp_path /spool/nginx/client_temp 1 2;
    
  5. client_body_timeout

    含义:设置用户请求体的超时时间。
    语法:client_body_timeout <time> 
    作用域:http.server.location        
    示例:client_body_timeout 120s;  
    注意:只有请求体需要被1次以上读取时,该超时时间才会被设置。且如果这个时间后用户什么都没发,
    nginx会返回requests time out 408.
    
  6. client_header_buffer_size

    含义:设置用户请求头所使用的buffer大小  
    语法:client_header_buffer_size <size>       
    缺省:1k     
    作用域:http.server     
    示例:client_header_buffer_size 2k;  
    注意:
    (1)对绝大多数请求来说,1k足以满足请求头所需的buffer;      
    (2)对于携带有较大cookie或来自于wap用户的请求头来说,1k的buffer一般不够,这时可以使用指令
        large_client_header_buffers。
    
  7. client_header_timeout

    含义:设置用户请求头的超时时间。
    语法:client_header_timeout <time>       
    缺省:1m     
    作用域:http.server.location        
    示例:client_header_timeout 3m;      
    注意:只有请求头需要被1次以上读取时,该超时时间才会被设置。且如果这个时间后用户什么都没发,
         nginx会返回requests time out 408.
    
  8. client_max_body_size

    含义:设置所能接收的最大请求体的大小
    语法:client_max_body_size <size>        
    缺省:1m 
    作用域:http.server.location    
    示例:client_max_body_size 2m;       
    注意:根据请求头中的Content-Length来判断请求体大小是否允许。如果大于设定值,则返回
    “ Request Entity Too Large”(413)错误。不过要注意的是,浏览器一般并不对这个错误进行特殊显示。
    
  9. send_timeout

    含义:指定响应客户端的超时时间,单位:秒,默认值为60
    语法:send_timeout <time>
    
  10. keepalive_timeout

    含义:保持连接时间,单位:秒,超过该时间,服务器会关闭连接
    
  11. tcp_nopush

    含义:用于控制TCP链接是否推送,默认值是on
    
  12. tcp_nodelay

    含义:用于控制TCP链接是否延迟,默认值是on,将tcp_nopush和tcp_nodelay两个
         指令设置为on用于防止网络阻塞  
    

HTTP模块Location相关指令

  1. 基本语法

    语法:location [= | ~ | ~* | ^~] </uri/> {...}   
    缺省:N/A
    作用域:server
    
  2. 匹配规则

    1. 四种匹配方式
       = 精确匹配   
       ~ 大小写敏感正则匹配
       ~* 大小写不敏感正则匹配    
       ^~ 前缀匹配
    
    2. location匹配指令的执行顺序  
       首先:= 精确匹配;   
       其次:^~ 前缀匹配;      
       再次:~* 和 ~ 正则匹配,顺序依据出现顺序;
       最后:如果出现正则匹配成功,则采用该正则匹配;如果无可匹配正则,
       则采用前缀匹配结果。
    

如:

        location  = / { # 只匹配"/".}
        location  / {# 匹配任何请求,因为所有请求都是以"/"开始
                 # 但是更长字符匹配或者正则表达式匹配会优先匹配
                    }

        location ^~ /images/ {
                # 匹配任何以 /images/ 开始的请求,并停止匹配
                  其它location
            }

         location ~* \.(gif|jpg|jpeg)$ {
          # 匹配以 gif, jpg, or jpeg结尾的请求. 
          # 但是所有 /images/ 目录的请求将由上面localtion处理.  
        }

压缩(gzip)模块相关指令

gzip(GNU-ZIP)是一种压缩技术。经过gzip压缩后页面大小可以变为原来的30%甚至更小,这样, 用户浏览页面的时候速度会块得多。gzip的压缩页面需要浏览器和服务器双方都支持,实际上就 是服务器端压缩,传到浏览器后浏览器解压并解析。浏览器那里不需要我们担心,因为目前的巨 大多数浏览器都支持解析gzip过的页面。Nginx的压缩输出有一组gzip压缩指令来实现。相关指 令位于http{….}两个大括号之间。

  1. gzip on

    该指令用于开启或关闭gzip模块(on/off)
    
  2. gzip_min_length 1k 设置允许压缩的页面最小字节数,页面字节数从header头得content-length中进行获取。 默认值是0,不管页面多大都压缩。建议设置成大于1k的字节数,小于1k可能会越压越大。

  3. gzip_buffers 4 16k 设置系统获取几个单位的缓存用于存储gzip的压缩结果数据流。4 16k代表以16k为单位, 安装原始数据大小以16k为单位的4倍申请内存。

  4. gzip_http_version 1.1

    识别http的协议版本(1.0/1.1)
    
  5. gzip_comp_level 2

    gzip压缩比,1压缩比最小处理速度最快,9压缩比最大但处理速度最慢(传输快但比较消耗cpu)
    
  6. gzip_types text/plain application/x-javascript text/css application/xml

    匹配mime类型进行压缩,无论是否指定,”text/html”类型总是会被压缩的。
    
  7. gzip_vary on

    和http头有关系,加个vary头,给代理服务器用的,有的浏览器支持压缩,有的不支持,
    所以避免浪费不支持的也压缩,所以根据客户端的HTTP头来判断,是否需要压缩
    
  8. gzip_disable "MSIE [1-6]."

    指定版本浏览器不压缩 
    

二、实际应用中配置实例

nginx.conf部分配置

    #user  nobody;
    worker_processes  48;
    worker_rlimit_nofile 1024;                                  
    error_log  logs/error.log  notice;
    #pid        logs/nginx.pid;
    events {
        use epoll;
        worker_connections  1024;
    }

    # HTTP服务配置
    http {

        include  common.conf;

此处nginx.conf中include了common.conf,其中common.conf中配置了http模块中公用信息

common.conf部分配置

    include       mime.types;
    default_type  application/octet-stream;     
    log_format  main  '|$remote_addr|- |$http_cookie| - |$remote_user| [$time_local]| '
                      '"$request" |$status| $body_bytes_sent| "$http_referer"| '
                      '|"$http_user_agent"| |"$http_x_forwarded_for"|';
    #access_log  off
    access_log  logs/access.log  main buffer=32K;   
    server_tokens off;
    client_max_body_size  20m;                                                          
    client_header_buffer_size    32K;                                                   
    large_client_header_buffers  4 32K;                                                 
    sendfile        on;                                                                 
    tcp_nopush     on;                                                                  
    tcp_nodelay     on;                                 
    client_header_timeout  30;                                                          
    client_body_timeout    30;                                                          
    send_timeout          30;
    keepalive_timeout  65;                                                              
    # HttpGzip模块配置
    include  gzip.conf;

此处common.conf中include了gzip.conf,其中gzip.conf中配置了HttpGzip模块中公用信息

其中gzip.conf部分配置

    # HttpGzip模块配置,这个模块支持在线实时压缩输出数据流
    gzip  on;
    gzip_min_length  1k;
    gzip_proxied     any;
    gzip_buffers     4    16k;
    gzip_http_version    1.1;
    gzip_comp_level    1;
    gzip_types   text/plain application/x-javascript text/css application/xml;
    gzip_vary    on;
    gzip_disable "MSIE [1-6]\.";  

Nginx配置及应用场景之高级配置

一、Nginx反向代理

反向代理(Reverse Proxy)方式是指以代理服务器来接受Internet上的连接请求,然后将请求转发给内部网络上的服务器;并将从服务器上得到的结果返回给Internet上请求连接的客户端,此时代理服务器对外就表现为一个服务器。

通常的代理服务器,只用于代理内部网络对Internet的连接请求,客户机必须指定代理服务器,并将本来要直接发送到Web服务器上的http请求发送到代理服务器中。当一个代理服务器能够代理外部网络上的主机,访问内部网络时,这种代理服务的方式称为反向代理服务。

一个通过HttpProxy模块实现反向代理的简单配置:

    server {
        listen   8888;
        server_name  134.32.28.134;

        location / {
            proxy_pass http://134.32.28.134:8090;
            proxy_redirect off;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
    }

此配置实现在ie中输入http://134.32.28.134:8888即会调转到134.32.28.134:8090中

Upstream模块配置实现:

    upstream appserver { 
         server 134.32.28.134:8090;
    }   
    server {
        listen   8888;
        server_name  134.32.28.134;

        location / {
            proxy_pass http://appserver;
        }
    }

HttpRewrite模块配置实现

    server {
        listen   8888;
        server_name  134.32.28.134;
        rewrite  http://134.32.28.134:8090/ permanent;
    }

二、Nginx负载均衡

Nginx本身提供轮询(round robin)、用户IP哈希(ip_hash)和指定权重三种方式负载均衡策略, 另外也出现第三方负载均衡模块fair和url_hash,默认情况下,Nginx以轮询作为负载均衡策略。

轮询与指定权重策略

简单配置如下:

    upstream appserver { 
       server 134.32.28.134:8090 weight=5;
       server 134.32.28.134:8091 weight=2;
    } 

weight是设置权重,用于后端服务器性能不均的情况。 轮询策略的缺点是某一时段内的一连串访问可能都是由同一个用户A发起的,那么第一次A的请求可能是 8090,而下一次是 8091,然后是 8090、8091…… 在大多数应用场景中,这样并不高效,并且如果后台服务器没有实现对session的共享,会导致session没有共享的。当然,也正因如此,Nginx 为你提供了一个按照IP来hash的方式,这样每个客户端的访问请求都会被甩给同一个后端服务器。

IP哈希策略

配置如下:

    upstream appserver { 
           ip_hash;
           server 134.32.28.134:8090;
           server 134.32.28.134:8091;
    } 

这种策略中,用于进行hash运算的key是客户端的IP地址。这样的方式保证一个客户端每次请求都将到达同一个后台主机。当然,如果所hash到的后台服务器当前不可用,则请求会被转移到其他服务器。

down机、重试策略及备份

当某个一个服务器暂时性的宕机(down)时,你可以使用“down”来标示出来,并且这样被标示的 、服务器就不会接受请求去处理。如:

    upstream appserver { 
       server 134.32.28.134:8090;
       server 134.32.28.134:8091 down;
    } 

可以为每个 backend 指定最大的重试次数,和重试时间间隔。所使用的关键字是 max_fails 和 fail_timeout。如下所示:

    upstream appserver { 
       server 134.32.28.134:8090;
       server 134.32.28.134:8091 max_fails=3 fail_timeout=30s;
    } 

可以使用“backup”关键字。当所有的非备机(non-backup)都宕机(down)或者繁忙(busy)的时候,就只使用由 backup 标注的备机。backup不能和ip_hash关键字一起使用。举例如下:

    upstream appserver { 
       server 134.32.28.134:8090;
       server 134.32.28.134:8091;
       server 134.32.28.134:8092 backup;
    } 

fair(Nginx需安装第三方模块,OpenResty已经集成)

fair按后端服务器的响应时间来分配请求,响应时间短的优先分配,配置如下:

    upstream appserver { 
           server 134.32.28.134:8090;
           server 134.32.28.134:8091;
           fair;
    } 

url_hash(Nginx需安装第三方模块)

url_hash按访问URL的hash结果来分配请求,使每个URL定向到同一个后端服务器,后端服务器为缓存时比较适用。另外,在upstream中加入hash语句后,server语句不能写入weight等其他参数。

    upstream appserver { 
           server 134.32.28.134:8090;
           server 134.32.28.134:8091;
           hash  $request_uri;
           hash_method  crc32;
    } 

三、Nginx静态缓存

Nginx过Proxy Cache可以使其对静态资源进行缓存。其原理就是把静态资源按照一定的规则存在本地硬盘,并且会在内存中缓存常用的资源,从而加快静态资源的响应。

http段设置

proxy_connect_timeout 600;  #nginx跟后端服务器连接超时时间(代理连接超时)
proxy_read_timeout    600;  #连接成功后,后端服务器响应时间(代理接收超时)
proxy_send_timeout    600;  #后端服务器数据回传时间(代理发送超时)
proxy_buffer_size     32k;  #设置代理服务器(nginx)保存用户头信息的缓冲区大小
proxy_buffers         4 32k;#proxy_buffers缓冲区,网页平均在32k以下的话,这样设置
proxy_busy_buffers_size  64k;           #高负荷下缓冲大小(proxy_buffers*2)
proxy_temp_file_write_size  64k;       #设定缓存文件夹大小,大于这个值,将从upstream服务器传
proxy_temp_path /home/spdev/nginx/openresty/local/nginx/proxy_temp;
proxy_cache_path /home/spdev/nginx/openresty/local/nginx/cache levels=1:2 
keys_zone=cache_one:200m inactive=1d max_size=30g;
#levels设置目录层次,keys_zone设置缓存名字和共享内存大小 
#inactive在指定时间内没人访问则被删除在这里是1天,max_size最大缓存空间

server段设置

 location ~* \.(gif|jpg|png|htm|html|css|js|flv|ico|swf)$ {

     proxy_pass http://appserver;  #动态不缓存  
     proxy_redirect off;
     proxy_set_header Host $host;
     proxy_cache cache_one;
     proxy_cache_valid 200 302 1h;  #哪些状态缓存多长时间
     proxy_cache_valid 301 1d;
     proxy_cache_valid any 1m;      #其他的缓存多长时间   
     expires 30d;   #置失期时间,为30天
 }

四、IP并发限制、带宽限制

nginx可以通过HttpLimitReqModul和HttpLimitZoneModule配置来限制ip在同一时间段的访问次数来防cc攻击。 HttpLimitReqModul用来限制连单位时间内连接数的模块,使用limit_req_zone和limit_req指令配合使用来达到限制。 一旦并发连接超过指定数量,就会返回503错误。HttpLimitConnModul用来限制单个ip的并发连接数,使用limit_zone和limit_conn指令这两个模块的区别前一个是对一段时间内的连接数限制,后者是对同一时刻的连接数限制。

设置HttpLimitReqModul限制某一段时间内同一ip访问数

http段设置

    #限制同一ip每秒访问20次
    limit_req_zone $binary_remote_addr zone=allips:10m rate=20r/s;

这里定义一个名为allips的limit_req_zone用来存储session,大小是10M内存, 以$binary_remote_addr 为key,限制平均每秒的请求为20个,1M能存储16000个状态,rate的值必须为整数,如果限制两秒钟一个请求,可以设置成30r/m。

server段设置

    limit_req zone=allips burst=5 nodelay;
    #brust的意思就是,如果第1秒、2,3,4秒请求为19个,第5秒的请求为25个是被允许的。
    #但是如果你第1秒就25个请求后面的5个请求就会被限制,返回503错误。
    #nodelay,如果不设置该选项,严格使用平均速率限制请求数,
    #也就是说如果你设置rate=120r/m,相当于每秒只允许处理2个请求

设置HttpLimitZoneModule 限制并发连接数

http段设置

    #ip限制并发数
    limit_conn_zone  $binary_remote_addr zone=addr:10m;

    #服务器限制并发总数
    limit_conn_zone $server_name zone=perserver:10m;

server段设置

    #连接数限制
    limit_conn addr 10;  

    limit_conn perserver 50000;

    #连接限速
    limit_rate 500k;   

    #限制ip
    allow 132.35.75.0/24;
    #deny all;

其中allow、deny是HTTP Access模块对应的指令,以下需注意:

1、deny 一定要加一个ip,否则直接跳转到403,不往下执行了;如果403默认页是
   同一域名下,会造成死循环访问;

2、allow的ip段从允许访问的段位从小到大排列,如127.0.0.0/24 下面才能是
   10.10.0.0/16
   24表示子网掩码:255.255.255.0
   16表示子网掩码:255.255.0.0
   8表示子网掩码:255.0.0.0;

3、deny all;结尾 表示除了上面allow的其他都禁止
   如:
         deny 192.168.1.1;
         allow 127.0.0.0/24;
         allo w 192.168.0.0/16;
         allow 10.10.0.0/16;
         deny all;

五、第三方合并静态文件模块的使用

这里介绍的是淘宝开发的nginx_concat_module针对nginx的文件合并模块,主要用于合并前端代码减少http请求数。对于此模块的安装前面已经有过说明,这里不再详细解说。

nginx_concat_module模块配置

    # nginx_concat_module 主开关
    concat on;

    # 最大合并文件数
    concat_max_files 10;

    # 只允许同类型文件合并
    concat_unique on;

    # 允许合并的文件类型,多个以逗号分隔。如:application/x-javascript, text/css
    concat_types text/html;

举例如:

http://主机地址/test/??1.css,2.css,3.css…10.css,这里会将1.css,2.css...10.css 是个css文件合并为一个文件从而只需一次请求。

六、实际应用中配置实例

nginx.conf部分配置

    include  common.conf;
    include  proxy_cache.conf;
    #设定负载均衡的服务器列表
    upstream appserver { 
           server 134.32.28.134:8090 weight=5;
           server 134.32.28.134:8091 weight=2;
    } 

    include limit_common.conf;
    # server虚拟主机配置                                                  
    server {
        listen       8888;
        server_name  134.32.28.134;


        #设置网页的默认编码格式
        #charset utf8;      

            #根据访问域名生成对应的访问日志
        access_log  logs/host.access.log  main;     

        lua_code_cache on;                      



        location / {                
            proxy_pass http://appserver;                                
            include user_agent.conf;
            include limit_info.conf;
        }

        location /mytest {    
            content_by_lua_file conf/alcache.lua;       
        }

        location /proxy {    
                include user_agent.conf;                                        
            include limit_info.conf;
            proxy_pass http://appserver$uri;    
        }


        #静态文件缓存
        location ~* \.(gif|jpg|png|htm|html|css|js|flv|ico|swf)$ {

             #防盗链
                 #valid_referers none blocked 134.32.28.134;
                     #if ($invalid_referer) {
                            #return 403;
                     #}

             proxy_pass http://appserver;
             proxy_redirect off;
             proxy_set_header Host $host;
             proxy_cache cache_one;
             proxy_cache_valid 200 302 1h;
             proxy_cache_valid 301 1d;
             proxy_cache_valid any 1m;
             expires 30d;
        }

此处nginx.conf中include了limit_common.conf、user_agent.conf、 limit_info.conf与proxy_cache.conf,其中user_agent.conf中配置了客户端信息判断及文件合并等信 息,limit_common.conf配置了ip限制相关公用信息,limit_info.conf配置了实际server中限制要 求,proxy_cache.conf中配置了静态缓存相关信息,其中静态文件缓存部分为server运用中的配置。

user_agent.conf配置

#客户端判断
#if ($http_user_agent ~* "MSIE") { proxy_pass http://appserver; }
if ($http_user_agent ~* "Nokia") { rewrite . /404.html break; }
if ($http_user_agent ~* "Mobile") { rewrite . /404.html break; }
if ($http_user_agent ~* "SAMSUNG") { rewrite . /404.html break; }
if ($http_user_agent ~* "SonyEricsson") { rewrite . /404.html break; }
if ($http_user_agent ~* "MOT") { rewrite . /404.html break; }
if ($http_user_agent ~* "BlackBerry") { rewrite . /404.html break; }
if ($http_user_agent ~* "LG") { rewrite . /404.html break; }
if ($http_user_agent ~* "HTC") { rewrite . /404.html break; }
if ($http_user_agent ~* "J2ME") { rewrite . /404.html break; }
if ($http_user_agent ~* "Opera Mini") { rewrite . /404.html break; }
if ($http_user_agent ~* "ipad") { proxy_pass http://appserver; }
if ($http_user_agent ~* "iphone") { proxy_pass http://appserver; }
if ($http_user_agent ~* "android") { proxy_pass http://appserver; }

#只允许访问get、head、post方法
if ($request_method !~* ^(GET|HEAD|POST)$ ) {
        return 403;
}

#js、css文件合并
concat on;
#concat_max_files 10;
#只允许同类型文件合并
#concat_unique on;
#允许合并的文件类型,多个以逗号分隔。如:application/x-javascript, text/css
#concat_types text/html

limit_common.conf配置

#限制同一ip每秒访问20次
limit_req_zone $binary_remote_addr zone=allips:10m rate=20r/s;
#ip限制并发数
limit_conn_zone  $binary_remote_addr zone=addr:10m;

#服务器限制并发总数
limit_conn_zone $server_name zone=perserver:10m;

limit_info.conf配置

#brust的意思就是,如果第1秒、2,3,4秒请求为19个,第5秒的请求为25个是被允许的。
#但是如果你第1秒就25个请求后面的5个请求就会被限制,返回503错误。
#nodelay,如果不设置该选项,严格使用平均速率限制请求数,
#也就是说如果你设置rate=120r/m,相当于每秒只允许处理2个请求

limit_req zone=allips burst=5 nodelay;

#连接数限制
limit_conn addr 10;  

limit_conn perserver 50000;

#连接限速
limit_rate 500k;   

#限制ip
allow 132.35.75.0/24;
#deny all;

proxy_cache.conf配置

proxy_connect_timeout 5;
proxy_read_timeout 60;
proxy_send_timeout 5;
proxy_buffer_size 16k;
proxy_buffers 4 64k;
proxy_busy_buffers_size 128k;
proxy_temp_file_write_size 128k;
proxy_temp_path /home/spdev/nginx/openresty/local/nginx/proxy_temp;
proxy_cache_path /home/spdev/nginx/openresty/local/nginx/cache levels=1:2 
keys_zone=cache_one:200m inactive=1d max_size=30g;


Nginx服务器介绍及扩展

一、概述

架构

nginx在启动后,在unix系统中会以daemon的方式在后台运行,后台进程包含一个master进程和多个worker进程。我们也可以手 动地关掉后台模式,让nginx在前台运行,nginx是以多进程的方式来工作的,当然nginx也是支持多线程的方式的,只是我们主流的方式还是多进程 的方式。

nginx在启动后,会有一个master进程和多个worker进程。master进程主要用来管理worker进程,包含:接收来自外界的信 号,向各worker进程发送信号,监控worker进程的运行状态,当worker进程退出后(异常情况下),会自动重新启动新的worker进程。而 基本的网络事件,则是放在worker进程中来处理了。多个worker进程之间是对等的,他们同等竞争来自客户端的请求,各进程互相之间是独立的。一个 请求,只可能在一个worker进程中处理,一个worker进程,不可能处理其它进程的请求。worker进程的个数是可以设置的,一般我们会设置与机 器cpu核数一致,这里面的原因与nginx的进程模型以及事件处理模型是分不开的。nginx的进程模型,可以由下图来表示:

基本概念

connection

在nginx中connection就是对tcp连接的封装,其中包括连接的socket,读事件,写事件。利用nginx封装的 connection,我们可以很方便的使用nginx来处理与连接相关的事情,比如,建立连接,发送与接受数据等。而nginx中的http请求的处理 就是建立在connection之上的,所以nginx不仅可以作为一个web服务器,也可以作为邮件服务器。当然,利用nginx提供的 connection,我们可以与任何后端服务打交道。

在nginx中,每个进程会有一个连接数的最大上限,这个上限与系统对fd的限制不一样。在操作系统中,通过ulimit -n,我们可以得到一个进程所能够打开的fd的最大数,即nofile,因为每个socket连接会占用掉一个fd,所以这也会限制我们进程的最大连接 数,当然也会直接影响到我们程序所能支持的最大并发数,当fd用完后,再创建socket时,就会失败。不过,这里我要说的nginx对连接数的限制,与 nofile没有直接关系,可以大于nofile,也可以小于nofile。nginx通过设置worker_connectons来设置每个进程可使用 的连接最大值。nginx在实现时,是通过一个连接池来管理的,每个worker进程都有一个独立的连接池,连接池的大小是 worker_connections。这里的连接池里面保存的其实不是真实的连接,它只是一个worker_connections大小的一个 ngx_connection_t结构的数组。并且,nginx会通过一个链表free_connections来保存所有的空闲 ngx_connection_t,每次获取一个连接时,就从空闲连接链表中获取一个,用完后,再放回空闲连接链表里面。

一个nginx能建立的最大连接数,应该是worker_connections * worker_processes。这里说的是最大连接数,对于HTTP请求本地资源来说,能够支持的最大并发数量是 worker_connections * worker_processes,而如果是HTTP作为反向代理来说,最大并发数量应该是worker_connections * worker_processes/2。因为作为反向代理服务器,每个并发会建立与客户端的连接和与后端服务的连接,会占用两个连接。

request

request具体到nginx中的数据结构是ngx_http_request_t。ngx_http_request_t是对一个http请求的封装。以下为nginx一个http请求的生命周期图:

Nginx指令

nginx的配置系统由一个主配置文件和其他一些辅助的配置文件构成。这些配置文件均是纯文本文件,全部位于nginx安装目录下的conf目录 下。配置文件中以#开始的行,或者是前面有若干空格或者TAB,然后再跟#的行,都被认为是注释,也就是只对编辑查看文件的用户有意义,程序在读取这些注 释行的时候,其实际的内容是被忽略的。在nginx.conf中,包含若干配置项。每个配置项由配置指令和指令参数2个部分构成。指令参数也就是配置指令 对应的配置值。

配置指令是一个字符串,可以用单引号或者双引号括起来,也可以不括。但是如果配置指令包含空格,一定要引起来。指令的参数使用一个或者多个空格或者 TAB字符与指令分开。指令的参数有一个或者多个TOKEN串组成。TOKEN串之间由空格或者TAB键分隔。TOKEN串分为简单字符串或者是复合配置 块。复合配置块即是由大括号括起来的一堆内容。一个复合配置块中可能包含若干其他的配置指令。

如果一个配置指令的参数全部由简单字符串构成,也就是不包含复合配置块,那么我们就说这个配置指令是一个简单配置项,否则称之为复杂配置项。例如下面这个是一个简单配置项:

error_page 500 502 503 504 /50x.html;

对于简单配置,配置项的结尾使用分号结束。对于复杂配置项,包含多个TOKEN串的,一般都是简单TOKEN串放在前面,复合配置块一般位于最后,而且其结尾,并不需要再添加分号。例如下面这个复杂配置项

location / { root /home/jizhao/nginx-book/build/html; index index.html index.htm; }

Nginx模块概述

nginx的内部结构是由核心部分和一系列的功能模块所组成。这样划分是为了使得每个模块的功能相对简单,便于开发,同时也便于对系统进行功能扩 展。nginx将各功能模块组织成一条链,当有请求到达的时候,请求依次经过这条链上的部分或者全部模块,进行处理。每个模块实现特定的功能。例如,实现 对请求解压缩的模块,实现SSI的模块,实现与上游服务器进行通讯的模块。

模块分类

nginx的模块根据其功能基本上可以分为以下几种类型:

event module: 搭建了独立于操作系统的事件处理机制的框架,及提供了各具体事件的处理。包括ngx_events_module, ngx_event_core_module和ngx_epoll_module等。nginx具体使用何种事件处理模块,这依赖于具体的操作系统和编译 选项。

phase handler: 此类型的模块也被直接称为handler模块。主要负责处理客户端请求并产生待响应内容,比如ngx_http_static_module模块,负责客户端的静态页面请求处理并将对应的磁盘文件准备为响应内容输出。

output filter: 也称为filter模块,主要是负责对输出的内容进行处理,可以对输出进行修改。例如,可以实现对输出的所有html页面增加预定义的footbar一类的工作,或者对输出的图片的URL进行替换之类的工作。

upstream: upstream模块实现反向代理的功能,将真正的请求转发到后端服务器上,并从后端服务器上读取响应,发回客户端。upstream模块是一种特殊的handler,只不过响应内容不是真正有自己产生的,而是从后端服务器上读取的。

load-balancer: 负载均衡模块,实现特定的算法,在众多的后端服务器中,选择一个服务器出来作为某个请求的转发服务器。

handler模块

Handler模块就是接受来自客户端的请求并产生输出的模块,目前第三方开发模块最可能开发的就是三种类型的模块,即handler,filter和load-balancer。

二、OpenResty介绍及安装

OpenResty介绍

OpenResty (也称为 ngx_openresty)是一个全功能的 Web 应用服务器,它打包了标准的 Nginx 核心,很多的常用的第三方模块,以及它们的大多数依赖项。OpenResty 通过汇聚各种设计精良的 Nginx 模块。从而将 Nginx 有效的变成一个强大的 Web 应用服务器,这样, Web 开发人员可以使用 Lua 脚本语言调动 Nginx 支持的各种C以及Lua 模块。 OpenResty 的目标是让你的Web服务直接跑在 Nginx 服务内部,充分利用 Nginx 的非阻塞 I/O 模型,不仅仅对 HTTP 客户端请求,甚至于对远程后端诸如MySQL,PostgreSQL, Memcache 以及 ~Redis 等都进行一致的高性能响应。

OpenResty安装

1、下载OpenResty http://openresty.org/download/ngx_openresty-1.4.2.8.tar.gz
2、解压openresty gunzip -c ngx_openresty-1.4.2.8.tar.gz | tar xvf -
3、./configure \ --prefix=/home/spdev/nginx/openresty/local \ --sbin-path=/home/spdev/nginx/openresty/sbin \ --user=spdev\ --group=spd\ --with-debug \ --with-http_dav_module \ --with-http_ssl_module \ --with-http_stub_status_module \ --with-http_addition_module \ --with-http_flv_module \ --without-http_memcached_module \ --without-http_redis2_module \ --without-http_redis_module \ --without-lua_redis_parser \ --without-mail_pop3_module \ --without-mail_imap_module \ --without-mail_smtp_module \
 make
 make install 其中--with是自定义安装需要模块,--without是不安装默认安装的模块。

第三方模块安装

1、服务器新建目录如:/home/spdev/nginx/tb_module
2、下载第三方模块,如淘宝合并js模块 (svn checkout http://code.taobao.org/svn/nginx_concat_module/trunk/ $NGINX_CONCAT_MODULE)。
3、./configure 中增加参数,--add-module=$NGINX_CONCAT_MODULE ./configure \ --prefix=/home/spdev/nginx/openresty/local \ --sbin-path=/home/spdev/nginx/openresty/sbin \ --user=spdev\ --group=spd\ --with-debug \ --with-http_dav_module \ --with-http_ssl_module \ --with-http_stub_status_module \ --with-http_addition_module \ --with-http_flv_module \ --without-http_memcached_module \ --without-http_redis2_module \ --without-http_redis_module \ --without-lua_redis_parser \ --without-mail_pop3_module \ --without-mail_imap_module \ --without-mail_smtp_module \ --add-module=/home/spdev/nginx/tb_module/$NGINX_CONCAT_MODULE \
4、make make install

三、Nginx简单命令

Nginx默认配置文件nginx.conf位于nginx安装目录conf目录下,执行命令需切换至对应目录。

nginx 启动Nginx nginx -c </path/to/config> Nginx 指定一个配置文件,来代替缺省的。
 nginx -t 不运行,仅仅测试配置文件语法的正确性。
nginx -v 显示 nginx 的版本。
nginx -V 显示 nginx 的版本,编译器版本和配置参数。
nginx -s reload 更改了配置后无需重启Nginx,平滑重启。
 nginx -s stop 停止Nginx


Nginx配置及应用场景之lua

一、说明

这里不对lua语言本身及其编译器运行环境等做介绍,以下所有介绍前提对lua相关有所了解。

二、ngx_lua介绍

原理

ngx_lua将Lua嵌入Nginx,可以让Nginx执行Lua脚本,并且高并发、非阻塞的处理各种请求。Lua内建协程,这样就可以很好的将 异步回调转换成顺序调用的形式。ngx_lua在Lua中进行的IO操作都会委托给Nginx的事件模型,从而实现非阻塞调用。开发者可以采用串行的方式 编写程序,ngx_lua会自动的在进行阻塞的IO操作时中断,保存上下文;然后将IO操作委托给Nginx事件处理机制,在IO操作完成 后,ngx_lua会恢复上下文,程序继续执行,这些操作都是对用户程序透明的。

每个NginxWorker进程持有一个Lua解释器或者LuaJIT实例,被这个Worker处理的所有请求共享这个实例。每个请求的Context会被Lua轻量级的协程分割,从而保证各个请求是独立的。

ngx_lua采用“one-coroutine-per-request”的处理模型,对于每个用户请求,ngx_lua会唤醒一个协程用于执行 用户代码处理请求,当请求处理完成这个协程会被销毁。每个协程都有一个独立的全局环境(变量空间),继承于全局共享的、只读的“comman data”。所以,被用户代码注入全局空间的任何变量都不会影响其他请求的处理,并且这些变量在请求处理完成后会被释放,这样就保证所有的用户代码都运行 在一个“sandbox”(沙箱),这个沙箱与请求具有相同的生命周期。

得益于Lua协程的支持,ngx_lua在处理10000个并发请求时只需要很少的内存。根据测试,ngx_lua处理每个请求只需要2KB的内存,如果使用LuaJIT则会更少。所以ngx_lua非常适合用于实现可扩展的、高并发的服务。

协程

协程类似一种多线程,与多线程的区别有:

  1. 协程并非os线程,所以创建、切换开销比线程相对要小。
  2. 协程与线程一样有自己的栈、局部变量等,但是协程的栈是在用户进程空间模拟的,所以创建、切换开销很小。
  3. 多线程程序是多个线程并发执行,也就是说在一瞬间有多个控制流在执行。而协程强调的是一种多个协程间协作的关系,只有当一个协程主动放弃执行权,另一个协程才能获得执行权,所以在某一瞬间,多个协程间只有一个在运行。
  4. 由于多个协程时只有一个在运行,所以对于临界区的访问不需要加锁,而多线程的情况则必须加锁。
  5. 多线程程序由于有多个控制流,所以程序的行为不可控,而多个协程的执行是由开发者定义的所以是可控的。

Nginx的每个Worker进程都是在epoll或kqueue这样的事件模型之上,封装成协程,每个请求都有一个协程进行处理。这正好与Lua内建协程的模型是一致的,所以即使ngx_lua需要执行Lua,相对C有一定的开销,但依然能保证高并发能力。

二、ngx_lua安装

Nginx中安装ngx_lua需要安装LuaJIT,ngx_devel_kit,ngx_lua等安装文件,我们这里用的OpenResty,内部已经集成ngx_lua,无需再安装任何模块。

三、ngx_lua用法

嵌套lua脚本

location /lua { set $test "hello, world"; content_by_lua ' ngx.header.content_type = "text/plain"; ngx.say(ngx.var.test); '; }

$ curl 'http://134.32.28.134:8888/lua',输出 hello, world。

include lua文件

Nginx中include lua的脚本文件方式,如:

location /mytest { content_by_lua_file conf/alcache.lua; }

其中在alcache.lua中编写lua脚本即可。

四、实际运用中通过lua结合分布式缓存对session的处理

这里redis与memcache的支持不是调用Nginx自带redis与memcache模块,都是调用OpenResty内部集成的第三方模块

nginx.conf部分配置

location /login { content_by_lua_file conf/alcache.lua; }

alcache.lua配置

local key = tostring(ngx.var.arg_username)
local val = tostring(ngx.var.arg_password)
 local passLogin = tostring(ngx.var.arg_passLoginFlag)
 local flags = tostring(ngx.var.arg_flags or 0)
 local exptime = tostring(ngx.var.arg_exptime or 0)
 local sessionId = tostring(ngx.var.cookie_JSESSIONID) ngx.say("sessionId:",sessionId) ngx.say("key:",key) ngx.say("val:",val) if (key == nil and val == nil)
then return
end --if (passLogin == nil or sessionId == nil)
 then return
end
local memcached = require("resty.memcached") --
local redis = require("resty.redis")
local cache,err = memcached:new() -
-local cache,err = redis.new()
if not cache
then
 ngx.say("failed to instantiate cache: ",err)
 return
end cache:set_timeout(1000) local ok,err = cache:connect("134.32.28.134",11211) --local ok,err = cache:connect("134.32.28.134",6379) if not ok then ngx.say("failed to connect: ",err) return end local res,flags,err = cache:get(key) if err then ngx.say("failed to get ",key," : ",err) return end if res and tostring(res) ~= sessionId then cache:delete(key) cache:set(key,sessionId,exptime,flags) else cache:set(key,sessionId,exptime,flags) end local ok, err = cache:close() if not ok then ngx.say("failed to close:", err) return end local url = ngx.var.uri local res = ngx.location.capture("/proxy")
  评论这张
 
阅读(229)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017