或许大家体验过抢红包,但如何对现实世界的业务场景进行抽象,形成软件系统的需求,进行建模与技术选型,这是有一套“方法论”的。来看看本文吧!
0 源代码结构
1 业务&模型概述
1.1 业务场景
通过移动互联网应用发红包成为了大众普遍的娱乐现象!
1.1.1 发红包场景
- 表白、祝福、庆祝、营销等非技术性名场面
- 装逼、曝光、知识付费提问等技术性场面
1.1.2 业务用例
- 发红包
- 抢红包
1.2 业务定义
1.2.1 所谓红包?
不过是定量的数量和金额的红包序列
- 红包是具备虚拟资金特征的特殊商品
- 收/发红包实际上是资金的交易过程
- 资金交易是资金从一个账户转向另一个账户的过程
1.3 业务模型
2 数据库建模
2.1 从业务领域模型到数据库物理模型
- 物理模型和逻辑模型保持一致,亦可不一致
- 不违背业务模型逻辑的前提下可以做优化
- 冗余、合并、拆分、异构
2.2 资金账户的表设计
2.3 账户物理模型-账户表和流水表结构
2.4 ?数据库物理模型
2.4.1 ?业务模型
2.4.2 合并的?物理模型
库存主要维护: 剩余金额和数量
因为相生相死,库存模型和商品模型可以直接合并,将库存字段放入商品模型
商品和订单也是相生相死,可以合并
商品和活动也是相生相死,都是一对一关系,可以合并
所以,最终优化为两个子模型
- ?物理模型概览
3 ?算法
3.1 ?序列
按照红包总金额和总数量计算拆分后的子红包集合
- 发红包时预置,预存储,直接取
- 收红包时实时内存计算,效率高,异步存储
- 采用收红包时生成红包序列的方式
3.2 ?算法
- 普通红包数量和单个金额固定,不需要算法计算
- 碰运气红包单个金额随机,需要算法来支撑
3.3 计算逻辑要求
- 保证所有人都能抢到红包,且不能出现金额0
- 每个人抢到的红包序列和 = 红包总金额
- 红包序列是随机的,序列元素之间差异性可以控制
- 大小分布可预期
- 尽可能降低性能损耗
3.4 二倍平均算法
- 算法代码
优点
无论红包数量多大,几率都一样
缺点
可玩性低,玩不了刺激,无太大的红包产生
4 负 库存/金额 问题
作为一个高并发资金交易系统,势必存在资金交易安全和事务问题
◆ 本质是要保证剩余数量和金额字段不能为负数 ◆ 事务行锁稳定可靠 ,但性能较差,且容易引发死锁
红包业务中剩余数量和剩余金额不存在负数的场景
◆ 将剩余数量和剩余金额字段类型设计为无符号整型 ◆ 乐观锁 ,在where条件中限制,降低开销 ◆ 总体性能比事务行锁高30% ◆ 无符号字段 乐观锁的方法 ◆ 资金账户转账业务逻辑中,支出时会涉及到资金扣减 ◆ 收红包时红包剩余数量和剩余金额的扣减场景中
5 架构演进
5.1 单一应用
随着业务量增加,进入下一阶段