原则上来讲,每个版本都应该是支持灰度和可回滚的。本星期的发布意外地发现了一个这样的问题。
当次版本有一个数据表加了两个字段,并且是灰度发布的,只发了一台服务器,另一台维持老的版本。然而在生产上的灰度发现了这样的问题,落在老版本上的请求,处理出错,落在新版本上的请求处理成功。定位问题发现是 mysql 报错。
有一段 sql 语句是这样写的:
insert into A values(...)
落在新版本上时,我们执行这个 sql 语句是OK的,但是老版本上却报错了:values 里面的字段个数与表 A 的不一致!这个问题也是很好理解的。
问题很容易找到,但是这给发布造成了很大的困扰:本来是要灰度的,然而现在灰度报错了。那好,我们就回滚吧,但是,如果一旦回滚到老的版本,数据库也得回滚!数据库不回滚,那新老版本都会报上面那个错了!但是数据库回滚一般比较麻烦,因为没有现成的脚本,得手动改数据库,然而,生产上不允许直接手动更改数据库。需要提单走流程变更,而且需要部门领导审批。。。最后万幸的是,由于这个系统不涉及到交易,只是一个柜面展示的功能,所以运维组长评估后让我们全量发布了,这样就避免掉了问题。
最后问题虽然解决了,但是中间暴露出了发布不规范,评估能否灰度,评估版本变更对灰度的影响不到位等问题。这也是个经验和教训:版本变更一定要评估全面,是否支持灰度,是否能支持灰度,是否支持回滚。
像上面的情况,支持灰度是比较简单的,只需要在开发时,将那个 sql 语句写为:insert into A (...) values (...) 带上列名,就能轻松解决无法灰度的问题了。
谨记!