场景
当版本切换的时候,后端服务器不可能瞬间同时进行代码更新,这样就会出现客户在短暂时间内访问到不一样版本的服务。前端
使用如下流程能够避免上述问题:
1.后端设立两个的主机组(A_CLUSTER,B_CLUSTER),以及一个ALL_CLUSTER包含两个主机组提供服务。
2.当要发布前,将全部的流量切换到B_CLUSTER。
3.切换完毕后升级A_CLUSTER代码。
4.将流量再切换到A_CLUSTER。
5.再升级B_CLUSTER的代码。
6.最后将流量再切换至两CLUSTER。nginx
要完成上述操做,在代码更新方面有jenkins等发布工具来实现。但前端切换流量的在传统中只能经过手动修改nginx配置文件来实现。redis
openresty提供了一个可编程的nginx,经过lua能够实现对于nginx的”在线修改”,从redis获取信息从而选择将请求发送到后端指定的upsteam。而如何指定所须要的upstream?这时就须要redis,或者其余的中间件或其余lua能够调用的接口来实现。编程
准备工做
1.安装redis
2.安装openrestry
3.安装lua
4,安装lua的redis驱动后端
配置分享
nginx.conf:服务器
http { lua_shared_dict vtimes 10m; upstream a_cluster { server 192.168.1.200:8888; } upstream b_cluster { server 192.168.1.203:8080; } init_by_lua_block { cache = ngx.shared.vtimes cache:set("times",1000) redis = require "redis" client = redis.connect('127.0.0.1', 6379) local cluster = client:get("usCluster"); cache:set("cluster",cluster); } server { listen 8080; location ~ /vtimes/ { content_by_lua_block{ cache = ngx.shared.vtimes; times = cache:get("times"); ngx.say(times); } } location / { set_by_lua_block $upstream{ cache = ngx.shared.vtimes; vtimes = cache:get("times"); if(vtimes > 0)then cluster = cache:get("cluster"); vtimes = vtimes - 1; cache:set("times",vtimes); return cluster; else redis = require "redis" client = redis.connect('127.0.0.1', 6379) local cluster = client:get("usCluster"); cache:set("times",1000); cache:set("cluster",cluster) return cluster; end } proxy_pass http://$upstream; } }
配置说明
1.若是每次访问都须要访问redis,这将致使效率降低。运维
2.基于第一条缘由,咱们设定这样一个机制,每1000次(这个数值能够本身设定),从redis中获取指定的upstream数值,而后保存在内存中,并使用这个设定。ide
3.这样除了须要在redis中保存数据,还须要在openrestry中保存当前upstream以及访问次数的数据。工具
4.lua_shared_dict vtimes 10m;开辟了一个共享内存空间,能够将数据以key-value形式保存到内存内。ui
5.创建两个upstream,这里做为演示就作的比较简单,事实上能够作无数多个,用于指定。
6.init_by_lua_block;用于初始化数据,在程序启动前,就从redis中获取设定的访问upstream,以及设定访问次数。
7./vtimes/;用于查看访问次数,当次数到达0以后,openresty将从新获取配置。固然也能够配置一个用于清零这个计数器的接口。
8.set_by_lua_block $upstream 这里经过lua脚本给变量upstream赋值(计算的方法上文中已经明确说明过),并将这个值做为proxy_pass的参数,实现自动切换。
9.控制流量切换的是redis中的key:usCluster,将它设定为a_cluster或者b_cluster就能实现流量切换。在本身的运维平台上层再实现业务逻辑提供了很大的便利和可能。完善在线发布的流程。