• home > OMD > TEST >

    灰度发布方案(2):nginx灰度发布实现方案

    Author:zhoulujun Date:

    ABTestingGateway,采用ngx-lua 实现系统功能,通过启用lua-shared-dict和lua-resty-lock作为系统缓存和缓存锁,系统获得了较为接近原生nginx转发的性能。

    Nginx是一款轻量级的Web服务器/反向代理服务器以及电子邮件代理服务器。

    nginx其是由Nginx核心加很多第三方模块组成,其最大的亮点是默认集成了Lua开发环境,使得Nginx可以作为一个Web Server使用。借助于Nginx的事件驱动模型和非阻塞IO,可以实现高性能的Web应用程序。

    而且OpenResty提供了大量组件如Mysql、Redis、Memcached等等,使在Nginx上开发Web应用更方便更简单。目前在京东如实时价格、秒杀、动态服务、单品页、列表页等都在使用Nginx+Lua架构,其他公司如淘宝、去哪儿网等。

    nginx灰度方案说明

    负载均衡策略:轮询(默认)、weight、ip_hash、fair(响应时间)、url_hash

    nginx实现的灰度系统中,分流逻辑往往通过 rewrite 阶段的 if 和rewrite 指令等实现,优点是性能较高,缺点是功能受限、容易出错,以及转发规则固定,只能静态分流。针对这些缺点, ABTestingGateway,采用ngx-lua 实现系统功能,通过启用lua-shared-dictlua-resty-lock作为系统缓存和缓存锁,系统获得了较为接近原生nginx转发的性能。

    ABTestingGateway

    基于动态策略的灰度发布系统

    • ABTestingGateway 是一个可以动态设置分流策略的灰度发布系统,工作在7层,基于nginx和ngx-lua开发,使用 redis 作为分流策略数据库,可以实现动态调度功能。

    • nginx是目前使用较多的7层服务器,可以实现高性能的转发和响应;ABTestingGateway 是在 nginx 转发的框架内,在转向 upstream 前,根据 用户请求特征 和 系统的分流策略 ,查找出目标upstream,进而实现分流。

    • ABTestingGateway 是新浪微博内部的动态路由系统 dygateway 的一部分,因此本文档中的 dygateway 主要是指其子功能 ABTestingGateway。动态路由系统dygateway目前应用于手机微博7层、微博头条等产品线。

    git地址:https://github.com/CNSRE/ABTestingGateway

    ABTestingGateway是在 nginx 转发的框架内,在转向 upstream 前,根据 用户请求特征 和 系统的分流策略 ,查找出目标upstream,进而实现分流。

    ABTestingGateway架构图

    功能列表

    • 支持多种分流方式,目前包括iprange、uidrange、uid尾数和指定uid分流

    • 动态设置分流策略,即时生效,无需重启

    • 可扩展性,提供了开发框架,开发者可以灵活添加新的分流方式,实现二次开发

    • 高性能,压测数据接近原生nginx转发

    • 灰度系统配置写在nginx配置文件中,方便管理员配置

    • 适用于多种场景:灰度发布、AB测试和负载均衡等

    • new feature: 支持多级分流

    对于ab分流功能而言,分流流程图如图所示

    ABTestingGateway

    ngx_http_geoip_module结合abtestingGateway

    ngx_http_geoip_module结合abtestingGateway实现基于城市的分流方案,无需在url里添加city参数

    原理: 安装ngx_http_geoip_module模块后,该模块可以通过请求过来的客户ip获取到客户端的相关信息,它提供了一些变量如:geoip_city。abtestingGateway里面可以通过在url里添加city参数来进行城市的分流(当然这里只是分流脚本对参数的约定,你可以修改脚本来使用其它的参数名),如果我们能在配置文件中设置好arg_city参数,那么就无需在url后面添加city参数了。

    实现方式: 在nginx.conf配文件中设置好$arg_city参数。

    server {
        listen 80;
        server_name abtest.zt-express.com;
        access_log logs/abtestingExample.com.cn_access.log main;
        error_log logs/abtestingExample.com.cn_error.log;
        proxy_redirect off;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504 http_404;
    
        set $redis_host '127.0.0.1';
        set $redis_port '6379';
        set $redis_uds '/var/run/redis.sock';
        set $redis_connect_timeout 10000;
        set $redis_dbid 0;
        set $redis_pool_size 1000;
        set $redis_keepalive_timeout 90000;
    
        #geoip_city是由ngx_http_geoip_module模块提供的
        set $arg_city $geoip_city;
    
        location /{
    
                error_log  logs/abtestingExample.com.cn_error.log debug;
                #content_by_lua_block {
                #  ngx.say(ngx.var.arg_city)
                #  ngx.print(ngx.var.arg_city)
                #}
                set $hostkey $server_name;
                set $sysConfig api_root_sysConfig;
                set $kv_upstream kv_api_root_upstream;
                set $backend 'abtestingExampleBackend';
                rewrite_by_lua_file '../diversion/diversion.lua';
                proxy_pass http://$backend;
        }
    
       location /city{
        return 200 str:$geoip_country_code;
       }
    }


    参考文章:

    https://github.com/CNSRE/ABTestingGateway/issues/68


    转载本站文章《灰度发布方案(2):nginx灰度发布实现方案》,
    请注明出处:https://www.zhoulujun.cn/html/Operation/test/2020_0810_8537.html