zoukankan      html  css  js  c++  java
  • Nginx 灰度实现方式(支持纯灰度,纯生产,50度灰及更多比例配置)

    前言

    Nginx相关技术短信本篇幅不做详细介绍,所以学习本文之前要对Nginx有相关的了解。

    生产环境即线上环境,在经历开发、测试再到上线,不可避免的会更新生产环境,但谁又能保证测试过的代码到线上运行就一定不会有问题?

    相信大部人都有相似经历,测试环境好好的代码,上了生产却可能发生问题,为何呢?

    因为环境不一样,最经常发生的情况可能是:新的迭代中数据库表结构发生了变化、数据初始化不一致、配置文件不一致。

    要如何避免这种情况呢,那就引入灰度模式,简单的说来就是模拟线上环境,即准生产环境,配置一致、数据一致,然后再看有没有问题,如果一切正常则上线,此时能kill掉99%可能出现的BUG(另外1%可能是硬件或网络问题,情况极少)。

    其实灰度模式不止这个好处,下面简单列举一下:

    1、做为内测环境,先对内部开放,功能是否达到预期要求,而不是上线让用户当小白鼠。

    2、做为备份环境,因为灰度的数据跟线上是一模一样,旦生产发生故障,可快速切换为灰度,保证有足够的反应时间来修复生产。

    3、作为负载均衡环境,当流量高峰时,可适当引流入灰度,以减轻生产压力。

    实现步骤

    一、配置结构

    Nginx的配置文件为:nginx.conf,这是主配置,我们另外新建二个配置文件:

    这二个文件其实是对nginx.conf的延伸,在nginx.conf中include进来的,放在与nginx.conf同级的目录下即可。

    它们主要定义一些全局变量,就是规则定义,一般情况下用到grey_cond.rules就可以了,如果配合项目管理工具(如jenkins发布),需要手动控制灰度规则,那么grey_cond_set.rules就起作用了。

    下面是这二个文件与nginx.conf的关系配置,我直接贴配置代码:

    http {
    
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;
    
    include /etc/nginx/mime.types;
    default_type application/octet-stream;
    
    log_format access '$proxy_add_x_forwarded_for $remote_user [$time_local] "$request" '
    '$status $body_bytes_sent $request_time "$http_referer" '
    '"$http_user_agent" '
    'upsteam: $upstream_addr';
    access_log /data/log/nginx/access.log access;
    error_log /data/log/nginx/error.log;
    
    gzip on;
    gzip_http_version 1.0;
    gzip_disable "msie6";
    
    gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
    
    include /etc/nginx/grey_cond.rules;
    include /etc/nginx/grey_cond_set.rules;
    include /etc/nginx/sites-enabled/*;
    }
    

    其中include /etc/nginx/sites-enabled/*;这是真正的业务规则,后面细说。

    注意:这里的顺序要保证灰度规则文件在业务规则之前,而且grey_cond.rules要在grey_cond_set.rules之前(保证手动控制能生效)。

    简单的描述为:全局规则--->手动规则--->业务规则。业务规则可覆盖手动规则,手动规则可覆盖全局规则,我们真正要实现的是业务规则,这样的顺序可以带来规则变化上的灵活性。

    二、定制灰度规则

    无外乎几种情况:

    1、根据请求IP制定规则,如内部用户访问灰度,外部用户访问生产

    2、根据特殊请求路径制定规则,如一个新功能上线,需要走灰度

    3、根据客户端制定规则,如ios还是android

    其他更多规则视具体情况而定。以下是本机示例:

    root@m1:/etc/nginx# cat grey_cond.rules 
    set $grey_cond  0;
    
    if ($http_x_forwarded_for = 115.228.193.20){
            set $grey_cond  1;      
    }
    if ($http_user_agent ~ "AppVersion/5.0"){
            set $grey_cond  1;       
    }
    
    if ($http_x_forwarded_for = 124.95.61.78){
            set $grey_cond  1;       
    }
    if ($http_x_forwarded_for = 134.188.193.83){
            set $grey_cond  1;
            set $sns_grey_cond  1;
            set $rocket_grey_cond  1;
    }
    
    if ($http_x_forwarded_for = 221.76.138.142){
            set $grey_cond  1;
            set $sns_grey_cond  1;
            set $rocket_grey_cond  1;
    }
    
    if ($http_user_agent ~ "Android"){
       set $grey_cond  1;  
    }
    ....

    上面示例代码中给了部分规则,如按IP地址(一般是公司内部的公网IP地址,如有多个配置多行即可)。

    三、定制动控制规则

    grey_cond_set.rules初始化可以是空,你可以把它理解成为一个临时性的文件,在需要时往里面写入一段nginx文本。

    根据上段介绍,这个文件中的变量是可以向上覆盖的,你可以手动编辑这个文件,或者通过jenkins执行命令写入,然后然后配合nginx reload来做文章。

      本机示例:

     1、初始状态 (可空)

    root@m1:/etc/nginx# cat grey_cond_set.rules 
    #Default beta testing policy.
    

    2、通过jenkins写入

             这个jenkins配置中,有一行脚本变量 为:-PpolicyFile=grey_cond_set.rules,正是我们说的那个临时文件,下面还有一行变量是要写入这个临时文件中的:-PpolicyString="set $grey_cond 1;",

             如果对jenkins不熟悉,可适当去了解一下,本文不做详情介绍。

             那么这个执行是怎么进行的呢,就是通过/var/lib/jenkins/buildscripts/build.gradle这个构建脚本来执行其中的deployPolicy方法,下面直接贴示例代码:

            

             

    [root@jenkins buildscripts]# cat build.gradle 
    buildscript {
      repositories {
        jcenter()
      }
      dependencies {
        classpath 'org.hidetake:gradle-ssh-plugin:1.1.4'
      }
    }
    
    apply plugin: 'org.hidetake.ssh'
    
    ssh.settings {
      logging = 'stdout'
    }
    
    remotes {
      javaServer {
        host = remoteHost
        user = remoteUser
            password = remotePassword
            knownHosts = allowAnyHosts
      }
      
      nginxServer {
        host = remoteHost
        user = remoteUser
            password = remotePassword
            knownHosts = allowAnyHosts
      }
      
      nodeJsServer {
            host = remoteHost
            user = remoteUser
            password = remotePassword
            knownHosts = allowAnyHosts
      }
    }
    
    .....
    
    task deployPolicy {
        def policyFile = project.properties['policyFile']
            doLast{
              ssh.run {
                    session(remotes.nginxServer) {
                        if(project.hasProperty('policyString')) {
                                    println "policy applied: '$policyString'"
                                    executeSudo("echo '$policyString' > /etc/nginx/$policyFile", pty: true)
                                    executeSudo("service nginx reload", pty: true)
                            }
                    }
            }
      }
    }
    
    .....
    

    这个脚本中标红的部分为核心,policyFile与policyString就是在jenkins中传进来的,下面二行executeSudo就是执行linux下的二个命令,一个是写入我们上面说到的临时文件,一个是重新加载nginx配置。

    四、常用规则

    10%的灰度:
    -PpolicyString="if ($http_x_forwarded_for ~ 0$){set $grey_cond 1;}"   
    50度灰:
    -PpolicyString="if ($http_x_forwarded_for ~ [0,1,2,3,4]$){set $grey_cond 1;}"   //这是一个正则匹配,ip以0,1,2,3,4结尾的就跳灰度
    纯灰:
    -PpolicyString="set $grey_cond 1;"
    纯生产:
    -PpolicyString="#Defaultbeta testing policy." //可以是空,也可以是一个注释性文本

      

    更多待续...

  • 相关阅读:
    青檬音乐台闲时听听电台吧
    [转]What is AOP?
    实现页面元素拖动效果的JS函数
    gorithms.算法概论.习题答案
    Asp.Net读取并显示Excel文件中的内容(OleDb方式)
    收藏的一些小软件
    Master Page Path (MasterPage 相对路径)
    rundll32 netplwiz.dll,UsersRunDll
    关于锁
    我的回帖保存
  • 原文地址:https://www.cnblogs.com/clonen/p/8023916.html
Copyright © 2011-2022 走看看