背景
在项目发展的早期,为了简单方便,我们升级服务器端应用,一般会先将应用源码或程序包上传到服务器,然后再停掉老版本服务,启动新版本服务。由于此时,项目用户少访问量小,这样做通常不会有什么太大问题。但后面随着项目越来越大,用户越来越多,再这样做你会发现存在两个明显的问题。
1、在新版本升级过程中,服务是暂时中断的,在这期间,服务将不可使用。
2、如果新版本有BUG,升级失败,回滚起来将非常麻烦,容易造成更长时间的服务不可用。
为了解决上面这些问题,人们研究出了很多发布策略,如蓝绿发布、滚动发布等,下面要讲的灰度发布也是其中之一。
什么是灰度发布
灰度发布也叫金丝雀发布,其原理如下图所示:
用文字描述即在灰度发布开始后,我们会先启动一个新版本应用V2,但是此时并不直接将流量切过来,而是先让测试人员对新版本进行线上测试。如果测试没有问题,那么就将少量的(如图中的5%)用户流量导入到新版本上,然后再对新版本做运行状态观察,收集各种运行时数据。当确认新版本运行良好后,再逐步将更多的流量导入到新版本上。
在此期间,我们可以不断地调整新旧两个版本的运行的服务器副本数量,以使得新版本能够承受越来越大的流量压力。当最后我们将100%的流量都切换到新版本上后,就可以关闭剩下的老版本服务,完成灰度发布。
另外,如果在灰度发布过程中发现新版本有问题,我们可以立即将流量切回老版本上,这样,可以将负面影响控制在最小范围内。
如何实现灰度发布
实现灰度发布有多种方式,但总结起来有三类
- 基于IP
- 基于COOKIE
- 基于权重
如下是利用nginx对这三类的实现。
1、基于IP
我们利用LUA,先获取客户端IP,然后通过判断客户端IP的类型,来判断应该选择访问什么服务器。如果是客户端IP为公司出口IP,则反向代理到@client;如果不是,则反向代理到@client_test。如下:
2、基于Cookie
我们先定义三个upstream,tts_v6、tts_v7和default,然后查询Cookie键为version的值,如果该Cookie值为tts1,则转发到tts_v6;如果该Cookie值为tts2,则转发到tts_v7;如果该Cookie值既不是tts1,也不是tts2,则默认走default所对应的服务器。如下:
其中,192.168.3.81:5380所指向的服务器为运行新功能的服务器。
3、基于权重
我们定义一个upstream,设置三个服务器IP,其权重分别为5,3,1。我们先把新功能部署在权重为1的服务器上,然后使用ip_hash进行负载均衡。待权重为1的服务器运行没有问题后,就将新功能部署到权重为3的服务器。如此重复操作,最后将新功能部署到所有服务器上。如下:
总结
灰度发布虽然操作复杂,但在一定程度上保证了系统的安全与稳定。随着项目的不断发展,系统稳定越来越比完善功能更加重要。从长远来看,使用灰度发布利大于弊。