vivo 全球商城:优惠券系统架构设计与实践( 四 )


 
定向发券不同于用户主动领券 , 定向发券的量通常会很大(亿级) 。为了支撑大批量的定向发券 , 定向发券做了一些优化:
1)去除事务 。事务逻辑过重 , 对于定向发券来说没必要 。发券失败 , 记录失败的券 , 保证失败可以重试 。
2)轻量化校验 。定向发券限制了券类型 , 通过限制配置的方式规避需严格校验属性的配置 。不同于用户主动领券校验逻辑的冗长 , 定向发券的校验非常轻量 , 大大提升发券性能 。
3)批量插入 。批量券插入减少数据库IO次数 , 消除数据库瓶颈 , 提升发券速度 。定向发券是针对不同的用户 , 用户优惠券做了分库分表 , 为了实现批量插入 , 需要在内存中先计算出不同用户对应的库表后缀 , 数据归集后再批量插入 , 最多插入M次 , M为库表总个数 。
4)核心参数可动态配置 。比如单次发券数量 , 单次读库数量 , 发给消息中心的消息体包含的用户数量等 , 可以控制定向发券的峰值速度和平均速度 。
3.2.3 券码兑换
站外营销券的发放方式与其他券不同 , 通过券码进行兑换 。券码由后台导出 , 通过短信或者活动的方式发放到用户 , 用户根据券码兑换后获取相应的券 。券码的组成有一定的规则 , 在规则的基础上要保证安全性 , 这种安全性主要是券码校验的准确性 , 防止已兑换券码的再次兑换和无效券码的恶意兑换 。
3.3 精细化营销能力设计
通过标签组合配置的方式 , 优惠券提供精细化营销的能力 , 以实现优惠券的千人千面 。标签可分为准实时和实时 , 值得注意的是 , 一些实时的标签的处理需要前提条件 , 比如地区属性需要用户授权 。
优惠券的精准触达:

vivo 全球商城:优惠券系统架构设计与实践

文章插图
 
3.4 券和商品之间的关系
优惠券的使用需要和商品关联 , 可关联所有商品 , 也可以关联部分商品 。为了灵活性地满足运营对于券关联商品的配置 , 优惠券系统有两种关联方式:
a. 黑名单 。
可用商品 = 全部商品 - 黑名单商品 。
黑名单适用于券的可使用商品范围比较广这种情况 , 全部商品排除掉黑名单商品就是券的可使用范围 。
 
b. 白名单 。
可用商品 = 白名单商品 。
白名单适用于券的可使用商品范围比较小这种情况 , 直接配置券的可使用商品 。
 
除此以外 , 还有超级黑名单的配置 , 黑名单和白名单只对单个券有效 , 超级黑名单对所有券有效 。当前优惠券系统提供商品级的关联 , 后续优惠券会支持商品分类维度的关联 , 分类维度 + 商品维度可以更灵活地关联优惠券和商品 。
3.5 高性能保证
优惠券对接系统多 , 存在高流量场景 , 优惠券对外提供接口需保证高性能和高稳定性 。
多级缓存
为了提升查询速度 , 减轻数据库的压力 , 同时为了应对瞬时高流量带来热点key的场景(比如发布会直播结束切换流量至特定商品商详页、热点活动商品商详页都会给优惠券系统带来瞬时高流量) , 优惠券采用了多级缓存的方式 。
vivo 全球商城:优惠券系统架构设计与实践

文章插图
 
数据库读写分离
优惠券除了上述所说的分库分表外 , 在此基础上还做了读写分离操作 。主库负责执行数据更新请求 , 然后将数据变更实时同步到所有从库 , 用从库来分担查询请求 , 解决数据库写入影响查询的问题 。主从同步存在延迟 , 正常情况下延迟不超过1ms , 优惠券的领取或状态变更存在一个耗时的过程 , 主从延迟对于用户来说无感知 。
vivo 全球商城:优惠券系统架构设计与实践

文章插图
 
依赖外部接口隔离熔断
优惠券内部依赖了第三方的系统 , 为了防止因为依赖方服务不可用 , 产生连锁效应 , 最终导致优惠券服务雪崩的事情发生 , 优惠券对依赖外部接口做了隔离和熔断 。


推荐阅读