一次运营配错活动的技术善后处理。

背景:

某日, 我们的业务开新城, 运营配错了一个冲单奖活动,原本是想配成月度冲单奖, 达到300单有奖。 但是错配为天天冲单奖。 结果任何骑手都不可能触发这个冲单奖励。  且运营直到6月26日才发现配错, 找到研发和产品要求做善后补救。 希望在对用户无感知的情况下, 完成线上数据修改和数据迁移。 

讨论运营事故善后处理方案:

大家先直观的拿出两个方案来, 1是在现有的活动数据基础上做修改。 2. 是创建一个新的活动记录, 并把旧活动的订单奖励数据平滑迁移到新活动上, 同时完成数据修复。 

最终确定方案2, 原因是, 方案1对线上数据改动量大, 改动条目太多达到几十万条, 容易出错,而且一旦出错, 数据将很难恢复。

方案2, 是新增数据, 几乎不改动现有活动数据。 而且由于运营引擎对发钱发券的操作都是幂等设计, 因此不需要编写线上数据修复脚本, 只需要重复消费订单相关的消息队列即可完成数据重建。 

对于发钱发券相关的业务, 我们优先考虑数据出错的风险, 工作量评估还在其次。 第二个方案兼顾工作量和风险, 数据出错时,回滚也很容易。 

风险评估:

讨论方案执行计划时,重点讨论了几种可能的意外情况

1. 消息队列重放的时候, 可能新数据和老活动数据不一致。 丢数据了。

预案: 消息队列第二次重放。 公司基础架构对消息队列服务的SLA是“不丢”, 但不保证不重复。  当讨论这个预案时, 我不觉得有被执行机会。

2. 消息队列重放的时候, 可能新数据和老活动数据不一致。 数据多了。 

讨论这个预案的时候, 基于消息队列不丢消息的考虑, 认为可能会由于我们现有系统的bug导致消息在处理时被丢掉。还有在处理时可能有新订单进入系统(凌晨2点后无订单)。 因此大家认为出现数据增多这种情况时, 如果增加的订单不多, 可以抽查看一下原因就可以了。

3.消息队列第二次重放失败

重放当前消息队列的上游消息队列。

执行方案

凌晨2点, 执行计划

1. 02:21 执行更新新活动的start_time为2018-06-25 00:00:00

2. 02:24 执行 删除6月25日创建的老活动,即更新status=5

3. 02:30 停止订单消息队列的消费

4. 02:31  激活新活动

5. 02:34 mq重新启用

6. 监控看到新活动里的订单数据持续增长。 

7. 期间三次调整了mq消费速度, 从200qps,一直调整到2000qps, cpu内存监控正常(也顺便做了压力测试)

8. 03.30 消费完毕, 开始数据diff。 发现新老活动的订单数据不一致。 新活动与老活动相比, 多了几百条订单, 少了1万多条订单。

9. 通过日志, 大家确认mq没有发送那几条老数据过来, 气氛紧张起来, 担心是mq丢消息。 

10. 04.14, 按照预案, 重新消费消息队列, 同时大家紧张地讨论可能的原因。

11. 04.20, 很快发现, 新活动里的订单数据在涨。大家猜测可能第一次回放消息的时候调整qps导致消息没发过来。 

12. 05:00, 老活动订单数据全部迁移完成,并发现多了200多单。 检查发现, 多的订单是由于系统bug, mq连续重试三次写库失败放弃重发。最终这些订单没有入库,而且没有监控报警。 

善后计划执行结果和行动:数据修复成功,并发现前面遗留的bug。 把mq重试次数改成2000次。 写库失败的地方加关键点监控报警,mq第一次重放少消息的问题报给基础架构定位解决。 

总结:

这次善后处理方案选择和执行计划, 事先经过了很多人几个小时的充分讨论和推演, 并且针对这次善后操作可能导致的各种意外情况准备足了预案。戏剧性的是,我们预想的意外情况也确实都发生了, 并通过事先准备好的预案解决。 最终数据diff确认本次善后方案执行成功。 

这次的善后处理真的是, 按部就班,有备无患, 处变不惊。是一次非常成功的best practise。

原文地址:https://www.cnblogs.com/realzjx/p/9233514.html