灰度发布,已经不是一个很新的概念了.一个产品,如果需要快速迭代开发上线,又要保证质量,保证刚上线的系统,一旦出现问题那么可以很快的控制影响面,就需要设计一套灰度发布系统.
灰度发布系统的作用在于,可以根据自己的配置,来将用户的流量导到新上线的系统上,来快速验证新的功能修改,而一旦出问题,也可以马上的恢复,简单的说,就是一套A/BTest系统.
它大抵的架构,应该是类似这样的:
其中分为几个部分:
关于接入策略的设计上,从协议层来说,需要从一开始就设计是根据哪些参数来进行转发的,而且这些参数最好跟具体的协议体内容分开,这样减少接入层对协议的解析.举个例子,如果客户端的请求是走HTTP协议的,那么将这些参数放在HEADER部分就好了,接入层不需要去具体解析body部分的数据就拿到了转发策略需要的参数.当然,放在HEADER中的数据,因为没有了加密性,又是需要考虑的另一个问题.
当然,最简单粗暴的转发策略,可以根据客户端ip地址来做,这是比较粗略的一个划分策略.
同样的,新旧服务器要对新旧客户端的协议兼容,也是能做到灰度发布的根本,如何设计一个扩展性好的应用协议,这一点就不在这里考虑了.
接下来,还需要满足如果管理后台下发了新的转发策略,接入层应该是可以马上感知到然后切换到这个新的策略来的.有好些不同的做法.假如接入层是Nginx这样的服务器,使用者只是在上面写了自己的Nginx模块来实现策略的转发,那么可能还需要在每台接入服务器上部署一个Agent的服务,主要用于:
如果接入层不是Nginx这样的服务,那么也可以做一个pub-sub模型的订阅者,用ZK或者Redis都可以,订阅管理后台下发的服务进行处理即可.
上周写完灰度发布系统相关的博文之后,有朋友表示灰度系统的实现太过简单了,因为我目前接触的系统确实比较简单,很多复杂的东西没有考虑周全,如果更大型的业务系统,涉及到的服务更多,还有如果掺杂着数据的迁移,就更复杂了.这里就把当时讨论的内容提取出来,主要的贡献者为滴滴的沈佳伟.
1.调用链上有多个业务服务的场景
考虑这样一个业务场景,假设对外提供了服务A给客户端访问,服务A后面会调用服务B,C,D,此时需要上线一个功能,这个功能涉及到了服务A,C的修改,但是服务B,D不需要变动,换言之,我们的意图是,如果一个客户端请求,走到了新的灰度服务A,那么最终这个请求也应该走到这次和A一起灰度的服务C上.
这里的处理策略,可以给客户端请求进行tag打标记的方式,比如经由新版本服务A处理的请求,全部打上tag A,而在服务C上,也有接入层进行转发,它转发的策略之一就是根据根据这个tag来进行转发,这个系统如下图所示:
上图中,请求首先走到了旧版本的服务A上,该服务没有对请求打上tag,所以后续访问的都是没有配套灰度的旧版本C服务.
上图中,请求首先走到了新版本需要灰度的服务A上,在经过该服务处理后,给请求打上了tag A,由于带上了tag,后续访问的都是配套灰度的C服务.
简单的总结下,涉及到一个调用链路上某几个服务需要灰度的情况,可以通过tag的方式,将走灰度服务的请求汇集到一起来,如果一个请求走到了一个灰度路径上,就打上一个tag,这样只有有这个tag的请求才能走到这条链路上后续也需要一起灰度的服务上.至于如何给请求打tag,如果是HTTP协议,那就很简单了,也是加Header的方式,否则需要在设计协议的时候就考虑协议的扩展性支持这个操作.
2. 涉及到数据的灰度服务
假设灰度的服务,需要使用到数据库,如果灰度前后数据库的字段保持不变,那么新旧两套系统使用同一套数据库就可以了.
如果前后数据不一致,需要处理的情况就比较复杂,分为以下几种情况.
在部分灰度的情况下,有部分请求到旧系统上,另一部分请求到了新的灰度系统上.走到旧系统的请求,还是照原样处理.但是走到了新版灰度系统的请求,需要同时将请求转发给旧系统上来对应的接口上修改旧系统的数据.如果走到新系统的请求查不到该用户的数据,还需要首先同步一份来新系统上.如果是事务性的请求,以写入老系统成功来做为操作成功的标准.
在灰度系统已经全部接管了线上流量之后,为了安全起见,仍然需要对新老系统进行双写,步骤和前面一样.
灰度完成与前面的全量灰度状态不太一样,区别在于前面的全量灰度状态下,仍然不能肯定系统一定是没有问题的,所以需要进行新旧系统的双写来保证数据可以在老系统上进行回滚.而在灰度完成状态,此时认为这个新版本已经完全通过了验证,无需再写入旧系统了.但是此时可能存在部分在灰度期间没有上线的用户,此时需要做一次同步,从旧系统上将这部分数据同步过来.
可以看到,这三个状态下,对新旧系统是否进行双写,做了严格的区分,目的只有一个:一旦新上线的系统出现问题,可以马上撤掉灰度系统,而这期间用户的任何修改在旧系统上都是可以找到的.
苹果的灰度发布
好多人觉得分阶段发布会不会影响发布更新周期?
这里,苹果也有很严谨的解释说明:
通过自动更新的分阶段发布,您可以在 7 天内依序向已打开自动更新的用户发布此更新。请注意,所有用户仍可从 App Store 手动更新至此版本。您可最多暂停分阶段发布 30 天,或随时向所有用户发布此更新
一、关于自动更新分阶段发布的一些说明
1.启动后,版本更新将会在一个 7 天的时间段内按百分比发布给已打开自动更新的 iOS 用户。
2.在分阶段发布期间每天完成自动更新的用户的百分比将显示在iTunes Connect中。
3.所有老用户仍然可以直接从App Store手动更新应用,而新客户将始终看到最新版本。
4.如果发现版本更新中发现有问题,可以随时暂停分阶段发布,总共最多30天,而不管暂停次数。版本更新暂停超过30天后,发布将在暂停的那一天恢复,将无法再次暂停发行。
5.在分阶段发布期间中,也可停止发布阶段性的应用,选择发布给所有已打开自动更新的用户。
6.分阶段发布不能选择特定的人群(如年龄、性别,领域或设备信息,如操作系统版本或设备类型),为随机选择。
7.在分阶段发布期间,开启自动更新的用户完成自动更新,用户不会受到通知。
二、自动更新的分阶段发布的步骤
1.从iTunes Connect 主页,单击我的应用程序,然后选择您的应用程序。
2.在左侧列中,点击要提交的应用版本。
3.在“自动更新的分阶段发布”部分中,选择使用分阶段发布的7天内的“发布更新”。
4.单击保存。
三、在分阶段发布期间每天完成自动更新的用户百分比如下,百分比为固定的,不可更改。
四、自动更新的分阶段发布的利弊
利:
1.发现新问题,可及时暂停分阶段发布,将损失降到最低。
2.加速产品的发布进程,减少测试周期。
弊:
1.只能选择老用户更新时的灰度,也就是说新用户安装的都是新版。
2.在群体的选择上是随机的,抽到的用户不能代表全局用户特征,统计误差不定,有可能很大,也有可能很小。
3.灰度发布的新版本一旦出现问题是无法回滚的,在修复版开发完成重新发布审核上架之前,已经更新的用户只能继续用bug版本。
4.只能做较大的灰度测试,无法针对功能较小模块甚至代码片段做灰度。
Android平台做灰度再合适不过了。
找单一渠道投放特别版本出去是一个思路。另一个是做升级平台的改造,允许针对部分用户推送升级通知甚至版本强制升级。
无论哪种方法都需要做好版本管理工作,分配特别的版本号以示区别。
当然,既然是做灰度,数据监控(常规数据、新特性数据、主要业务数据)还是要做到位,该打的数据桩要打。
还有,灰度版最好有收回的能力,一般就是强制升级下一个正式版。自己做产品时也有类似的需求,下边是我的方案:)
基本的逻辑是两个版本的代码都打到app包里,然后在app端植入测试框架,用来控制显示哪个版本。
测试框架负责与服务器端api通信,由服务器端控制app上A/B版本的分布,可以实现指定的一组用户看到A版本,其它用户看到B版本。
服务端会有相应的报表来显示A/B版本的数量和效果对比。
最后可以由服务端的后台来控制,全部用户在线切换到A或者B版本~
所以这个也可以用来做灰度发布 :)
另外由于打进去两个版本的代码,app的包体积会大一点(这和功能变化多少有关)
iOS:官方的测试平台有Testflight,已经被苹果收购,但是整个内测用户邀请的方法流程还是没有打通,邀请用户成本比较高,是通过添加用户邮箱的方式,收到邀请邮件后还需要用户按步骤下载tf,下载应用等,没有一套教学视频普通用户还是难以接受。但非常适合在新产品发布前使用一些运营手段去建立这个用户群。用户一旦完成第一次操作,以后更新就像appstore一样简单。对开发者来说,操作也是和appstore一样的。比较方便。
且一个公司有多款产品的话,使用这个成本也会稍低一些,不过最大的问题还是灰度的用户量,和后期用户的消亡管理和扩充
还有一个是如果有打不同的iOS渠道包(除了appstore还有其他越狱渠道)或者其他tag的话,也可以通过升级配置来指定灰度发布。
原文连接http://www.cnblogs.com/strinkbug/p/7078851.html
原文连接http://www.cnblogs.com/someonelikeyou/p/7238470.html
原文连接http://blog.csdn.net/weiwangchao_/article/details/52589615