微信红包设计流程讲解与实战分析
#1024程序员节 | 征文#

前言
微信红包作为大家耳熟能详的一种互动方式,其背后的技术支持包含多个方面。从用户发出红包到红包被抢完,涉及到的流程包括发红包、红包存储、红包拆分以及抢红包等。本文将详细介绍这一系列流程,并通过代码案例来实践讲解,特别重点分析红包的拆分算法。
微信红包设计流程
整个红包流程按照发红包、红包拆分、抢红包的顺序来设计。在数据结构的选择上,考虑到抢红包的高并发特性和即时响应要求,采用Redis非关系数据库进行设计是优于MySQL的。Redis的每个命令都是单线程执行,保证原子性操作,无需额外的锁机制。
1. 发红包
一个红包通常会被拆分成多个小红包,例如100元可以拆分为20元、20元、20元、30元和10元。这种情况下,可以使用Redis的list结构来存储这些拆分后的小红包。
2. 抢红包
在高并发环境下,如何保证多线程抢红包时不加锁且保持原子性是关键。Redis的特性使得每个命令都是单线程且原子性的,因此使用LPOP命令即可实现。
3. 记红包
为了确保同一个用户不能抢夺同一个红包两次,需要记录哪些红包被哪些用户抢过。这里可以使用Redis的hash结构来进行存储。
拆红包算法
在拆红包算法中,较为合理的是采用“二倍均值算法”。该算法的核心思想是每次拆分红包时,取一个随机区间,其最大值为剩余红包金额的两倍与未被抢的剩余红包个数的乘积。这样可以保证拆分的随机性和公平性。
代码实现
二倍均值算法的具体代码实现如下:
private Integer[] splitRedPackageAlgorithm(int totalMoney, int redPackageNumber){Integer[] splitRedPackageNumbers = new Integer[redPackageNumber];int useMoney = 0;for (int i = 0; i < redPackageNumber; i++) {if(i == redPackageNumber - 1){splitRedPackageNumbers[i] = totalMoney - useMoney;}else {int avgMoney = ((totalMoney - useMoney) / (redPackageNumber - i)) \* 2;splitRedPackageNumbers[i] = 1 + new Random().nextInt(avgMoney - 1);}useMoney += splitRedPackageNumbers[i];}return splitRedPackageNumbers;}
为什么生成每个小红包金额使用如下代码随机生成?
splitRedPackageNumbers[i] = 1 + new Random().nextInt(avgMoney - 1);
首先,前面加1的原因是new Random().nextInt(avgMoney -1)会生成0到avgMoney - 1之间的随机数,但不能为0。为了保证第一个红包不为0元,所以需要+1。其次,avgMoney - 1是为了控制随机数的最大值接近于avgMoney但不等于它。这样可以确保最后一个红包也不会为0元。如果不这样做,有可能每次随机数都取最大值,导致最后剩余的红包金额只能为0。
后面avgMoney -1,如果不-1,结果是怎样呢?接下来模拟不-1的情况下,假设100块分5个红包,每次随机数都取最大值,那么有如下情况:
| 红包 | useMoney | avgMoney | 每次随机数最大 | 本次红包金额 |
|---|---|---|---|---|
| 1 | 0 | 20 * 2 | new Random().nextInt(avgMoney) == 39 | 40 |
| 2 | 40 | 15*2 | new Random().nextInt(avgMoney) == 29 | 30 |
| 3 | 70 | 10*2 | new Random().nextInt(avgMoney) == 19 | 20 |
| 4 | 90 | 5*2 | new Random().nextInt(avgMoney) == 9 | 10 |
| 5 | 0 | | | 0 |
发红包
发红包的主要步骤是将拆分后的小红包保存到Redis的list结构中,并设置过期时间。具体代码如下:
@RequestMapping(value = "/send")public String sendRedPackage(int totalMoney, int redPackageNumber){Integer[] splitRedPackages = splitRedPackageAlgorithm(totalMoney,redPackageNumber);String key = RED\_PACKAGE\_KRY + IdUtil.simpleUUID();redisTemplate.opsForList().leftPushAll(key,splitRedPackages);redisTemplate.expire(key,1, TimeUnit.DAYS);return key+"\t" + Ints.asList(Arrays.stream(splitRedPackages).mapToInt(Integer::valueOf).toArray());}
调用发红包接口,比如20块钱分成5个红包,查看redis。

抢红包
抢红包的逻辑是先验证用户是否已经抢过该红包,如果没有则允许其抢红包并记录到Redis中。具体代码如下:
@RequestMapping(value = "/rob")public String robRedPackage(String redPackageKey,String userId){Object redPackage = redisTemplate.opsForHash().get(RED\_PACKAGE\_CONSUME\_KRY + redPackageKey, userId);if (redPackage == null){Object partRedPackage = redisTemplate.opsForList().leftPop(RED\_PACKAGE\_KRY + redPackageKey);if (partRedPackage != null){redisTemplate.opsForHash().put(RED\_PACKAGE\_CONSUME\_KRY+redPackageKey,userId,partRedPackage);System.out.println("用户"+userId+" 抢到红包了 " + partRedPackage);return String.valueOf(partRedPackage);}return "errorCode : -1 ,红包抢完了";}return "errorCode : -2 ," + userId + " 你已经抢过红包了";}
调用抢红包接口后,用户可以返回抢到的红包金额,并且在Redis中也能查看到相应的红包记录。
总结
本文主要介绍了微信红包的拆分、发放和抢红包的流程,并重点讲解了二倍均值法在拆红包算法中的应用。通过随机生成红包金额的方式,实现了公平且随机的抢红包效果。整个过程中涉及到了Redis数据库的高效利用以及高并发环境下的数据处理问题。
相关文章:
微信红包设计流程讲解与实战分析
#1024程序员节 | 征文# 前言 微信红包作为大家耳熟能详的一种互动方式,其背后的技术支持包含多个方面。从用户发出红包到红包被抢完,涉及到的流程包括发红包、红包存储、红包拆分以及抢红包等。本文将详细介绍这一系列流程,并通过代码案例来…...
AI智能体:AI智能体(Agent)是什么?为什么要学?99%的人不知道!
为什么要学? 我们先搞清楚为什么? 最近看到 AI 创新力五问,我们日常生活中有使用 AI 来融入到我们的学习工作流嘛? 值得我们日常反省。 未来企业人才招聘测试AI创新力的五问: 您是否处于每天习惯使用 AI 的状态&am…...
NVR小程序接入平台/设备EasyNVR多个NVR同时管理的高效解决方案
在当今的数字化安防时代,视频监控系统的需求日益复杂和多样化。为了满足不同场景下的监控需求,一种高效、灵活且兼容性强的安防视频监控平台——NVR批量管理软件/平台EasyNVR应运而生。本篇探讨这一融合所带来的创新与发展。 一、NVR监测软件/设备EasyNV…...
APS开源源码解读: 排程工具 optaplanner II
上篇 排产,原则上也就是分配时间,分配资源;保证资源日历约束,保证工艺路线约束。我们看一下如何实现optaplanner 优化的 定义一个move, 一个move可能改变了分配到的资源,也可能改变了一个资源上的顺序。改变即意味着优…...
科技是把双刃剑,巧用技术改变财务预测
数字化和全球化的双向驱动,引领我国各行各业在技术革新的浪潮中不断扬帆。这一趋势不仅带来了前所未有的突破与创新,推进企业迈向数据驱动决策的新未来,同时也伴随着一些潜在的问题和挑战。科技的普及就像是一场革命,在财务管理领…...
vscode默认添加python项目的源目录路径到执行环境(解决ModuleNotFoundError: No module named问题)
0. 问题描述 vscode中编写python脚本,导入工程目录下的其他模块,出现ModuleNotFoundError: No module named 错误 在test2的ccc.py文件中执行print(sys.path) 查看路径 返回结果发现并无’/home/xxx/first_demo’的路径,所以test2下面的文…...
【每日刷题】Day143
【每日刷题】Day143 🥕个人主页:开敲🍉 🔥所属专栏:每日刷题🍍 🌼文章目录🌼 1. 200. 岛屿数量 - 力扣(LeetCode) 2. LCR 105. 岛屿的最大面积 - 力扣&…...
基于Springboot智能学习平台的设计与实现
基于Springboot智能学习平台的设计与实现 开发语言:Java 框架:springboot JDK版本:JDK1.8 数据库:mysql 5.7 数据库工具:Navicat11 开发软件:idea 源码获取:https://download.csdn.net/downlo…...
黑马javaWeb笔记重点备份11:Web请求与响应
请求 SpringBoot内置Servlet 在Tomcat这类Web服务器中,是不识别我们自己定义的Controller的,但在tomcat中是可以识别 Servlet程序的。在SpringBoot进行web程序开发时,它内置了一个核心的Servlet程序 DispatcherServlet,称之为 核…...
H5对接海康硬盘录像机视频简单说明
开发过程中使用HTML5(通常是通过Web技术栈,如HTML、CSS、JavaScript)与海康威视(Hikvision)的硬盘录像机(DVR)进行视频对接,通常涉及以下步骤: 获取DVR的RTSP流地址:海康威视DVR支持RTSP协议,你可以通过DVR的管理界面获取每个摄像头的RTSP流地址。 使用视频播放器库…...
测试人必备的Linux常用命令大全...【全网最全面整理】
Linux常用命令大全(非常全!!!) 最近都在和Linux打交道,感觉还不错。我觉得Linux相比windows比较麻烦的就是很多东西都要用命令来控制,当然,这也是很多人喜欢linux的原因,…...
苹果AI落后两年?——深度解析苹果在AI领域的挑战与前景
# 苹果AI落后两年?——深度解析苹果在AI领域的挑战与前景 近年来,人工智能(AI)领域的技术竞争日益激烈,各大科技巨头纷纷推出突破性的AI产品。然而,关于苹果公司在AI领域的表现,最近传出一些内…...
三菱PLC伺服-停止位置不正确故障排查
停止位置不正确时,请确认以下项目。 1)请确认伺服放大器(驱动单元)的电子齿轮的设定是否正确。 2)请确认原点位置是否偏移。 1、设计近点信号(DOG)时,请考虑有足够为0N的时间能充分减速到爬行速度。该指令在DOG的前端开始减速到爬行速度&…...
Mybatis 批量操作存在则更新或者忽略,不存在则插入
Mybatis 批量操作新增,如果存在重复有下列2种处理方式: 1、存在则忽略代码示例: <insert id"insertDuplicateKeyIgnoreList">INSERT IGNORE INTO specs(status,type,code,name,create_time,create_by)VALUES<foreach col…...
「C/C++」C++ STL容器库 之 std::deque 双端队列容器
✨博客主页何曾参静谧的博客📌文章专栏「C/C」C/C程序设计📚全部专栏「VS」Visual Studio「C/C」C/C程序设计「UG/NX」BlockUI集合「Win」Windows程序设计「DSA」数据结构与算法「UG/NX」NX二次开发「QT」QT5程序设计「File」数据文件格式「PK」Parasoli…...
一招教你解决Facebook广告账号问题
这段时间,我们写了很多文章来探讨Facebook的广告账户问题:《Facebook被封号该怎么办》《Facebook二不限、三不限账号是什么》《Facebook海外户(三不限)和账单户该如何选择》《如何区分真假Facebook三不限海外户》相信看过这些文章…...
MySQL启动报错:InnoDB: Unable to lock ./ibdata1 error
MySQL启动报错:InnoDB: Unable to lock ./ibdata1 error 在OS X环境下MySQL启动时报错: 016-03-03T00:02:30.483037Z 0 [ERROR] InnoDB: Unable to lock ./ibdata1 error: 35 2016-03-03T00:02:30.483100Z 0 [Note] InnoDB: Check that you do not alr…...
Linux终端之旅: 打包和压缩
在 Linux 世界中,打包和压缩文件是管理系统资源、传输数据和备份的重要技能。通过命令行工具如 tar、gzip、zip 等,我们可以高效地将多个文件或目录打包为一个文件,并通过压缩减少其体积。接下来,我将记录学习如何利用这些工具&am…...
PDA手持机提升管理效率和准确性
在当今快节奏的商业世界中,管理效率和准确性是企业成功的关键因素。而 PDA 手持机的出现,为企业管理带来了革命性的变革,成为提升管理效率和准确性的有力武器。 PDA 手持机,即个人数字助理手持设备,集数据采集、存储、…...
C++ [项目] 愤怒的小鸟
现在才发现C游戏的支持率这么高,那就发几篇吧 零、前情提要 此篇为 制作,由于他没有CSDN,于是由我代发 一、基本介绍 支持Dev-C5.11版本(务必调为英文输入法),基本操作看游戏里的介绍,怎么做的……懒得说,能看懂就看注释,没有的自己猜,如果你很固执……私我吧 …...
【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型
摘要 拍照搜题系统采用“三层管道(多模态 OCR → 语义检索 → 答案渲染)、两级检索(倒排 BM25 向量 HNSW)并以大语言模型兜底”的整体框架: 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后,分别用…...
DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径
目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...
涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战
“🤖手搓TuyaAI语音指令 😍秒变表情包大师,让萌系Otto机器人🔥玩出智能新花样!开整!” 🤖 Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制(TuyaAI…...
QT: `long long` 类型转换为 `QString` 2025.6.5
在 Qt 中,将 long long 类型转换为 QString 可以通过以下两种常用方法实现: 方法 1:使用 QString::number() 直接调用 QString 的静态方法 number(),将数值转换为字符串: long long value 1234567890123456789LL; …...
Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理
引言 Bitmap(位图)是Android应用内存占用的“头号杀手”。一张1080P(1920x1080)的图片以ARGB_8888格式加载时,内存占用高达8MB(192010804字节)。据统计,超过60%的应用OOM崩溃与Bitm…...
蓝桥杯3498 01串的熵
问题描述 对于一个长度为 23333333的 01 串, 如果其信息熵为 11625907.5798, 且 0 出现次数比 1 少, 那么这个 01 串中 0 出现了多少次? #include<iostream> #include<cmath> using namespace std;int n 23333333;int main() {//枚举 0 出现的次数//因…...
用机器学习破解新能源领域的“弃风”难题
音乐发烧友深有体会,玩音乐的本质就是玩电网。火电声音偏暖,水电偏冷,风电偏空旷。至于太阳能发的电,则略显朦胧和单薄。 不知你是否有感觉,近两年家里的音响声音越来越冷,听起来越来越单薄? —…...
深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用
文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么?1.1.2 感知机的工作原理 1.2 感知机的简单应用:基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...
AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别
【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而,传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案,能够实现大范围覆盖并远程采集数据。尽管具备这些优势…...
【Elasticsearch】Elasticsearch 在大数据生态圈的地位 实践经验
Elasticsearch 在大数据生态圈的地位 & 实践经验 1.Elasticsearch 的优势1.1 Elasticsearch 解决的核心问题1.1.1 传统方案的短板1.1.2 Elasticsearch 的解决方案 1.2 与大数据组件的对比优势1.3 关键优势技术支撑1.4 Elasticsearch 的竞品1.4.1 全文搜索领域1.4.2 日志分析…...
