需求分析案例:生日送券事故与需求优化

本文介绍一个生日送券需求,因为考虑不充分引发的事故,及后续不使用技术优化方案,改用需求优化方案的过程。
该事故大概在2019年左右,相关数据已经不太确定了,仅供参考。

1、事故前因

一个互联网的餐饮系统,拥有几千万的注册用户。
大概在8,9月份,产品为了激活老顾客,提升用户留存,提出了一个需求:给注册用户发生日券,
具体一点,就是在每个用户的生日前第7天,给用户赠送一张生日券,并发送微信通知。
这个需求并不复杂,开发加测试大概2周左右就上线了,并且上线2,3个月一直运行稳定,用户能成功收券,成功消费。
当时的代码逻辑大概如下:

  • 新建一个Job,每天0点启动执行一次
  • 根据SQL找出所有所有第7天后过生日的用户,SQL伪代码大致如下:
    select id, wx_openid, username from users where birthday=now+7
  • 遍历这些用户,依次执行:
    • 判断该用户未赠送生日券;
    • 生成生日券,并插入用户券表;
    • 发微信推送消息。
  • 结束,等第2天再执行
    在这里插入图片描述

2、事故发生过程

在12月25号早餐时间段,该餐饮系统的支付模块出现告警,且出现大量支付超时。
经初步排查,票券模块的API响应很慢,都在数秒甚至几十秒以上;
进一步排查,是票券模块的数据库出现了大量死锁和慢查询:

  • 死锁是插入生日券的事务和查询、核销业务发生冲突;
  • 慢查询是券表数据量在几小时内增加了上千万行生日券数据;

处理措施,就是先停止送券Job,增加相应索引,故障排除,具体的排查和处理过程就不细说了。

因为是支付模块出错,又是圣诞节出现大量用户投诉,属于重大生产事故。
事后复盘原因:

  • 用户注册时默认生日为1月1日,大量用户使用默认值注册,未修改,导致1月1日过生日的用户数占70%以上(数千万);
  • 串行发券,且要微信推送(没有异步),导致特别慢,持续到白天Job还未完成,用户进来引发大量死锁;
  • 用户券表的数据,从百万级突增到千万级,一些原来很快的查询,因为缺乏有效索引变慢查询,引发雪崩效果。

3、事故优化方案

根据复盘原因,内部讨论了一些技术解决方案:

  • 批量发券,而不是一个一个用户去INSERT;
  • 通过内存事件或消息中间件,异步处理微信推送;
  • 复盘所有票券业务SQL,清理慢查询;
  • 定时备份和清理过期未使用的票券数据;
  • 用户券表分表,比如:按用户ID对100取模分100张表

这些方案中,前3个还ok,并安排去推行了;
第4个可能影响业务,用户查不到历史数据;
第5个分表改造工作量太大,工期会比较长,先列入待办,后续安排。

4、需求优化方案与实现

后面经过反思,这个送券需求的一些关键点:

  • 数千万用户时,有80%是非活跃用户,他们的生日券基本上是用不到的;
  • 生日券的有效期是7天,过期作废,不能再使用。

经过内部反复的讨论和思考,最终得到一个产品解决方案,需要做一定的需求变更,大致思路:
要给用户发的券单独存储,用户进入时提醒用户领取,未领取的券则作废,这样用户券表就不会出现大量无效数据了。
后面找产品经理沟通和确认,需求变更影响的2个点:

  • 增加了用户的点击领取行为,有一定体验损失;
  • 未领取的券,用户是看不到的,而原来可以看到过期状态;
    注:要看也是可以的,有一定开发工作量,性能上没啥问题。

经过评估,觉得体验问题可接受,未领取的券就不需要让用户看到,决定实施该方案,
最终需求实现和技术落地步骤如下:

  • 新增数据库表:待领取券表,字段与旧的用户券表一致;
  • 给用户发券时,插入新的 待领取券表,并进行微信推送;
  • 用户点击推送消息 或 登录进入系统时,如果有 待领取的券时,弹出消息:您是否要领取这张券;
    用户点击领取后,才把这张券,插入用户券表,并记录领取日志;
  • 待领取券表 的过期数据,及已领取的数据,定期删除(可以考虑备份,看业务需要);

因为这个需求变更,不仅仅可用于生日券,也能用于其它的优惠活动,
这个改造上线后,用户券表的数据增长情况,降低了80%以上,也就不需要再考虑分表的技术行为了。

5、反思

通过这个需求优化,引申了几点:

  • 技术人员要深入理解业务,并成为业务领域的专家,才能做好产品;
  • 经验的积累,对后续的产品需求、问题都有指导意义,能成为直接或间接的解决方案参考;
  • 技术方案没有银弹,这个案例里,分库分表并不是最佳方案;
    直到我离职,这个用户券表,都没有再去做分表的工作,也从来没出现性能问题;
  • 最有最好的方案,只有相对合适的方案。

6、后记

这个需求优化方案出来后,一开始还挺开心,
后面在使用美团、淘宝、麦当劳之类的APP时,突然意识到,它们早已经是按这种方案进行落地的了,
比如双11,淘宝都会弹窗让你领券;麦当劳每周都会弹窗让你领券;

以前用这些APP,只是下意识的点击领券,内心偶尔还吐槽为啥要领一次,从来没有深入思考过为什么,
自己有了类似案例,才意识到其中的亮点。

果然应了那句话:
有时你的顿悟,只是别人的基本功。

出现问题先参考其它产品的解决方案,站在巨人的肩膀上前行。

猜你喜欢

转载自blog.csdn.net/youbl/article/details/131355430
今日推荐