数据灰度发布中碰到的一个坑

在一个产品研发过程中,一般在发布前都有线下测试阶段,那么是不是线下测试验证通过后,就可以直接将产品的新代码发布上线,覆盖原来的版本呢?这样做其实有很大的风险,因为线下测试的运行环境和线上环境不是完全一致的,可能线下运行OK,到线上就出问题;另外,对于用户体验方面,在线下测试阶段的用户是不全的,只有测试、开发和PD等人,他们的体验不能完全代表线上的大量用户。另外还有性能方面的原因等等。所以,一般线下测试通过后,在发布阶段会采用灰度发布的方式,选用线上的部分服务器部署新代码,剩下的服务器仍然部署老代码,然后进行引流,部分请求采用部署了新代码的服务器处理,剩下的请求采用仍然部署着老代码的服务器处理。经过一段时间的线上观察,没问题后,再更新所有的服务器。

本文要说的是数据方面的灰度发布,先介绍一下项目背景:项目中,需要新建一个表,原来已发布的api通过新建的管控平台发布后,api配置数据会落在新表里。系统发布后,需要将原来老表中已存在的几十个api通过新建的管控平台进行发布。为了降低风险,采用灰度发布,即不是一次性发布完所有的api,而是慢慢切换,一个api发布后,经过线上观察OK后,再接着发布下一个api。这样就导致在运行过程中,api的数据会来自两个表,部分来自老表,部分来自新表。

灰度发布中忽略了一个问题,由于新的发布顺序和老的发布顺序不一致,会导致老表和新表中不同名称的api可能会具有相同的主键id,譬如:老数据中,名称为A的api是第一个发布的,所以在老表中的主键id就为1,B是第二个发布的,则主键ID就为2;而在新数据中,B是第一个发布的,所以在新表中的主键id就为1,A是第二个发布的,所以在新表中的主键id就为2。因此,在老表和新表中,A和B的主键id都为1。不幸的是,系统中就有其他地方根据主键ID来查询api的功能,这样,对于同一个id,就会对应两条不同的api,导致业务异常。

规避方案:

  1. 新表中的api的发布顺序与老表中保持一致
  2. 新表中的主键初始值>老表中的最大主键值;

       在发布前,可以采用以上两种方案的任何一种。但如果发布前没有意识到主键冲突的问题,没有采用以上两种方案,则发布后的紧急解决方案就是:立即将导致主键冲突的老表中的api发布,使之移到新表中。在成功发布前,如果仅仅只是读操作,那还比较幸运,只会产生一定量的错误日志,但如果还有写操作,那就悲剧了,会产生脏数据,这时候就需要数据订正了。

本文为原创,转载请注明出处

相关推荐