• Nginx系列(二)——流量分发管控


    本文最近更新于2020.6.7
    (一)灰度发布

    1.简单介绍
    Nginx的灰色发布可以通过nginx自带的split_clients模块对流量进行分发,按照一定的分发规则,同时提供多个版本的文件或应用服务,从而实现灰色发布.
    原理是通过对"${http_user_agent}AAA" (这个是浏览器版本+字符串AAA的意思)使用MurmurHash2算法进行哈希.以值4294967295为界,如果"${http_user_agent}AAA"最终返回的哈希值位于4294967295的前75%,则该请求发给130,如果是后25%则发给133
    可以参考http://www.ttlsa.com/nginx/nginx-ngx_http_split_clients_module/
    2.配置方法
    以下是我的nginx.conf配置:

    split_clients "${http_user_agent}AAA" $variant{  #这个$variant应该是一个相当于标签命名吧,方便下面proxy_pass使用
        75.0% 192.168.2.130:80;
        25.0% 192.168.2.133:80;
    }
    server {
        listen       80;
        server_name  localhost;
        location / {
             proxy_pass http://$variant;
    }

    3.验证
    因为这个涉及到访问百分比问题,纠结了好久怎么去验证,最终找到一个浏览器插件进行辅证
    我使用的浏览器是firefox浏览器,插件名为Random User-Agent
    通过切换不同的浏览器版本信息,实现变换http_user_agent的值,切换一个浏览器刷新一下页面,多进行几次就会发现返回的页面内容不同.
    还可以通过设置日志格式查看

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                          '$status $body_bytes_sent "$http_referer" '
                          '"$http_user_agent" "$http_x_forwarded_for"' "$variant" ;  #打印$variant的值
    access_log  logs/access.log  main;

    4.扩展知识
    所谓灰度发布就是在原对外服务的系统上,先让一部分用户使用待正式发布的服务版本,确认没问题后再进行逐步更替甚至全面更新.这也就是我们说的金丝雀发布.
    除了灰度发布外,还有蓝绿发布.和灰色发布只需要一套系统不同,蓝绿发布需要使用到两套相同系统,这两套系统处于共存状态.一套为正常对外提供服务的系统,我们称之为绿色系统,还有一套是不对外提供服务的系统,我们称之为蓝色系统.蓝色系统只用于做发布前的测试,测试过程中发现问题时直接修改蓝色系统,不影响用户使用.当蓝色系统修改到符合上线标准时,直接将用户切换到这个蓝色系统.切换到蓝色系统后,绿色系统仍保留一段时间,使得蓝色系统出现问题时可以快速切回绿色系统.直到确认蓝色系统正常运行后,才可以删掉原来的绿色系统.
    另外还有一个就是A/B测试,A/B测试和灰度发布和蓝绿发布不是一回事.灰度/蓝绿发布主要时为了避免新版本有BUG等,而A/B测试则是偏重于新发布的版本内容是否符合用户需求,例如一个经过验证的新功能通过A/B测试发布后,通过用户的反馈,从而决定是否要将该功能纳入正式版本中.
    采用什么发布方法,取决于具体需求.例如只有一台服务器的情况下,不适合使用灰度发布,因为使用灰度发布会导致出现问题后回滚比较麻烦,而应该采用蓝绿发布.相反,如果后台服务器有几十甚至上百台,那么建议使用灰度发布,因为蓝绿发布要求蓝色系统可以提供和绿色系统一样的对外服务能力,也就是说蓝色系统也需要用到很多台服务器.
    具体可以参考https://www.cnblogs.com/lijiaocn/p/9986880.html
    (二)根据区域管控流量
    通过GeoIP Module and Database实现,需要额外安装GeoIp数据库,并将其嵌入到Nginx.
    GeoIP Module and Database是一个IP地理位置库,根据位置库得到IP所在国家,从而对这些国家所在的IP流量进行管控,例如我们可以直接禁止美国的用户访问我们的服务器.更具体的,我们还可以实现到拒绝纽约市用户访问.
    这里我使用的是通过YUM安装的nginx,对其进行重新编译添加新的geopip模块
    步骤如下:
    1.重新编译安装
    添加geopip模块

    /usr/sbin/nginx -V    #首先我们确定nginx版本
    wget -c https://nginx.org/download/nginx-1.16.1.tar.gz    #我的是1.16.1版本,所以下载一个相同的版本进行编译
    tar -zxvf nginx-1.16.1.tar.gz 
    cd nginx-1.16.1/
    yum install geoip geoip-devel -y  #安装geoip
    ./configure --prefix=/usr/share/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --with-http_geoip_module  #在原编译配置上添加最后的geoip模块即可,这里我省略了部分配置
    make  #注意不能执行make install,否则原nginx会出问题,影响业务
    mv /usr/sbin/nginx /usr/sbin/nginx.bak  #原nginx可执行文件进行备份
    cp objs/nginx /usr/sbin/nginx  #新编译的nginx可执行文件代替现有文件
    make upgrade  #平滑升级
    /usr/sbin/nginx -V  #确认是否成功配置geoip模块

    2.配置nginx.conf
    在http{}模块内,添加以下内容,根据IP所处的国家,给其添加一个country_access标记.

    geoip_country /usr/share/GeoIP/GeoIP.dat;
        map $geoip_country_code $country_access {        #设置$country_access对应的值为1或0
            "CN" 0;    #ip来自中国,设置对应值为0
            "RU" 0;
            default 1;    #默认值为1
        }

    在server{}模块内,添加以下内容,当country_access为1时,返回403(禁止访问)

    if ($country_access = '1') {    #值为默认值时直接拒绝
                return 403;
            }

    3.验证
    CN对应值为0时

     CN对应的值为1时

     4.补充说明
    以上是针对国家区域进行的流量管控,貌似还可以对国家里具体的城市进行流量管控,这个还没实践,有兴趣的可以参考以下内容:
    https://www.nginx.cn/doc/optional/geoip.html
    (三)限制连接数
    限制连接。构建一个共享内存区域,限制打开的连接数
    1.配置
    http {
    limit_conn_zone $binary_remote_addr zone=limitbyaddr:10m;  #limitbyaddr为区域命名,10m应该是共享内存大小
    limit_conn_status 429;    #返回过多请求数代码429
    ...
    server {
    ...
    limit_conn limitbyaddr 2;  #使用limitbyaddr区域,连接数最大为2(这里只是一个举例,便于测试看到效果).则并发数超过2后,就会直接返回429
    ...
    }
    }

    2.验证

    ab -n 5 -c 5 -v 2 192.168.2.129/index.html    #使用ab工具进行压力测试,-n指定请求总数,-c指定并发数,-v指定返回的信息等级

    返回信息部分截图.可以看到,部分请求返回正常的页面内容,还有就是429状态码

    (四)访问限速
    使用rate-limiting模块进行限速。可用于防止拒绝式攻击
    http {
    limit_req_zone $binary_remote_addr zone=limitbyaddr:10m rate=1r/s;
    limit_req_status 429;
    ...
    server {
    ...
    limit_req zone=limitbyaddr burst=2 nodelay; #并发达到2后,立即实施延迟
    ...
    }
    }
    2.检验

    使用以下命令进行压测

    ab -n 10 -c 5 -v 2 192.168.2.129/index.html

    部分请求返回结果如下

    来看一下最后的压测结果

    10个请求中,失败了六个,只成功了4个.
    倒推一下,10个请求,并发数为5,那么也就是分为两次并发量为5的请求.每次并发为5,而我们nginx配置的最大并发为2,也就是说一次并发就会有3次报错,那么两次并发就是2*3=6次报错,和配置一致.
    (五)下载限速
    限制客户端下载带宽。
    location /download/ {
    limit_rate_after 10m;    #最大访问下载速度为10m
    limit_rate 1m;  #默认1m
    }
    未限速前

     限速后.

     可以看到,之前2秒就传输完了,先在需要几分钟,速度最快在10M左右,不过基本都是在1M左右

  • 相关阅读:
    Windows Vs2010 + Qt5
    Java基础1
    关键字volatile
    内联函数
    Const详解2
    模板特化
    引用
    旧代码中的"enum hack"
    angularjs之ngoption
    angularjs之向下一个页面传参
  • 原文地址:https://www.cnblogs.com/biaopei/p/12925284.html
Copyright © 2020-2023  润新知