美文网首页部署运维Nginx高端成长之路运维点滴
Nginx反向代理负载均衡配置梳理大全

Nginx反向代理负载均衡配置梳理大全

作者: 三杯水Plus | 来源:发表于2018-01-16 10:51 被阅读109次
    本文梳理了Nginx在做反向代理时常用的核心配置,所有细节可以参考官网http://nginx.org/,我这里主要起到穿针引线的作用。

    本文主要涉及了如下模块:
    ngx_http_core_module
    ngx_htpp_access_module
    ngx_http_geo_module
    ngx_http_map_module
    ngx_http_index_module
    ngx_http_log_module
    ngx_http_perl_module
    ngx_http_rewrite_module
    ngx_http_ssi_module
    ngx_http_ssl_module
    ngx_http_upstream_module
    ngx_http_proxy_module
    ngx_http_limit_conn_module
    ngx_http_limit_req_module
    ngx_stream_core_module
    ngx_stream_proxy_module
    ngx_upstream_module
    第三方模块如下:
    redis2-nginx-module
    redis-nginx-module
    srcache-nginx-module
    nginx-upsync-module

    一、跳转

    利用ngx_http_core_module、ngx_http_rewrite_module模块
    主要是301跳转
    Return写法:域名http请求跳转到对应的https请求

     server
      {
         listen   80;
        server_name www.test.com;
        index index.html index.htm index.shtml;
        location / {
              return      301 https://$host$request_uri;
       }
        access_log  /data/wwwlogs/access_www.test.com.log  access;
    }
    

    Rewrite写法:rewrite写法比较灵活可以调整路径,但没有return高效

    server
    {
        listen   80;
        server_name www.test.com;
        index index.html index.htm index.shtml;
        location ~* ^/(meinv|huodong|zhuanti)/(.*)$  {
            rewrite  ^/(meinv|huodong|zhuanti)/(.*)$   http://oldwww.test.com/$1/$2 permanent;
        }
        location / {
            proxy_pass http://www_test_com;
        }
        access_log  /data/wwwlogs/access_www.test.com.log  access;
    }
    upstream www_test_com {
            server 192.168.88.188:80;
            server 192.168.88.189:80;
    }
    
    二、重写代理

    利用ngx_http_proxy_module、ngx_http_upstream_module模块

    server
    {
        listen 80;
        server_name www.test.com;
        index index.html index.htm index.shtml;
        location ~* /api/ {
             rewrite /api/(.*)$ /api/$1 break;
             proxy_set_header Host  apiwww.test.com;
             proxy_set_header X-Real-IP  $remote_addr;
             proxy_set_header        X_FORWARDED_FOR $proxy_add_x_forwarded_for;
             proxy_set_header        VIA     111.111.111.111;
             proxy_pass http://www_test_com_api;
         }
        access_log  /data/wwwlogs/access_www.test.com.log  access;
    }
    upstream www_test_com_api {
            server 192.168.88.188:80;
            server 192.168.88.189:80;
    }
    
    三、限速限连接

    利用ngx_http_limit_conn_module、ngx_http_limit_req_module模块
    首先http区域里面定义好限速限制连接数策略,再在线上具体域名上使用
    Http区域配置如下:

    map $http_x_forwarded_for  $clientRealIpnormal {
        ""  $remote_addr;
        ~^(?P<firstAddr>[0-9\.]+),?.*$  $firstAddr;
    }
    map $http_http_cdn_src_ip $clientRealIp{
        ""   $clientRealIpnormal;
        default $http_http_cdn_src_ip;
    }
    geo  $clientRealIp  $white_ip  {
    default 1;
    include geo.conf;
    }
    map $white_ip $limited {
            1  $clientRealIp;
            0  "";
     }
    
    limit_req_status 418;
    limit_conn_status 418;
    
    limit_conn_zone $limited zone=addr:200m;
    limit_req_zone  $limited zone=zero1:20m rate=1r/s;
    limit_req_zone  $limited zone=zero2:20m rate=2r/s;
    limit_req_zone  $limited zone=zero:20m rate=3r/s;
    limit_req_zone  $limited zone=one:20m rate=10r/s;
    limit_req_zone  $limited zone=two:20m rate=20r/s;
    limit_req_log_level info;
    limit_conn_log_level info;
    

    线上域名开启配置如下:

    server
    {
        listen   80;
        server_name www.test.com;
        index index.html index.htm index.shtml;
        location / {
              limit_req zone=two burst=5 nodelay;
              limit_conn  addr 20;
              proxy_pass http://www_test_com;
        }
        access_log  /data/wwwlogs/access_www.test.com.log  access;
    }
    upstream www_test_com {                      
            server 192.168.88.188:80;
            server 192.168.88.189:80;
    }
    
    四、屏蔽IP

    1、方法一
    使用ngx_http_access_module模块allow、deny控制,缺点是通过remote_addr来屏蔽IP的,优点是支持CIDR等格式地址

    allow 111.111.111.111;
    allow 192.168.88.0/24;
    deny all;
    

    2、方法二
    用于自定义客户端IP变量$clientRealIp来屏蔽,缺点IP需要写成正则形式的,优点是支持IP穿透,过CDN的域名这种方法才能生效

    if ($clientRealIp ~ "(183.60.189.195|182.10.18.135)")
    {
            return 403;
    }
    

    3、方法三
    自定义屏蔽IP,结合Elasticsearch查询异常IP可自动化屏蔽IP

      set $clientipfileurl  "/usr/local/nginx/html/blockip/$host/$clientRealIp";
      if ( -f  $clientipfileurl) {
        return 403 "Your IP address $clientRealIp is too frequent, please try again later or contact the webmaster, thank you!";
      }
    
    五、屏蔽URL

    1、方法一
    自动屏蔽,结合Elasticsearch查询异常URL,可自动化屏蔽URL

    set $fileurl  "/usr/local/nginx/html/blockurl/$host/$uri";
    if ( -f  $fileurl) {
        return 403 "This url $host$uri is too frequent, please try again later or contact the webmaster, thank you!";
     }
    

    2、方法二
    手动屏蔽,当某个目录或者URL影响到全站访问时可以手动屏蔽

    location ~* ^/mbw/xoxo/123456789/ {
        return 403;
    }
    
    六、SSI包含

    利用ngx_http_ssi_module模块
    开启ssi后,include与ushtml代理到ssi服务器

    server
    {
        listen   80;
        server_name www.test.com;
        index index.html index.htm index.shtml;
            ssi on;
            ssi_silent_errors off;
            ssi_types text/shtml;
        location ~* ^/(include|ushtml)  {
            proxy_pass http://www_test_com_include;
        }
        location / {
            proxy_pass http://www_test_com;
        }
        access_log  /data/wwwlogs/access_www.test.com.log  access;
    }
    upstream www_test_com {                      
            server 192.168.88.188:80;
            server 192.168.88.189:80;
    }
    upstream www_test_com_include {
            server 192.168.88.11:80;
            server 192.168.88.12:80;
    }
    
    七、Srcache配置

    该架构是给论坛做帖子缓存的,注意只能缓存帖子,目录不能缓存是openresty +srcache+reids2-nginx-module组成:入口是openresty,缓存是codis集群,上游服务器是iis源站
    其中http区域配置为删除过期key,更新key的作用,由新第维护lua脚本,配置如下:

    http {
        server {
            listen       80;
            server_name  www.test.com;
            allow  192.168.88.0/24;
            allow  192.168.188.0/24;
            deny all;
            location ~ /delkey/(.*) {
                    internal;
                    set $redis_key $1;
                    redis2_query del $redis_key;
                    redis2_pass redis_server;
            }
        }
        include proxy.conf;
        include vhosts_all/*.conf;
    }
    

    具体源站配置,放在vhost下,目前只有www.test.com域名,配置如下:

    upstream www_test_com {                      
            server 192.168.88.188:80;
            server 192.168.88.189:80;
    }
    
    server {
          listen       80;
          server_name  www.test.com;
          more_clear_headers  "X-AspNet-Version";
          more_clear_headers  "X-Powered-By";
          location / {
            default_type text/html;
            srcache_methods GET;
            srcache_response_cache_control on;
            srcache_store_statuses 200;
            srcache_store_max_size 1024000;
            set $key $host$uri;
            set_escape_uri $escaped_key $key;
            srcache_fetch GET /redis_get $key;
            srcache_default_expire 0;
            srcache_max_expire 1h;
            srcache_store PUT /redis_set 
            key=$escaped_key&exptime=$srcache_expire;
            add_header X-Cached-From $srcache_fetch_status;
            add_header X-Cached-Store $srcache_store_status;
            add_header X-Key $key;
            add_header X-Query_String $query_string;
            add_header X-expire $srcache_expire;
            access_log /data/wwwlogs/access_www.test.com-redis.log srcache_log;
            proxy_pass http://www_test_com;
    
         }
         location = /redis_get {
                 internal;
                 set $redis_key $args;
                 redis_pass redis_server;
         }
         location = /redis_set {
                 internal;
                 set_unescape_uri $exptime $arg_exptime;
                 set_unescape_uri $key $arg_key;
                  redis2_query set $key $echo_request_body;
                 redis2_query expire $key $exptime;
                 redis2_pass redis_server;
         }
     }
    
    八、Upsync配置

    该项目是动态上下负载,架构为nginx+nginx-upsync-module+consul,配置文件只需要对具体域名进行修改,如下:

    server
    {
        listen 80;
        server_name www.test.com;
        index index.html index.htm index.shtml;
        location / {
            proxy_pass http://www_test_com;
        }
        location = /upstream_show {
            upstream_show;
        }
        access_log  /data/wwwlogs/access_www.test.com.log  access;
    }
    upstream www_test_com {
        upsync 192.168.88.58:8500/v1/kv/upstreams/www.test.com/ upsync_timeout=6m upsync_interval=500ms upsync_type=consul strong_dependency=off;
        upsync_dump_path /usr/local/nginx/conf/servers/dump_www.test.com.conf;
        include /usr/local/nginx/conf/servers/include_www.test.com.conf;
    }
    
    九、Websock配置

    Websock协议为ws,如果还需要添加ssl支持,协议为https正常添加证书就行,websock支持长连接。

    server
    {
        listen 80;
        server_name www.test.com;
        index index.html index.htm index.shtml;
        location / {
                proxy_pass http://olc_yiche_com;
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection $connection_upgrade;
                proxy_read_timeout 28800;
                proxy_redirect    off;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP        $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
         }
    }
    map $http_upgrade $connection_upgrade {
            default upgrade;
            ''      close;
    }
    
    upstream www_test_com {                      
            server 192.168.88.188:80;
            server 192.168.88.189:80;
    }
    
    十、其他
    1、只允许POST请求
    location ~* /hd/api/prizehandler.ashx {
        if ($request_method = GET ) {
            return 403;
            }
            proxy_method POST; 
        proxy_pass http://apiwww_test_com;
    }
    
    2、禁止Agent
    if ($http_user_agent ~* "(python-requests|Java/1.8.0_40|Java/1.0.0_07|Java/1.7.0_67|Mac OS X 10_7_5|Iceweasel|curl|spider|ChinaCache)") 
    { 
           return 403; 
    }
    
    3、设置过期时间
    location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|js|css)$
    { 
           expires      30d;
           proxy_pass http://image_test_com;
    }
    
    4、设置权限
    location / {
           auth_basic "Please input Username and Password";
           auth_basic_user_file /usr/local/nginx/conf/.pass_file;
    }
    
    5、rewrite忽略大小写
    rewrite (?i)^/newsimg_(\d+)x(\d+)/(.*)$ /videoimgnew.php?w=$1&h=$2&dir=$3 break;
    
    6、404冗余

    方法一
    通过$request_filename判断

    if ( !-f $request_filename ){
         proxy_pass http://image_test_com;
         break;
    }
    

    方法二
    if判断效率比较低,可以使用try_files

    location / {
        try_files $uri @backend;
    }
    location @backend {
         proxy_pass http://image_test_com;
    }
    

    方法三
    通过error_page功能

    location / {
            error_page 404 500 = @fallback;
            proxy_pass http://image_test_com;
        }
    location @fallback {
         proxy_pass http://imagebak_test_com;
    }
    
    7、url大小写转换

    http区域配置如下

       perl_set $url ' 
       sub {
       my $r = shift;
       my $re = lc($r->uri);
       return $re;
       } ';
    

    域名server区域配置如下

        if ($uri ~ [A-Z])
        {
          rewrite ^(.*)$  $url last;
        } 
    
    8、支持跨域

    字体支持所有域名跨域调用,某些客户端可能支持的不太友好

    location ~* /topics/iconfont/
        {
               add_header Access-Control-Allow-Origin *;
    }
    
    9、SSL支持

    该域名配置同时支持http与https,配置如下:

    server
    {
        listen 80;
        listen 443;
        server_name zhongce.m.yiche.com;
        index index.html index.htm index.shtml;
            ssl                         on;
            ssl_certificate             globalsignssl/server.cer;
            ssl_certificate_key      globalsignssl/server.key;
            ssl_prefer_server_ciphers   on;
            ssl_ciphers "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";
            ssl_protocols               TLSv1.2 TLSv1.1 TLSv1;
            ssl_session_cache           shared:SSL:10m;
            ssl_session_timeout         60m;
        location / {
             proxy_pass http://www_test_com;
         }
    }
    
    10、tcp负载

    需要开启stream模块,如果要支持ssl,需要开启stream_ssl模块
    http区域配置如下:

    cat /usr/local/nginx/conf/nginx.conf
    user  www www;
    worker_processes  auto;
    worker_cpu_affinity auto;
    error_log  logs/error.log  error;
    pid        logs/nginx.pid;
    worker_rlimit_nofile 409600;
    events
    {
      use epoll;
      worker_connections 409600;
    }
    stream {
    
    log_format basic '$remote_addr [$time_local] '
                     '$protocol $status $bytes_sent $bytes_received '
                     '$session_time';
    
    log_format proxy '$remote_addr [$time_local] '
                     '$protocol $status $bytes_sent $bytes_received '
                     '$session_time "$upstream_addr" '
                     '"$upstream_bytes_sent" "$upstream_bytes_received" "$upstream_connect_time"';
    
    include tcpupstream/*.conf;
    }
    

    tcp负载配置如下:
    cat /usr/local/nginx/conf/tcpupstream/test12306.conf

    upstream test_12306 {
            server 192.168.88.21:12306;
            server 192.168.88.22:12306;
     }
    server {
            listen 12306;
            proxy_connect_timeout 10s;
            proxy_timeout 30s;
            proxy_pass test_12306;
            access_log /data/wwwlogs/access_test12306.log proxy;
    }
    

    相关文章

      网友评论

        本文标题:Nginx反向代理负载均衡配置梳理大全

        本文链接:https://www.haomeiwen.com/subject/qtqsoxtx.html