利用nginx+lua+memcache实现灰度发布

摘要:摘要: 利用nginx+lua+memcache实现灰度发布

一、灰度发布原理说明

灰度发布在百度百科中解释:

灰度发布是指在黑与白之间,能够平滑过渡的一种发布方式。AB test就是一种灰度发布方式,让一部分用户继续用A,一部分用户开始用B,如果用户对B没有什么反对意见,那么逐步扩大范围,把所有用户都迁移到B上面 来。灰度发布可以保证整体系统的稳定,在初始灰度的时候就可以发现、调整问题,以保证其影响度。

 

这里的用于WEB系统新代码的测试发布,让一部分(IP)用户访问新版本,一部分用户仍然访问正常版本,其原理如图:

timg (17).jpg

执行过程:

1、 当用户请求到达前端代理服务Nginx,内嵌的lua模块解析Nginx配置文件中的lua脚本代码;

2、 Lua变量获得客户端IP地址,去查询memcached缓存内是否有该键值,如果有返回值执行@client_test,否则执行@client。

3、 Location @client_test把请求转发给部署了new版代码的服务器,location @client把请求转发给部署了normal版代码的服务器,服务器返回结果。整个过程完成。

下面把安装配置过程详细说明。

 

二、安装配置过程详解

1、安装nginx

安装依赖包

yum-yinstallgccgcc-c++autoconflibjpeglibjpeg-devellibpnglibpng-develfreetypefreetype-devellibxml2libxml2-develzlibzlib-develglibcglibc-develglib2glib2-develbzip2bzip2-develncursesncurses-develcurlcurl-devele2fsprogse2fsprogs-develkrb5krb5-devellibidnlibidn-developensslopenssl-developenldapopenldap-develnss_ldapopenldap-clientsopenldap-serversmakepcre-develyum-yinstallgdgd2gd-develgd2-devellualua-develyum–yinstallmemcached

 

下载lua模块、lua-memcache操作库文件和nginx包

wgethttps://github.com/simpl/ngx_devel_kit/archive/v0.2.18.tar.gzwgethttps://github.com/chaoslawful/lua-nginx-module/archive/v0.8.5.tar.gzwgethttps://github.com/agentzh/lua-resty-memcached/archive/v0.11.tar.gzwgethttp://nginx.org/download/nginx-1.4.2.tar.gztarxvfnginx-1.4.2.tar.gz cdnginx-1.4.2/./configure--prefix=/soft/nginx/--with-http_gzip_static_module--add-module=/root/ngx_devel_kit-0.2.18/--add-module=/root/lua-nginx-module-0.8.5/makemakeinstall

 

拷贝lua的memcached操作库文件

tarxvfv0.11.tar.gzcp-rlua-resty-memcached-0.11/lib/resty//usr/lib64/lua/5.1/

 

配置nginx

#vim/soft/nginx/conf/nginx.conf worker_processes1; events{ worker_connections1024; } http{ includemime.types; default_typeapplication/octet-stream; sendfileon; keepalive_timeout65; proxy_next_upstreamerrortimeout; proxy_redirectoff; proxy_set_headerHost$host; proxy_set_headerX-Real-IP$http_x_forwarded_for; proxy_set_headerX-Forwarded-For$proxy_add_x_forwarded_for; client_max_body_size100m; client_body_buffer_size256k; proxy_connect_timeout180; proxy_send_timeout180; proxy_read_timeout180; proxy_buffer_size8k; proxy_buffers864k; proxy_busy_buffers_size128k; proxy_temp_file_write_size128k; upstreamclient{ server192.168.200.29:80; } upstreamclient_test{ server192.168.200.29:81; } server{ listen80; server_namelocalhost; location/{ content_by_lua\' clientIP=ngx.req.get_headers()["X-Real-IP"]ifclientIP==nilthen clientIP=ngx.req.get_headers()["x_forwarded_for"] endifclientIP==nilthen clientIP=ngx.var.remote_addr end localmemcached=require"resty.memcached" localmemc,err=memcached:new()ifnotmemcthen ngx.say("failedtoinstantiatememc:",err) return end localok,err=memc:connect("127.0.0.1",11211)ifnotokthen ngx.say("failedtoconnect:",err) return end localres,flags,err=memc:get(clientIP)iferrthen ngx.say("failedtogetclientIP",err) return endifres=="1"then ngx.exec("@client_test") return end ngx.exec("@client") \'; } location@client{ proxy_passhttp://client; } location@client_test{ proxy_passhttp://client_test; } location/hello{ default_type\'text/plain\'; content_by_lua\'ngx.say("hello,lua")\'; } location=/50x.html{ roothtml; } } }

 

检测配置文件。

#/soft/nginx/sbin/nginx-t nginx:theconfigurationfile/soft/nginx/conf/nginx.confsyntaxisok nginx:configurationfile/soft/nginx/conf/nginx.conftestissuccessful

 

启动nginx

/soft/nginx/sbin/nginx

 

启动memcached服务

memcached-unobody-m1024-c2048-p11211–d

 

 

三、测试验证

测试lua模块是否运行正常

访问http://测试服务器ip地址/hello。如果显示:hello,lua 表示安装成功。

 

在另一台测试机(这里是192.168.200.29)设置两个虚拟主机,一个用80端口是执行正常代码,一个是81端口执行灰度测试代码。

 

在memcached中以你的客户机IP地址为key,value值为1。这里我的IP是192.168.68.211.

telnetlocalhost11211Trying::1... Connectedtolocalhost. Escapecharacteris\'^]\'. set192.168.68.2110011STORED get192.168.68.211VALUE192.168.68.211911END quit

 

 

注意:

set后第一个值为key值。

192.168.68.211这是key值是需要灰度测试的IP地址;

0 表示一个跟该key有关的自定义数据;

3600 表示该key值的有效时间;

1 表示key所对应的value值的字节数。

 

下面访问Nginx,效果符合预期,我的IP已经在memcached中存储值,所以请求转发给执行灰度测试代码的主机。

从memcached删除我的主机IP值。

再次请求Nginx,请求转发给执行正常代码内容的主机。

 

整个配置并不复杂,整个判断过程对服务的影响非常小。如果需要使用这个系统最好自己看看lua脚本。