当前位置: 首页 > news >正文

上海网站建设上海网站制作荥阳网站优化公司

上海网站建设上海网站制作,荥阳网站优化公司,建筑工程资质查询平台,网代理加盟#1024程序员节 | 征文# 前言 微信红包作为大家耳熟能详的一种互动方式,其背后的技术支持包含多个方面。从用户发出红包到红包被抢完,涉及到的流程包括发红包、红包存储、红包拆分以及抢红包等。本文将详细介绍这一系列流程,并通过代码案例来…

#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个红包,每次随机数都取最大值,那么有如下情况:

红包useMoneyavgMoney每次随机数最大本次红包金额
1020 * 2new Random().nextInt(avgMoney) == 3940
24015*2new Random().nextInt(avgMoney) == 2930
37010*2new Random().nextInt(avgMoney) == 1920
4905*2new Random().nextInt(avgMoney) == 910
500

发红包

发红包的主要步骤是将拆分后的小红包保存到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数据库的高效利用以及高并发环境下的数据处理问题。

http://www.mmbaike.com/news/93278.html

相关文章:

  • wordpress 站内链接软文推广有哪些
  • 卖设备用哪个网站百度站长快速收录
  • 个人做百度云下载网站百度网址大全旧版
  • 做网站如何推广百度引流推广怎么做
  • 怎样买空间做网站武汉seo学徒
  • 接网站建设的单子seo优化推广教程
  • 2023年珠海疫情最新情况百度热搜关键词排名优化
  • apache网站日志广告投放网站平台
  • 网站中点击链接怎么做今日最新消息
  • 那个网站报道过鸟巢建设广告公司联系方式
  • 门户网站的主要功能seo推广方案
  • 莱芜网站制作石家庄网站建设排名
  • 揭阳手机网站建设2022最新版百度
  • 武汉市城市建设委员会网站上海app网络推广公司电话
  • 网页设计网站费用个人网站免费域名注册
  • 安国网站建设微信怎么推广引流客户
  • 建设银行手机个人网站南京百度seo排名优化
  • 南京哪家做网站好杭州seo的优化
  • 张雪峰软件工程的前景seo人才招聘
  • 网站建设方案流程找相似图片 识别
  • 顺企网是什么网站百度收录查询网址
  • 做网站好几个css查询友情链接
  • 台州网站排名优化网店推广方法
  • vs手机网站开发百度客户服务电话
  • 网站制作 系统定制对seo的理解
  • 重庆沙坪坝企业网站建设联系电话搜索引擎优化的简称
  • 昆山市有没有做网站设计的佛山网站seo
  • 手机网站自助建站源码软文推广经典案例
  • 谁做彩票网站代理sem代运营托管公司
  • wordpress上传图片不占用id杭州seo百度关键词排名推广