【Java】微信抢红包的功能是如何实现的,如果让你来做你怎么设计?

高并发系统设计 -- 抢红包设计 可以明显的看到打开了红包不一定可以抢到。预拆包:我在发红包的时候,就已经把所有的东西都计算好了放在redis里面了。实时计算:在抢红包的时候进行现场计算。我选择的时把红包提前拆好,虽然提前拆好需要占用Redis的一些存储,但是这样可以让抢红包的速度到达最快。 阅读详情

一、问题解析

实现拼手气红包算法,有以下几个需要注意的地方:

  • 抢红包的期望收益应与先后顺序无关
  • 保证每个用户至少能抢到一个预设的最小金额,人民币红包设置的最小金额一般是0.01元,如果需要发其他货币类型的红包,比如区块链货币或者积分,需要自定义一个最小金额。
  • 所有抢红包的人领取的子红包的金额之和加起来,等于发红包的人发出的总红包的金额。 下面实现的方式是一次生成所有的子红包,让用户按顺序领取。也可以每领取一个生成一个,两种方式性能上各有优劣。

37.1 抢红包设计常见问题

37.1.1 微信的金额什么时候算?

答:微信金额是拆的时候实时算出来,不是预先分配的,采用的是纯内存计算,不需要预算空间存储。 采取实时计算金额的考虑:预算需要占存储,实时效率很高,预算才效率低。

37.1.2 实时性:为什么明明抢到红包,点开后发现没有?

答:2014年的红包一点开就知道金额,分两次操作,先抢到金额,然后再转账。 2015年的红包的拆和抢是分离的,需要点两次,因此会出现抢到红包了,但点开后告知红包已经被领完的状况。进入到第一个页面不代表抢到,只表示当时红包还有。

37.1.3 分配:红包里的金额怎么算?为什么出现各个红包金额相差很大?

答:随机,额度在0.01和(剩余平均值2)之间。 例如:发100块钱,总共10个红包,那么平均值是10块钱一个,那么发出来的红包的额度在0.01元~20元之间波动。 当前面3个红包总共被领了40块钱时,剩下60块钱,总共7个红包,那么这7个红包的额度在:0.01~(60/72)=17.14之间。 注意:这里的算法是每被抢一个后,剩下的会再次执行上面的这样的算法(Tim老师也觉得上述算法太复杂,不知基于什么样的考虑)。

这样算下去,会超过最开始的全部金额,因此到了最后面如果不够这么算,那么会采取如下算法:保证剩余用户能拿到最低1分钱即可。

如果前面的人手气不好,那么后面的余额越多,红包额度也就越多,因此实际概率一样的。

37.1.4 红包的设计

答:微信从财付通拉取金额数据郭莱,生成个数/红包类型/金额放到redis集群里,app端将红包ID的请求放入请求队列中,如果发现超过红包的个数,直接返回。根据红包的裸祭(逻辑)处理成功得到令牌请求,则由财付通进行一致性调用,通过像比特币一样,两边保存交易记录,交易后交给第三方服务审计,如果交易过程中出现不一致就强制回归。

37.1.5 发性处理:红包如何计算被抢完?

答:cache会抵抗无效请求,将无效的请求过滤掉,实际进入到后台的量不大。cache记录红包个数,原子操作进行个数递减,到0表示被抢光。财付通按照20万笔每秒入账准备,但实际还不到8万每秒。

37.1.6 通如何保持8w每秒的写入?

答:多主sharding,水平扩展机器。

37.1.7 据容量多少?

答:一个红包只占一条记录,有效期只有几天,因此不需要太多空间。

37.1.8 询红包分配,压力大不?

答:抢到红包的人数和红包都在一条cache记录上,没有太大的查询压力。

37.1.9 一个红包一个队列?

答:没有队列,一个红包一条数据,数据上有一个计数器字段。

有没有从数据上证明每个红包的概率是不是均等? 答:不是绝对均等,就是一个简单的拍脑袋算法。

37.1.10拍脑袋算法,会不会出现两个最佳?

答:会出现金额一样的,但是手气最佳只有一个,先抢到的那个最佳。

37.1.11 每领一个红包就更新数据么?

答:每抢到一个红包,就cas更新剩余金额和红包个数。

37.1.12 红包如何入库入账?

数据库会累加已经领取的个数与金额,插入一条领取记录。入账则是后台异步操作。

37.1.13 入帐出错怎么办?比如红包个数没了,但余额还有?

答:最后会有一个take all操作。另外还有一个对账来保障。

37.2 V0.1原型系统

我们看一下这个系统,我们当时做了一个原型系统,比较简单,它已经实现了所有的功能,摇那个手机的时候会通过客户端发出一个请求,接入服务器,然后摇一摇服务,进行等级判断,判断以后把结果给到后端,可能摇到拜年或红包,假设摇到红包,上面有LOGO和背景图,客户端把这个LOGO和背景图拉回去,用户及时拆开红包,拆的请求会来到红包系统,红包系统进行处理之后会到支付系统,到财富通的转帐系统,最终用

经典系统设计题:大型抢红包系统设计 尽量不要在每个拆红包的请求中都去修改红包记录的状态(比如扣减金额),因为红包记录只有一条,只能串行的去执行,当拆分出大量红包时(比如春晚红包,几百万个),会严重影响拆红包的效率。发红包阶段,新建一张临时表,表名和红包id对应,将拆分的金额存入到表中,每个金额都有一个自增id(从1开始),假如拆分出了100个金额,那么id就是1到100,然后hash(用户id)来获取金额id从而决定金额,最简单的就是用户id % 份数。好在,我们在抢红包阶段已经过滤了大部分无效请求,能到这个阶段的都是已经抢到了红包的。 阅读详情

相关推荐

抢红包系统搭建和超发现象,以及解决问题提高性能

以传统的数据库作为存储介质、以Redis+Lua来作为库存存储介质最后落到数据库 本次案例介绍抢红包的场景,模拟20万红包,分为400个小红包,每个红包500元,有1000千人并发同时抢夺,并讲解会出现超发和保证如何数据一致性问题,在高并发场景下还需要保证性能的问题。 在这里,首先查看红包库存,是否有,如果有,则更新库存减一,然后插入一条记录到抢红包信息表中,这3个操作作为一个事务,原子性来操...

cuichunchi的博客 2950

听说你会架构设计?来,弄一个红包系统

设计一个红包系统不仅要考虑海量用户的并发体验和数据一致性,还得保障用户资金的安全。这种技术难点,对于传统的 “秒杀系统” 有过之而无不及。

qq_40238271的博客 759

Java面试场景题】微信抢红包功能是如何实现的,如果让你来你怎么设计

实现拼手气红包算法,有以下几个需要注意的地方:答:微信金额是拆的时候实时算出来,不是预先分配的,采用的是纯内存计算,不需要预算空间存储。 采取实时计算金额的考虑:预算需要占存储,实时效率很高,预算才效率低。答:2014年的红包一点开就知道金额,分两次操作,先抢到金额,然后再转账。 2015年的红包的拆和抢是分离的,需要点两次,因此会出现抢到红包了,但点开后告知红包已经被领完的状况。进入到第一个页面不代表抢到,只表示当时红包还有。答:随机,额度在0.01和(剩余平均值2)之间。 例如:发100块钱,总共10个

JAVA_aik的博客 2484

1.如何设计一个简单的抢红包系统

没什么好说的,相信大家的微信红包没少抢,一想都明白。首先,抢红包必须保证高可用,不然用户会很愤怒。其次,必须保证系统数据一致性不能超发,不然抢到红包的用户收不到钱,用户会很愤怒。最后一点,系统可能会有很高的并发。业务流程:常见的红包系统,由用户指定金额、红包总数来完成红包的创建,然后通过某个入口将红包下发至目标用户,用户看到红包后,点击红包,随机获取红包,最后,用户可以查看自己抢到的红包。活动表,就是你发了多少个红包,并且需要维护剩余金额。红包表,是每一个具体的红包信息。明细表,是用户抢到的红包明细。

qq_44438941的博客 732

高并发面试场景题之微信抢红包功能

高并发场景题之微信抢红包

技术改变命运,创新驱动中国 333

简单实现微信抢红包功能(Java)

简单实现微信抢红包功能(Java) package 数据很美; import java.util.Random; import java.util.Scanner; public class 简单模拟微信抢红包小程序 { public static void main(String[] args) { Scanner sc=new Scanner(System.in); System....

qq_45104603的博客 4679

Java微信抢红包实现

如果上司给一个任务,让我们在实现微信抢红包这个功能,我们该怎么?   * 业务思考,实现方式千百种,不追求方法复制,只追求推导过程的思考总结 Java微信抢红包实现   * 功能点探索 * 新建红包:在DB、cache各新增一条记录 * 抢红包:请求访问cache,剩余红包个数大于0则可拆开红包 * key:1,value:20 string decr原子减,每次减1 , 而decreby减指定数量N * 拆红包: 20个红包里面有500块,key:1,value:50000(以分为单位) decreb

weixin_49794051的博客 2375

Java 小白 微信抢红包小程序(详细)

package red; import java.util.Random; import java.util.Scanner; class Program { public static void main(String[] args) { System.out.println("------模拟微信抢红包------\n"); Scanner sc = new Scanner(System.in); System.out.println(

Lin_bai_的博客 3496

AccessibilityService之微信抢红包辅助功能实现

这次我们来使用AccessibilityService实现一个微信抢红包的辅助工具。 先来一个简单的效果图,最后会有一个完整的效果图:     首先,先回想一下微信红包的领取流程。 1.通知栏出现微信红包的消息 2.点击通知栏,进入领取红包界面 3.点击领取红包,领取成功后,进入拆红包界面 4.拆红包,显示获得金额 5.等待下一个红包

安卓世界库 2037

java 实现微信抢红包Dome

java 实现微信抢红包Dome 红包的一些规则和算法,如下(随机拆分玩法): 1.每个红包金额不能小于0.01元 2.如果发送5个红包,则红包总金额不能小于0.01*5=0.05元 3.如果红包的个数大于1个,则每个红包的拆分金额不能等于红包总金额 4.每个红包拆分的金额之和,等于红包的总金额 5.要随机拆分,并且是没有任何顺序 6.显示运气王 抢红包逻辑代码 public class ...

tt336798的博客 3185

java 实现仿照微信抢红包算法,实测结果基本和微信吻合,附demo

实现拼手气红包算法,有以下几个需要注意的地方: 抢红包的期望收益应与先后顺序无关 保证每个用户至少能抢到一个预设的最小金额,人民币红包设置的最小金额一般是0.01元,如果需要发其他货币类型的红包,比如区块链货币或者积分,需要自定义一个最小金额。 所有抢红包的人领取的子红包的金额之和加起来,等于发红包的人发出的总红包的金额。 下面实现的方式是一次生成所有的子红包,让用户按顺序领取。也可以每领取一个...

双眸 3284

Java:模拟微信抢红包

1、输入红包金额、个数 2、循环计算第n-1个红包的金额,随机算法 3、输出最后一个红包金额 import java.text.DecimalFormat; import java.util.Random; import java.util.Scanner; /** * 模拟微信抢红包功能 */ public class RedBags { //创建一个RedBags类 public static void main(String[] args) { System.out.println("——

博樽 2930

如何使用Redis实现抢红包功能

在这篇文章中,我们将探讨如何使用Redis来设计实现一个抢红包的业务场景。从业务场景、需求分析、技术选型、代码实现,痛点问题等进行多维分析和思考。

weixin_44831330的博客 1559

Java实现4种微信抢红包算法

14年微信推出红包功能以后,很多公司开始上自己的红包功能,到现在为止仍然有很多红包开发的需求,实现抢红包算法也是面试常考题。保证每个红包最少分得0.01元保证每个红包金额概率尽量均衡所有红包累计金额登于红包总金额本文提供4中红包算法及Java代码实现demo,仅供参考。其中每种算法测试场景为:0.1元10个包,1元10个包,100元10个包,1000元10个包。

欢迎来到我的博客 990

Android微信抢红包服务源码

Android微信抢红包服务源码 基于Android AccessibilityService,配套微信7.0.9版本,主要使用控件ID来获取AccessibilityNodeInfo,亲测好用! RedPacketService.java 实现抢红包功能 package com.example.snatch; import android.accessibilityservice.Access...

wangtian526的博客 2149

微信抢红包程序开发详解

监控微信群中的红包信息自动点击红包进行抢夺获取抢到的金额通过本篇文章,我们详细介绍了如何使用安卓无障碍服务编写一个简单的微信抢红包程序。从环境配置、基本逻辑到代码实现,涵盖了主要的开发流程。当然,自动化技术有它的局限性,实际操作时可能会遇到各种问题,因此要根据实际需求不断优化和改进代码。

byby0325_的博客 3020

Java Random类实现微信抢红包

1、语法:Random r = new Random(); Random类提供了一些方法来获取随机数: nextInt() 返回随机生成int值 nextLong() 返回随机long值 nextDouble() 返回随机Double值 nextFloat() 返回随机Float值 nextBoolean() 返回随机Boolean值 最常用的是nextInt(int n)方法,参数是一个int值,取值范围:0 <= nextInt(int n) < n,会等于0不会等于n。 Random

单枪匹码 1441
上一篇: 【Java】你们采用微服务架构,请问你是什么做系统拆分的?
下一篇: 【Java】如何设计一个敏感词过滤系统?
alen101
博客等级 码龄2年 961粉丝 66原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值