【抽獎項目】|第二篇

前言:

? ? ? ? 高并發的活動預熱肯定不可以在數據庫操作,需要redis,特別是這種秒殺活動更是需要注意,所以可以在高并發的前夕先進行活動預熱。

?思路:

? ? ? ?1、 通過定時任務調度每分鐘查詢數據庫也沒有需要預熱的活動

? ? ? ? 2、采用分布式鎖防止任務重復調度

? ? ? ? 3、查詢到預熱活動需要信息全部進行redis存儲

? ? ? ? 4、生成令牌桶

? ? ? ? ? ? ? ? ? 細節:生成總獎品個數個令牌

? ? ? ? ? ? ? ? ? ? ? ? ? ? ?每個令牌生成開始到結束時間的一個隨機數

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 乘上1000,在額外加上一個三位數的隨機數? ------防止獎品過多令牌重復

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 把令牌放入令牌桶

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 設置令牌和獎品的關系

? ? ? ? 5、先按照時間大小排序,在壓入redis

? ? ? ? 6、改變預熱狀態

    @Scheduled(cron = "0 * * * * ?")public void execute() {//TODO 緩存預熱// 獲取當前時間的Calendar實例Calendar calendar = Calendar.getInstance();// 清除毫秒部分calendar.set(Calendar.MILLISECOND, 0);// 獲取不帶毫秒的Date對象Date now = calendar.getTime();//分布式鎖,防止重復啟動任務if (!redisUtil.setNx("game_task_"+now.getTime(),1,60L)){log.info("task started by another server!");return;}//查詢將來1分鐘內要開始的活動QueryWrapper<CardGame> gameQueryWrapper = new QueryWrapper<>();//開始時間大于當前時間gameQueryWrapper.gt("starttime",now);//小于等于(當前時間+1分鐘)gameQueryWrapper.le("starttime",DateUtils.addMinutes(now,1));List<CardGame> list = gameService.list(gameQueryWrapper);if(list.size() == 0){//沒有查到要開始的活動log.info("沒有查到要開始的活動");return;}log.info("需要緩存預熱的活動個數:{}",list.size());//有相關活動數據,則將活動數據預熱,進redislist.forEach(game ->{//活動開始時間long start = game.getStarttime().getTime();//活動結束時間long end = game.getEndtime().getTime();//計算活動結束時間到現在還有多少秒,作為redis key過期時間long expire = (end - now.getTime())/1000;
//            long expire = -1; //永不過期//活動持續時間(ms)long duration = end - start;Map queryMap = new HashMap();queryMap.put("gameid",game.getId());//活動基本信息game.setStatus(1);redisUtil.set(RedisKeys.INFO+game.getId(),game,-1);log.info("活動ID:{},名稱:{},開始:{},結束{}", game.getId(),game.getTitle(),game.getStarttime(),game.getEndtime());//活動獎品信息List<CardProductDto> products = gameLoadService.getByGameId(game.getId());Map<Integer,CardProduct> productMap = new HashMap<>(products.size());products.forEach(p -> {productMap.put(p.getId(),p);});//獎品數量等配置信息List<CardGameProduct> gameProducts = gameProductService.listByMap(queryMap);//令牌桶List<Long> tokenList = new ArrayList();gameProducts.forEach(cgp ->{//生成amount個start到end之間的隨機時間戳做令牌for (int i = 0; i < cgp.getAmount(); i++) {long rnd = start + new Random().nextInt((int)duration);//為什么乘1000,再額外加一個隨機數呢? - 防止時間段獎品多時重復//記得取令牌判斷時間時,除以1000,還原真正的時間戳long token = rnd * 1000 + new Random().nextInt(999);//將令牌放入令牌桶tokenList.add(token);//token到實際獎品之間建立映射關系redisUtil.set(RedisKeys.TOKEN + game.getId() +"_"+token,productMap.get(cgp.getProductid()),expire);}});//排序后放入redis隊列Collections.sort(tokenList);log.info("load tokens:{}",tokenList);//從右側壓入隊列,從左到右,時間戳逐個增大redisUtil.rightPushAll(RedisKeys.TOKENS + game.getId(),tokenList);redisUtil.expire(RedisKeys.TOKENS + game.getId(),expire);//獎品策略配置信息List<CardGameRules> rules = gameRulesService.listByMap(queryMap);//遍歷策略,存入redis hsetrules.forEach(r -> {redisUtil.hset(RedisKeys.MAXGOAL +game.getId(),r.getUserlevel()+"",r.getGoalTimes());redisUtil.hset(RedisKeys.MAXENTER +game.getId(),r.getUserlevel()+"",r.getEnterTimes());redisUtil.hset(RedisKeys.RANDOMRATE +game.getId(),r.getUserlevel()+"",r.getRandomRate());});redisUtil.expire(RedisKeys.MAXGOAL +game.getId(),expire);redisUtil.expire(RedisKeys.MAXENTER +game.getId(),expire);redisUtil.expire(RedisKeys.RANDOMRATE +game.getId(),expire);//活動狀態變更為已預熱,禁止管理后臺再隨便變動game.setStatus(1);gameService.updateById(game);});}

????????????????????????????????

????????

????????

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/73208.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/73208.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/73208.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

異或和之和 第十四屆藍橋杯大賽軟件賽省賽C/C++ 大學 A 組

異或和之和 題目來源 第十四屆藍橋杯大賽軟件賽省賽C/C++ 大學 A 組 原題鏈接 藍橋杯 異或和之和 https://www.lanqiao.cn/problems/3507/learning/ 問題描述 問題分析 要點1:異或運算 概念 異或(Exclusive OR,簡稱 XOR)是一種數學運算符,常用于邏輯運算與計算機…

從零到一:如何系統化封裝并發布 React 組件庫到 npm

1. 項目初始化 1.1 創建項目 首先&#xff0c;創建一個新的項目目錄并初始化 package.json 文件。 mkdir my-component-library cd my-component-library npm init -y1.2 安裝依賴 安裝開發所需的依賴項&#xff0c;如構建工具、測試框架等。 npm install --save-dev webp…

現代互聯網網絡安全與操作系統安全防御概要

現階段國與國之間不用對方路由器&#xff0c;其實是有道理的&#xff0c;路由器破了&#xff0c;內網非常好攻擊&#xff0c;內網共享開放端口也非常多&#xff0c;更容易攻擊。還有些內存系統與pe系統自帶瀏覽器都沒有javascript腳本功能&#xff0c;也是有道理的&#xff0c;…

2025-03-12 學習記錄--C/C++-PTA 習題8-4 報數

合抱之木&#xff0c;生于毫末&#xff1b;九層之臺&#xff0c;起于累土&#xff1b;千里之行&#xff0c;始于足下。&#x1f4aa;&#x1f3fb; 一、題目描述 ?? 習題8-4 報數 報數游戲是這樣的&#xff1a;有n個人圍成一圈&#xff0c;按順序從1到n編好號。從第一個人開…

【js逆向】某預約票網站 (webpack技術)

1、查看數據包 calendar是需要的數據包&#xff0c;看下它的請求參數。 accTimes參數加密&#xff0c;_times是時間戳。 2、全局搜索 accTimes 關鍵字 3、n的定義 4、把整個js代碼復制下來&#xff0c;應用到了webpack技術&#xff0c;圖中的Q是n

前端模塊管理新思路:如何使用 Import Maps

前言 前端開發中&#xff0c;我們常常需要使用各種庫和模塊來構建功能豐富的應用。在傳統方式中&#xff0c;管理這些庫和模塊的引用可能會有些繁瑣。 幸運的是&#xff0c;Import Maps 的出現為我們提供了一種更簡潔和高效的解決方案。今天我們就來聊聊如何使用 Import Maps。…

AI模型的構建過程是怎樣的(下)

你好,我是舒旻。 上節課,我們講了一個模型構建的前 2 個環節,模型設計和特征工程。今天,我們繼續來講模型構建的其他 3 個環節,說說模型訓練、模型驗證和模型融合中,算法工程師的具體工作內容,以及 AI 產品經理需要掌握的重點。 模型訓練 模型訓練是通過不斷訓練、驗證…

人工智能混合編程實踐:Python ONNX進行圖像超分重建

人工智能混合編程實踐:Python ONNX進行圖像超分重建 前言相關介紹Python簡介ONNX簡介圖像超分辨率重建簡介應用場景前提條件實驗環境項目結構使用Python ONNX進行圖像超分重建sr_py_infer.py參考文獻前言 由于本人水平有限,難免出現錯漏,敬請批評改正。更多精彩內容,可點擊…

視頻理解之Actionclip(論文宏觀解讀)

配合解讀代碼解讀 1.研究背景 1. 視頻行為識別的重要性 視頻行為識別是視頻理解領域的核心任務之一&#xff0c;旨在通過分析視頻內容來識別和分類其中的人物行為或活動。這一任務在多個領域具有重要的應用價值&#xff0c;例如智能監控、人機交互、自動駕駛、醫療健康等。隨…

【mysql】centOS7安裝mysql詳細操作步驟!

【mysql】centOS7安裝mysql詳細操作步驟&#xff01;—通過tar包方式 需要 root 權限&#xff0c;使用 root 用戶進行命令操作。 1. 查看 CentOS 版本 cat /etc/redhat-release2. 安裝rpm包&#xff0c;以8為例 打開 MySQL 官方 yum 倉庫網站&#xff0c;獲取與當前 CentOS …

【網絡編程】事件選擇模型

十、基于I/O模型的網絡開發 10.9 事件選擇模型 10.0.1 基本概念 事件選擇(WSAEventSelect) 模型是另一個有用的異步 I/O 模型。和 WSAAsyncSelect 模 型類似的是&#xff0c;它也允許應用程序在一個或多個套接字上接收以事件為基礎的網絡事件通知&#xff0c;最 主要的差別在…

STM32 F407ZGT6開發板

#ifndef _tftlcd_H #define _tftlcd_H #include "system.h" //定義LCD彩屏的驅動類型 可根據自己手上的彩屏背面型號來選擇打開哪種驅動 //#def…

江科大51單片機筆記【15】直流電機驅動(PWM)

寫在前言 此為博主自學江科大51單片機&#xff08;B站&#xff09;的筆記&#xff0c;方便后續重溫知識 在后面的章節中&#xff0c;為了防止篇幅過長和易于查找&#xff0c;我把一個小節分成兩部分來發&#xff0c;上章節主要是關于本節課的硬件介紹、電路圖、原理圖等理論…

鴻蒙模擬器運行NDK項目失敗 9568347

鴻蒙編譯NDK項目 模擬器運行NDK項目失敗 9568347 23:32:17.572: $ hdc file send D:\study\hongmeng\MyTestNdk\entry\build\default\outputs\default\entry-default-unsigned.hap "data/local/tmp/9fff4611338a424bb31b521bdc3555af" in 30 ms 23:32:17.651: $ hd…

uniapp+Vue3 開發小程序的下載文件功能

小程序下載文件&#xff0c;可以先預覽文件內容&#xff0c;然后在手機上打開文件的工具中選擇保存。 簡單示例&#xff1a;&#xff08;復制到HBuilder直接食用即可&#xff09; <template><view class"container-detail"><view class"example…

電機控制常見面試問題(九)

文章目錄 一、談談電機死區時間1.死區時間過短的后果&#xff1a;2.如何判斷死區時間不足?3.解決方案 二、請描述對實時操作系統&#xff08;RTOS&#xff09;的理解三.解釋FOC算法的原理并比較與其他無刷電機控制算法的優劣四.什么是電機堵轉&#xff0c;如何避免電機堵轉五.…

【分布式】聊聊分布式id實現方案和生產經驗

對于分布式Id來說&#xff0c;在面試過程中也是高頻面試題&#xff0c;所以主要針對分布式id實現方案進行詳細分析下。 應用場景 對于無論是單機還是分布式系統來說&#xff0c;對于很多場景需要全局唯一ID&#xff0c; 數據庫id唯一性日志traceId 可以方便找到日志鏈&#…

【性能測試】Jmeter如何做一份測試報告(3)

本篇文章主要介紹Jmeter中下載插件&#xff08;Jmeter Plugins&#xff09; 如何使用監聽器插件&#xff0c;線程組插件&#xff0c;梯度壓測線程組 測試報告需要去關注的數據&#xff0c;怎么看測試報告圖表 目錄 一&#xff1a;插件下載 1&#xff1a;下載地址 2&#xff…

cocos creator使用mesh修改圖片為圓形,減少使用mask,j減少drawcall,優化性能

cocos creator版本2.4.11 一個mask占用drawcall 3個以上&#xff0c;針對游戲中技能圖標&#xff0c;cd,以及多玩家頭像&#xff0c;是有很大優化空間 1.上代碼&#xff0c;只適合單獨圖片的&#xff0c;不適合在圖集中的圖片 const { ccclass, property } cc._decorator;c…

AI重構SEO關鍵詞布局

內容概要 在搜索引擎優化&#xff08;SEO&#xff09;領域&#xff0c;AI技術的深度應用正在顛覆傳統關鍵詞布局邏輯。通過機器學習算法與語義分析模型&#xff0c;智能系統能夠實時解析海量搜索數據&#xff0c;構建動態詞庫并精準捕捉用戶意圖。相較于依賴人工經驗的關鍵詞篩…