灰度发布方案(2):nginx灰度发布实现方案
Author:zhoulujun Date:
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-dict和lua-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,进而实现分流。
功能列表
支持多种分流方式,目前包括iprange、uidrange、uid尾数和指定uid分流
动态设置分流策略,即时生效,无需重启
可扩展性,提供了开发框架,开发者可以灵活添加新的分流方式,实现二次开发
高性能,压测数据接近原生nginx转发
灰度系统配置写在nginx配置文件中,方便管理员配置
适用于多种场景:灰度发布、AB测试和负载均衡等
new feature: 支持多级分流
对于ab分流功能而言,分流流程图如图所示
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