发红包问题
这是一篇与同事(下文用"neptunezx"代替) 交流的心得。
简单限制下讨论的范围: 1、编程语言为 PHP; 2、操作系统为主流 linux 服务器操作系统; 3、不使用 kafka、rabbitMq 等消息队列;
neptunezx 问:weizeng ,rti 系统那边的红包怎么实现的?
weizeng 答:这个我懂,语言栈是 java,根据 HTTP Request 打过来的积分总数和红包个数字段,rand 函数搞定红包分配,再放到 java 的内存队列里,然后等待用户 pop 即可!
neptunezx 问:有没有更好的实现方式?
weizeng 答:应该有,emmmmm~上面一段对话后面省略一万字,根据当时的讨论,发现抢红包问题里面的门道真是多!接下来主要分析下列问题:
1、发红包的数据结构应该怎么设计?
2、根据1,红包算法如何实现?(只考虑随机红包)
3、如果优雅的记录用户抢红包的记录?
4、如果使用内存型数据库(redis、mongoDb等),如何解决抢红包过程的负载问题?
5、随着业务增长,未来可能出现分布式架构,如何解决分布式架构下的抢红包问题?
挨个儿讨论,问题1:
首先考虑当前的业务量,如果业务量比较小,Redis 资源上比较充裕,若是恰好时间比较紧张,可以选择如下简单设计:
设计1:根据红包总数和红包金额,用 rand 函数计算每一个红包应该放多少钱,组成队列存入 Redis,抢红包过程中直接 POP 操作即可,相信我,普通情况请直接选它;
优化:
设计2:将上下文获得的红包总数和红包总金额存入 Redis,在抢红包的过程中一边计算一边抢红包,这种方法的瓶颈在抢红包的过程中需要实时计算本次红包应该抢多少?
对比一下,1 在设计上需要更多的存储空间,只是将红包的计算逻辑提前到红包创建过程中而已,所以设计2 当选问题2: 贴一段简单的代码,这里时间问题先不做过多的优化,回头有时间这里专门聊聊!
问题3:
问题4:
Swoole扩展 快速导航按钮!
// TODO
问题4,扩展问题: App 与 redis 同步在优化之后可能会出现一个非常尴尬的情况,如何保证稳定性?
举个例子完善下上面的问题,App 在内存中操作红包数据,按照之前的方案,需要有一个独立的进程实现 App 数据到 Redis 数据的同步, 大家也都比较清楚写程序最困难的部分是错误的处理,如何优雅的保证极端情况(网络抖动过于剧烈、程序crash等等)下 App 和 Redis 的一致性?
问题5:
Last updated