大营销笔记📒
大营销
第三节:策略概率装配处理
装配流程
- 装配抽奖策略,根据抽奖策略ID(strategy_id)进行装配
- 子流程如下:
- 根据抽奖策略ID(strategy_id)去数据库查询该策略配置下的奖品列表(strategyAwardEntityList),先从redis中读,如果redis中没有,再去数据库中拿,拿完转换一下实体类,存redis中,并返回这个奖品列表
- 拿到奖品列表后,进行第一次装配(此时没有根据权重规则过滤奖品),在redis中存的是该策略ID(strategy_id)下所有的奖品列表。(这一次装配应该是为了后续如果没有权重规则过滤,避免查询不到)
-
装配子流程:需要一个key(strategy_id),一个奖品列表实体类
-
拿最小概率值(方便后续计算)
-
拿概率值总和(所有的概率加一起,后面计算用)
-
获得概率范围,就是用概率总和除以这个最小概率值,向正无穷取整,算出来个大小范围,比如100.0/0.1 就是1000。就是相当于把小数点给去掉,得出来一个范围(0-1000)
-
生成策略概率查找表,生成一个list,大小就是上面的范围大小,然后根据相应的规则向里面填充奖品ID,比如奖品1占10%,就填充100个(以1000为例),把这个list填满。
-
然后乱序处理,交换各个元素的位置,保证它们的随机性,不然抽奖概率会有影响
-
生成一个map,奖品查找表,其实就是把这个list放到map里,key值是 list的大小从小到大(0-list.size()),value值是奖品id
-
最后把这个map存放到redis中,这一步有一个putall操作,如果你的redis报了一个(org.springframework.dao.InvalidDataAccessApiUsageException: ERR Protocol error: invalid multibulk length.)这种异常(windows 环境下3.2.100 版本的 redis 报的,mac 环境下redis版本 7.2.3 没有报,一切正常)可以试试把概率改小,map(默认好像有 100 多万大小)小一点,我这个改到了小数点后一位就正常了,可能是redis配置或者版本的问题。
-
- 装配权重策略,根据这个id去数据库里查,优先查redis,没有再去数据库查,查完存redis并返回 (StrategyEntity)这个实体类
- 从ruleModels中遍历看是否有"rule_weight"这个规则,有就是需要权重过滤,没有,为null直接结束
- 再次验证规则是否有异常,走到这一步是一定有 rule_weight的,如果根据id和ruleWeight查询不到,抛出异常,流程异常结束
- 根据权重规则,重新装配奖品
- 首先拿到 rule_weight 下所有的规则,4000分的规则,5000分的规则等等
- 就是这一串(4000:102,103,104,105 5000:102,103,104,105,106,107 6000:102,103,104,105,106,107,108,109)
- 把规则分割一下,key:(4000:102,103,104,105),value:([102],[103],[104],[105]),value是该规则下所有的奖品id,返回一个map<key,value>
- 遍历这个map,每个key下都有list奖品列表,从第一步装配的(strategyAwardEntityList)克隆一个新的list,从中移除 list奖品 中没有的
- 把这个克隆的新的list重新装配进redis中,参考装配子流程
- 装配结束(此时redis中key如下)
127.0.0.1:6379> keys *
1) "big_market_strategy_rate_range_key_100001_4000:102,103,104,105" // 4000规则下奖品实际范围
2) "big_market_strategy_award_key_100001" // 100001下的所有奖品列表
3) "big_market_strategy_rate_table_key_100001_4000:102,103,104,105" // 4000规则下的map<随机值,奖品>
4) "big_market_strategy_rate_table_key_100001" // 无权重规则下map的奖品实际范围
5) "big_market_strategy_rate_range_key_100001" // 无权重规则下的map<随机值,奖品>
6) "big_market_strategy_key_100001" // 抽奖规则实体 1对1,一个id对应一个抽奖规则实体
7) "big_market_strategy_rate_table_key_100001_6000:102,103,104,105,106,107,108,109" // 6000规则下的map<随机值,奖品>
8) "big_market_strategy_rate_range_key_100001_5000:102,103,104,105,106,107" // 5000规则下奖品实际范围
9) "big_market_strategy_rate_table_key_100001_5000:102,103,104,105,106,107" // 5000规则下的map<随机值,奖品>
10) "big_market_strategy_rate_range_key_100001_6000:102,103,104,105,106,107,108,109" // 6000规则下奖品实际范围
- 到这一步装配完,感觉可以把第一次装配的给删掉,里面存的是所有的没有过滤规则的奖品,而且 key 也不一样
抽奖流程
24-04-22.21:07:53.724 [main ] INFO StrategyArmoryDispatch - rateRange:6
24-04-22.21:07:53.728 [main ] INFO StrategyArmoryDispatch - key:100001_4000:102,103,104,105, result:105
24-04-22.21:07:53.728 [main ] INFO StrategyTest - 测试结果:105 - 4000 策略配置
24-04-22.21:07:53.729 [main ] INFO StrategyArmoryDispatch - rateRange:14
24-04-22.21:07:53.729 [main ] INFO StrategyArmoryDispatch - key:100001_5000:102,103,104,105,106,107, result:106
24-04-22.21:07:53.729 [main ] INFO StrategyTest - 测试结果:106 - 5000 策略配置
24-04-22.21:07:53.729 [main ] INFO StrategyArmoryDispatch - rateRange:4901
24-04-22.21:07:53.730 [main ] INFO StrategyArmoryDispatch - key:100001_6000:102,103,104,105,106,107,108,109, result:107
24-04-22.21:07:53.730 [main ] INFO StrategyTest - 测试结果:107 - 6000 策略配置
抽奖流程需要知道,抽奖的策略ID(strategyId),还有抽奖的规则(ruleWeightValue)
- 拼接出来redis的key,就是id+规则
- 从redis中拿(自动拼接big_market_strategy_rate_range_key_)这个 map 中存储的是生成的随机数,以及该策略 id 下 map 的大小(rateRange),根据 key从 redis中拿到一个概率范围rateRange
- 随机获取 0-rateRange 之间的值,根据key(自动拼接big_market_strategy_rate_table_key_ ) 和生成的随机数从 map 中拿到奖品 id并返回
本文来自博客园,作者:xiaolifc,转载请注明原文链接:https://www.cnblogs.com/xiaolibiji/p/18151606
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!