美文网首页
红包逻辑和状态处理

红包逻辑和状态处理

作者: 西5d | 来源:发表于2019-11-09 11:36 被阅读0次

之前写过一篇红包算法的内容,最后采用了微信的方案,没有使用预分配的方式。今天这篇会介绍下红包业务处理中的更多细节,以及过程迭代中遇到的一些问题和对应处理。

红包业务逻辑简述

首先,和微信红包一样,我在处理红包时,也先做状态检查,可客户端合作,在点击时,先做check,然后根据状态进行对应的操作。如是否过期,是否符合条件,是否已经抢过,以及最终可以抢红包的结果状态,返回列表,计算手气最佳等。这里有个比较特殊的是,一般红包是由用户自己触发,目前有限制,只有两次机会。还有一种是主动发送,称为定时奖励红包,是全量的。这个后面会详细说到。

红包逻辑和状态处理

红包ID

这里是比较复杂的一块,首先说下红包id的生成,用userId+chartId+timestamp+KEY => md5 生成,标记唯一的一个红包。加时间戳和userId, chartId也是为了验证,包括一个私有的KEY作为一定的安全防范措施,防止恶意生成和领取。

生成红包

  1. 生成id
  2. 根据策略生成红包数量,总金额 ,如群人数,固定的比例。
    2.1 获取群聊数量
    2.2 根据不同类型计算数目,金额
    2.3 保存红包记录。
    2.3.1 红包 id 为key, size 红包id + remainCoin作为两个值 ,存在Redis,过期时间为1天,数据只有红包数量和总金币,结构简单。Redis存储可以提供一致性和大的并发量,为后续抢红包做准备。
    2.3.2 保存数据库记录 。创建时间,名称,类型,消息。 发送者, 目标方,红包总数,总金额(不返回给用户)等,这里单独存储到数据库,做记录。
    2.4 返回红包结果
    注:这里用服务端返回给客户端结果,也可以考虑直接用Sdk作为消息发给客户端处理。

领取红包

分成两个步骤。
入参: 红包id,用户id, 群聊id, 创建时间
1 如上所述,先检查红包状态
1.1 根据红包id 查库, 获取红包,如果没有则记录不正确。
1.2 检查参数
查库拿到的红包创建者id 和 群聊id ,创建时间 再次生成红包id , 是否与参数红包id 相等,否则表示非法红包参数,这块作为安全验证。
1.3 检查状态
业务状态判断,这里是红包额外的一些业务限制检查,是否满足规定条件。
1.4 获取红包详情
根据红包id 从Redis获取, 红包 id + size 红包id + remainCoin 。 得到 该红包总数,总金额。
1.5 是否已空
该红包剩余的size 和 金币是否>0
1.6 获取红包领取记录
查询红包记录,通过红包id查询。
1.7 是否领取完毕
如果领取记录数 等于 1.4 获取的总数。 或者 1.5条件成立,则是已经领取完毕。
1.8 是否有当前用户领取记录
根据红包领取记录过滤,有当前记录则为有领取记录。
1.9 根据当前已知状态,最终返回状态。
红包非空 1.5 1.7
有当前用户记录 1.8
- 返回已经领取过。
没有当前用户领取记录 1.8
红包过期, 创建时间超过1天。 # 返回过期
红包没有过期 #返回可以领取。
红包已空 1.5 1.7
有当前用户记录
- 返回已经领取过
没有当前用户记录
红包过期, 创建时间超过1天。 # 返回过期
红包没有过期 #返回手慢了,领没了。
1.10 根据状态做对应的展示。

2 根据1中获得的状态,执行后续操作。
2.1 根据红包id 查库, 获取红包,如果没有则记录不正确。
2.2 检查红包参数 , 同1.2中处理。
2.3 查询领取记录
2.3.1 是否匹配到记录
2.3.2 红包是否过期
处理过期
过期:有匹配记录 - 返回消息为金币数
没有匹配记录 记录数等于红包总数 # 红包n个,已经抢光 , 标记手气最佳
- n个红包,已领取m个红包
最终返回状态为 # 过期
2.3.3 没有过期
2.3.4 检查是否足够时长
- 足够 继续
- 不足 返回状态为不足阅读时长
2.3.5 是否领取完毕
2.3.5.1 为空(总数==领取记录数)
如果记录包含当前用户,- 返回成功,用户金币数,已被抢光。
不包含当前用户 - 返回失败
标记手气最佳
检查是否领取过。
2.3.5.2 不为空,进行领取
1-1 记录包含当前用户 。
# 金币数 , 提示n个红包,已经领取m 个,状态为已经领取过
1-2 不包含当前用户
*********计算红包
得到单个金额
redis减少总数和金额,成功
减少成功,写入记录。增加金币,金币系统(加失败重试),最终失败回退 # 返回领取失败
返回剩余金币
- 返回
redis减少总数和金额,失败
状态红包已经被抢光
标记手气最佳
标记领取过

遇到的问题

以上比较仓促,细节对应到逻辑图会更好。红包自测试完备上线后,一直稳定运行,在1-3个月总数据量也到了千万级,不过限于业务限制,并发不高。其中定时红包在群总数逐渐增多后,遇到了几个问题。首先依赖的外部接口流控,导致很多超时,这块最后改为从本地的缓存获取每个群人数,目前看效果良好;其次,由于使用了一个封装好的Redis工具类,没有太注意相关参数,导致后面量增大之后,会有maxRedirection的异常,坑的是工具类的对应参数没法设置,只能自己做了更新,将底层jedis的maxAttempts修改为可配置,同时增大到10解决,之前是5,默认值;最后,定时红包按需求要保证100%的送达,目前遇到两个可能改进的点:一是在单机失败后,加到延迟队列或者在一段时间之后重试,这里延迟是防止当前压力过大,导致滚雪球效应。第二个是目前消息消息触发执行任务,有消息丢失的可能。这块看是否要自己支持结果回调,还是消息系统已经支持对应功能。

以上就是这篇总结,最近做的事,更加深入认识到业务量级所带来的不同挑战,同时也意识到做对应的技术积累和沉淀,未雨绸缪是很重要的事,否则只能被动,而且也不仅是个人,团队,部门,大到公司,集团都是如此,这是后话了。

相关文章

网友评论

      本文标题:红包逻辑和状态处理

      本文链接:https://www.haomeiwen.com/subject/iaggbctx.html