麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 數據庫 > Redis > 正文

通過redis的腳本lua如何實現搶紅包功能

2020-10-28 21:27:52
字體:
來源:轉載
供稿:網友

redis 腳本介紹

Redis從2.6版本開始,通過內嵌支持Lua環境

好處

  • 減少網絡開銷。可以將多個請求通過腳本的形式一次發送,減少網絡延遲
  • 原子操作。redis將整個腳本當作一個整體去執行,中間不會被其他命令插入,無需擔心腳本執行過程中會出現競態條件
  • 復用。客戶端發送的腳本會永久保存在redis中,可以復用這一腳本

數據庫表設計

簡單兩張表,一個紅包表,一個紅包領取記錄表

CREATE TABLE `t_red_envelope` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID', `amount` decimal(10,2) DEFAULT NULL COMMENT '金額', `num` int(11) DEFAULT NULL COMMENT '數量(分割成幾分)', `create_time` datetime DEFAULT NULL COMMENT '創建時間', `update_time` datetime DEFAULT NULL COMMENT '更新時間', PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4 COMMENT='紅包'CREATE TABLE `t_red_envelope_record` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id', `user_id` bigint(20) DEFAULT NULL COMMENT '用戶id', `reward` decimal(10,2) DEFAULT NULL COMMENT '領取到獎勵', `red_envelope_id` bigint(20) DEFAULT NULL COMMENT '紅包id', `create_time` datetime DEFAULT NULL COMMENT '創建時間', `update_time` datetime DEFAULT NULL COMMENT '更新時間', PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COMMENT='紅包領取記錄'

代碼編寫

首先,生成一個紅包,將其分成指定數量的隨機小紅包,以list結構(envelope:redEnvelopeId:紅包id作為key)存儲在reids中(以便搶紅包彈出數據)

 public Long divideRedEnvelope(int amount, int num) {  /**   * 每個人至少分到一分錢,如果有2000分,6人,隨機得到五個小于1994(2000-6)的數   * 比如 a1=4,a2=120,a3=324,a4=500,a5=700(隨機拿到的五個數進行排序),那么紅包錢分別為: a1+1,a2-a1+1,a3-a2+1,a4-a3+1,a5-a4+1,1994-a5+1(總和剛好為2000)   */  RedEnvelope redEnvelope = new RedEnvelope();  redEnvelope.setAmount(new BigDecimal(amount));  redEnvelope.setNum(num);  redEnvelope.setCreateTime(new Date());  redEnvelope.setUpdateTime(new Date());  redEnvelopeDao.insert(redEnvelope);  /**   * 拿來隨機分的,按分來算   */  int totalAmount = amount * 100 - num;  /**   * 隨機數   */  int[] randomNum = new int[num - 1];  /**   * 紅包金額   */  int[] redEnvelopeAmount = new int[num];  for (int i = 0; i < num - 1; i++) {   int rand = new Random().nextInt(totalAmount);   randomNum[i] = rand;  }  Arrays.sort(randomNum);  /**   * 條件語句分別分配的第一個、最后一個、中間的紅包   */  for (int i = 0; i < num; i++) {   if (i == 0) {    redEnvelopeAmount[i] = randomNum[i] + 1;   } else if (i == num - 1) {    redEnvelopeAmount[i] = totalAmount - randomNum[i - 1] + 1;   } else {    redEnvelopeAmount[i] = randomNum[i] - randomNum[i - 1] + 1;   }  }  /**   * 產生的小紅包key,以list存儲在reids中   */  String key = "envelope:redEnvelopeId:" + redEnvelope.getId();  Boolean flag = stringRedisTemplate.hasKey(key);  if (!flag) {   for (Integer i : redEnvelopeAmount) {    stringRedisTemplate.opsForList().leftPush(key, i + "");   }  }  return redEnvelope.getId(); }

搶紅包時,根據用戶userId和紅包id,生成KEYS[1]、KEYS[2]、KEYS[3] (存儲小紅包的key、領取紅包記錄的key、用戶userId的key)傳入腳本中。

​     1、先判斷該用戶是否搶過紅包,有則返回-1,沒有則從紅包列表取出一個小紅包

​     2、步驟1的小紅包如果為空,則表明紅包已經沒搶光,返回 -2

​     3、否則返回取出的小紅包金額

 public String grabRedEnvelope(Long userId, Long redEnvelopeId) {  DefaultRedisScript<String> redisScript = new DefaultRedisScript<>();  redisScript.setResultType(String.class);  redisScript.setScriptText(LuaScript.redLua);  List<String> keyList = new ArrayList();  /**   * 產生的小紅包key   */  keyList.add("envelope:redEnvelopeId:" + redEnvelopeId);  /**   * 紅包領取記錄key   */  keyList.add("envelope:record:" + redEnvelopeId);  keyList.add("" + userId);  keyList.add(String.valueOf(userId));  /**   * -1 已經搶到紅包 -2 紅包已經完了 ,其余是搶到紅包并返回紅包余額   */  String result = stringRedisTemplate.execute(redisScript, keyList);  return result; }

實現搶紅包的Lua腳本

public class LuaScript { /**  * -1 已經搶到紅包 -2 紅包被搶光 re 紅包金額 ,keys[1]、keys[2]、keys[3]分別為存儲小紅包的key、紅包領取記錄key、用戶id  */ public static String redLua = "if redis.call('hexists',KEYS[2],KEYS[3]) ~=0 then /n" +   " return '-1';/n" +   " else /n" +   "local re=redis.call('rpop',KEYS[1]);/n" +   "if re then/n" +   "redis.call('hset',KEYS[2],KEYS[3],1);/n" +   "return re;/n" +   "else/n" +   "return '-2';/n" +   "end/n" +   "end";}

測試

首先通過接口分配紅包生成一個100塊、份額為10份的紅包,并將其mysql數據庫和redis

通過jmeter進行壓測搶紅包

結果

github代碼鏈接

鏈接

總結

到此這篇關于通過redis的腳本lua如何實現搶紅包功能的文章就介紹到這了,更多相關redis的腳本lua實現搶紅包內容請搜索武林網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持武林網!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 激情久久免费视频 | 九九视频在线观看黄 | 中文字幕爱爱视频 | 欧美大穴 | 手机在线看片国产 | 成人免费观看49www在线观看 | 亚洲生活片 | 激情小说激情电影 | 黄色网址免费进入 | 自拍偷拍亚洲图片 | 草莓视频久久 | 久久综合入口 | 成人毛片在线 | 国产精品视频亚洲 | 欧美日本免费一区二区三区 | 717影院理论午夜伦八戒秦先生 | 欧美黑大粗硬毛片视频 | 亚洲精品aa | 伊人午夜视频 | 91精品观看91久久久久久国产 | 欧美黄色一级生活片 | 久久爽久久爽久久av东京爽 | 羞羞的视频免费在线观看 | 黄色大片大毛片 | 91久久91久久精品免观看 | 国产毛片aaa一区二区三区视频 | 在线播放黄色网址 | 免费啪视频在线观看 | 成年免费视频黄网站在线观看 | av在线一区二区三区 | 国产91久久久久久 | 失禁高潮抽搐喷水h | 一级黄色欧美 | 国产午夜小视频 | 国产成人自拍视频在线 | 国产一区视频免费观看 | 欧美日韩亚州综合 | 欧美视频一级 | 国产成人自拍小视频 | 免费观看国产精品视频 | 亚洲第一页夜 |