中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁(yè) > news >正文

網(wǎng)站的網(wǎng)站地圖怎么做seo推廣外包

網(wǎng)站的網(wǎng)站地圖怎么做,seo推廣外包,做百度推廣去些網(wǎng)站加客戶,手機(jī)網(wǎng)站排名優(yōu)化緩存預(yù)熱 為什么要做預(yù)熱: 當(dāng)活動(dòng)真正開(kāi)始時(shí)&#xff0c;需要超高的并發(fā)訪問(wèn)活動(dòng)相關(guān)信息 必須把必要的數(shù)據(jù)提前加載進(jìn)redis 預(yù)熱的策略: 在msg中寫一個(gè)定時(shí)任務(wù) 每分鐘掃描一遍card_game表 把(開(kāi)始時(shí)間 > 當(dāng)前時(shí)間)&& (開(kāi)始時(shí)間 < 當(dāng)前時(shí)間1分鐘)的活動(dòng)及相…

緩存預(yù)熱

為什么要做預(yù)熱:

當(dāng)活動(dòng)真正開(kāi)始時(shí),需要超高的并發(fā)訪問(wèn)活動(dòng)相關(guān)信息 必須把必要的數(shù)據(jù)提前加載進(jìn)redis

預(yù)熱的策略:

在msg中寫一個(gè)定時(shí)任務(wù)
每分鐘掃描一遍card_game表
把(開(kāi)始時(shí)間?>?當(dāng)前時(shí)間)&&?(開(kāi)始時(shí)間?<=?當(dāng)前時(shí)間+1分鐘)的活動(dòng)及相關(guān)信息放入redis

緩存預(yù)熱流程:

???????代碼上需要取出滿足條件的活動(dòng)列表,對(duì)每個(gè)活動(dòng)查出相應(yīng)的獎(jiǎng)品放到令牌桶,查出相應(yīng)的活動(dòng)策略放到Redis
1、查詢1分鐘內(nèi)的活動(dòng)?

2、循環(huán)遍歷活動(dòng)列表,挨個(gè)處理,假設(shè)當(dāng)前取出的是A

3、查詢A相關(guān)的獎(jiǎng)品列表及數(shù)量?

4、根據(jù)總數(shù)量生成獎(jiǎng)品相關(guān)的令牌桶

5、查詢A相關(guān)的活動(dòng)策略:抽獎(jiǎng)次數(shù)、中獎(jiǎng)次數(shù)等,放入Redis

緩存體系

1)活動(dòng)基本信息?k-v,以活動(dòng)id為key,活動(dòng)對(duì)象為value,永不超時(shí)

redisUtil.set(RedisKeys.INFO+game.getId(),game,-1);

2)活動(dòng)策略信息

使用hset,以活動(dòng)id為group,用戶等級(jí)為key,策略值為value

redisUtil.hset(RedisKeys.MAXGOAL + game.getId(),r.getUserlevel()+"",r.getGoalTimes());
redisUtil.hset(RedisKeys.MAXENTER +
game.getId(),r.getUserlevel()+"",r.getEnterTimes());

3)抽獎(jiǎng)令牌桶?雙端隊(duì)列,以活動(dòng)id為key,在活動(dòng)時(shí)間段內(nèi),隨機(jī)生成時(shí)間戳做令牌,有多少個(gè)獎(jiǎng)品就生成多少個(gè)令牌。令牌即獎(jiǎng)品發(fā)放的時(shí)間點(diǎn)。從小到大排序后從右側(cè)入隊(duì)。

redisUtil.rightPushAll(RedisKeys.TOKENS + game.getId(),tokenList);

4)獎(jiǎng)品映射信息

k-v ,?以活動(dòng)id_令牌為key,獎(jiǎng)品信息為value,會(huì)員獲取到令牌后,如果令牌有效,則用令牌token值,來(lái)這里獲取 獎(jiǎng)品詳細(xì)信息

redisUtil.set(RedisKeys.TOKEN + game.getId() +"_"+token,cardProduct,expire);

5)令牌設(shè)計(jì)技巧?

假設(shè)活動(dòng)時(shí)間間隔太短,獎(jiǎng)品數(shù)量太多。那么極有可能產(chǎn)生的時(shí)間戳發(fā)生重復(fù)。

解決技巧:額外再附加一個(gè)隨機(jī)因子。將 (時(shí)間戳?* 1000 + 3位隨機(jī)數(shù))作為令牌。抽獎(jiǎng)時(shí),將抽中的令牌/1000?,還原真實(shí)的時(shí)間戳。

//活動(dòng)持續(xù)時(shí)間(ms)
long duration = end - start;
long rnd = start + new Random().nextInt((int)duration); 
//為什么乘1000,再額外加一個(gè)隨機(jī)數(shù)呢? - 防止時(shí)間段獎(jiǎng)品多時(shí)重復(fù) 
long token = rnd * 1000 + new Random().nextInt(999);

6)中獎(jiǎng)計(jì)數(shù)?k-v,以活動(dòng)id_用戶id作為key,中獎(jiǎng)數(shù)為value,利用redis原子性,中獎(jiǎng)后incr增加計(jì)數(shù)。 抽獎(jiǎng)次數(shù)計(jì)數(shù)也是同樣的道理

redisUtil.incr(RedisKeys.USERHIT+gameid+"_"+user.getId(),1);

?7)中獎(jiǎng)邏輯判斷 : 抽獎(jiǎng)時(shí),從令牌桶左側(cè)出隊(duì)和當(dāng)前時(shí)間比較,如果令牌時(shí)間戳小于等于當(dāng)前時(shí)間,令牌有效,表示中獎(jiǎng)。大于當(dāng)前 時(shí)間,則令牌無(wú)效,將令牌還回,從左側(cè)壓入隊(duì)列。

代碼開(kāi)發(fā)

代碼在msg項(xiàng)目下的GameTask里,已集成Spring調(diào)度?

看了下Spring調(diào)度 ,@Scheduled內(nèi)寫循環(huán)時(shí)間,下面的代碼會(huì)定時(shí)執(zhí)行

commons模塊下有個(gè)RedisKeys,已經(jīng)定義了可用的Redis key前綴,可以直接使用

接下來(lái)補(bǔ)全GameTask中的函數(shù)

先用QueryWrapper取到下一分鐘所有的任務(wù)

// 獲取當(dāng)前時(shí)間
Date now = new Date();// 查詢將來(lái)1分鐘內(nèi)要開(kāi)始的活動(dòng)
QueryWrapper<CardGame> gameQueryWrapper = new QueryWrapper<>();
// 開(kāi)始時(shí)間大于當(dāng)前時(shí)間
gameQueryWrapper.gt("starttime", now);
// 小于等于(當(dāng)前時(shí)間+1分鐘)
gameQueryWrapper.le("starttime", DateUtils.addMinutes(now, 1));List<CardGame> list = gameService.list(gameQueryWrapper);
if (list.isEmpty()) {// 沒(méi)有查到要開(kāi)始的活動(dòng)log.info("No upcoming games within the next minute.");
} else {log.info("Found {} upcoming games.", list.size());
}

對(duì)于每個(gè)任務(wù),獲取到要存入Redis中的信息

list.forEach(game -> {// 活動(dòng)開(kāi)始時(shí)間long start = game.getStarttime().getTime();// 活動(dòng)結(jié)束時(shí)間long end = game.getEndtime().getTime();// 計(jì)算活動(dòng)結(jié)束時(shí)間到現(xiàn)在還有多少秒,作為redis key過(guò)期時(shí)間long expire = (end - now.getTime()) / 1000;// 活動(dòng)持續(xù)時(shí)間(ms)long duration = end - start;// 創(chuàng)建查詢參數(shù)的MapMap<String, Object> queryMap = new HashMap<>();queryMap.put("gameid", game.getId());

先將基本信息存入Redis

// 活動(dòng)基本信息
game.setStatus(1);
redisUtil.set(RedisKeys.INFO + game.getId(), game, -1);
log.info("Loaded game info: {}, {}, {}, {}", game.getId(), game.getTitle(), game.getStarttime(), game.getEndtime());

把獎(jiǎng)品放入map

// 活動(dòng)獎(jiǎng)品信息
List<CardProductDto> products = gameLoadService.getByGameId(game.getId());
Map<Integer, CardProduct> productMap = new HashMap<>(products.size());
products.forEach(p -> productMap.put(p.getId(), p));
log.info("Loaded product types: {}", productMap.size());
//獎(jiǎng)品數(shù)量等配置信息
List<CardGameProduct> gameProducts = gameProductService.listByMap(queryMap);
log.info("load bind product:{}",gameProducts.size());

令牌桶創(chuàng)建,然后token存入Redis

// 令牌桶
List<Long> tokenList = new ArrayList<>();
gameProducts.forEach(cgp -> {// 生成amount個(gè)start到end之間的隨機(jī)時(shí)間戳做令牌for (int i = 0; i < cgp.getAmount(); i++) {long rnd = start + new Random().nextInt((int) duration);// 為什么乘1000,再額外加一個(gè)隨機(jī)數(shù)呢? - 防止時(shí)間段獎(jiǎng)品多時(shí)重復(fù)// 記得取令牌判斷時(shí)間時(shí),除以1000,還原真正的時(shí)間戳long token = rnd * 1000 + new Random().nextInt(999);// 將令牌放入令牌桶tokenList.add(token);// 以令牌做key,對(duì)應(yīng)的商品為value,創(chuàng)建redis緩存log.info("Token -> Game: {} -> {}", token / 1000, productMap.get(cgp.getProductid()).getName());// Token到實(shí)際獎(jiǎng)品之間建立映射關(guān)系redisUtil.set(RedisKeys.TOKEN + game.getId() + "_" + token, productMap.get(cgp.getProductid()), expire);}
});// 排序后放入redis隊(duì)列
Collections.sort(tokenList);
log.info("Loaded tokens: {}", tokenList);// 從右側(cè)壓入隊(duì)列,從左到右,時(shí)間戳逐個(gè)增大
redisUtil.rightPushAll(RedisKeys.TOKENS + game.getId(), tokenList);
redisUtil.expire(RedisKeys.TOKENS + game.getId(), expire);

接著將策略存入Redis

// 獎(jiǎng)品策略配置信息
List<CardGameRules> rules = gameRulesService.listByMap(queryMap);
// 遍歷策略,存入redis hset
rules.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());log.info("Loaded rules: level={}, enter={}, goal={}, rate={}",r.getUserlevel(), r.getEnterTimes(), r.getGoalTimes(), r.getRandomRate());
});
redisUtil.expire(RedisKeys.MAXGOAL + game.getId(), expire);
redisUtil.expire(RedisKeys.MAXENTER + game.getId(), expire);
redisUtil.expire(RedisKeys.RANDOMRATE + game.getId(), expire);

寫完運(yùn)行發(fā)現(xiàn)每隔一分鐘嘗試將活動(dòng)信息寫入緩存

然后寫了個(gè)緩存接口來(lái)測(cè)試,代碼從Redis里取數(shù)據(jù)即可

@GetMapping("/info/{gameid}")
@ApiOperation(value = "緩存信息")
@ApiImplicitParams({@ApiImplicitParam(name="gameid",value = "活動(dòng)id",example = "1",required = true)
})
public ApiResult info(@PathVariable int gameid) {Map<String, Object> resMap = new LinkedHashMap<>();Map<String, Object> tokenMap = new LinkedHashMap();Object gameInfo = redisUtil.get(RedisKeys.INFO + gameid);Map<Object, Object> maxGoalMap = redisUtil.hmget(RedisKeys.MAXGOAL + gameid);Map<Object, Object> maxEnterMap = redisUtil.hmget(RedisKeys.MAXENTER + gameid);List<Object> tokenList = redisUtil.lrange(RedisKeys.TOKENS + gameid, 0, -1);resMap.put(RedisKeys.INFO + gameid, gameInfo);resMap.put(RedisKeys.MAXGOAL + gameid, maxGoalMap);resMap.put(RedisKeys.MAXENTER + gameid, maxEnterMap);for (Object item : tokenList) {Object tokenData = redisUtil.get(RedisKeys.TOKEN + gameid + "_" + item.toString());Long key = Long.valueOf(item.toString());Date date = new Date(key / 1000);SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");String formattedDate = dateFormat.format(date);tokenMap.put(formattedDate, tokenData);}resMap.put(RedisKeys.TOKENS + gameid, tokenMap);return new ApiResult(200, "緩存信息", resMap);
}

運(yùn)行測(cè)試

在后臺(tái)數(shù)據(jù)庫(kù)啟動(dòng)一個(gè)近期活動(dòng):

查看Redis

http://www.risenshineclean.com/news/50630.html

相關(guān)文章:

  • 企夢(mèng)網(wǎng)站建設(shè)成功的網(wǎng)絡(luò)營(yíng)銷案例及分析
  • 最新章節(jié) 62.一起來(lái)做網(wǎng)站吧網(wǎng)絡(luò)營(yíng)銷有哪些
  • 網(wǎng)站建設(shè)及網(wǎng)絡(luò)營(yíng)銷百度推廣關(guān)鍵詞排名在哪看
  • 網(wǎng)站開(kāi)發(fā)設(shè)計(jì)思想最新疫情最新情況
  • 茂名建站公司模板秦潔婷seo博客
  • 上海浦東建筑建設(shè)網(wǎng)站推廣方案怎么做
  • 阿里云免費(fèi)網(wǎng)站建設(shè)模板廣告聯(lián)盟大全
  • ??涤蛎W(wǎng)站百度一下首頁(yè)百度一下知道
  • 網(wǎng)站廣告聯(lián)盟怎么做的域名注冊(cè)需要什么條件
  • 做一個(gè)醫(yī)院網(wǎng)站多少錢鏈接檢測(cè)工具
  • wordpress調(diào)用tag鞏義關(guān)鍵詞優(yōu)化推廣
  • 網(wǎng)站建設(shè)公司上海做網(wǎng)站公司哪家好國(guó)內(nèi)永久免費(fèi)的云服務(wù)器
  • 北京 工業(yè)網(wǎng)站建設(shè)公司價(jià)格引流推廣
  • 做網(wǎng)站的人能看到瀏覽的人的信息嗎網(wǎng)址如何被快速收錄
  • 個(gè)人網(wǎng)站 阿里云seowhy論壇
  • 建設(shè)網(wǎng)站深圳全媒體運(yùn)營(yíng)師報(bào)名入口
  • 提供網(wǎng)站建設(shè)備案公司微信上怎么做廣告推廣
  • 吳江和城鄉(xiāng)建設(shè)局網(wǎng)站關(guān)鍵信息基礎(chǔ)設(shè)施安全保護(hù)條例
  • 企業(yè)網(wǎng)站 流程推廣產(chǎn)品怎么發(fā)朋友圈
  • 做網(wǎng)站要看什么書百度搜索廣告收費(fèi)標(biāo)準(zhǔn)
  • 做問(wèn)卷的幾個(gè)網(wǎng)站如何優(yōu)化關(guān)鍵詞的排名
  • 國(guó)家建設(shè)部人才交流中心網(wǎng)站廣告公司收費(fèi)價(jià)格表
  • 免費(fèi)單頁(yè)網(wǎng)站在線制作營(yíng)銷軟文500字
  • dw做網(wǎng)站小技巧東莞網(wǎng)絡(luò)營(yíng)銷公司
  • 如何創(chuàng)建一個(gè)平臺(tái)型公司優(yōu)化網(wǎng)站seo策略
  • 廣州網(wǎng)站制作公司優(yōu)化百度競(jìng)價(jià)查詢
  • 企業(yè)網(wǎng)站建設(shè)公司排名河南省網(wǎng)站
  • 紅河州網(wǎng)站建設(shè)制作深圳市企業(yè)網(wǎng)站seo營(yíng)銷工具
  • 廊坊網(wǎng)站建設(shè)外包如何網(wǎng)絡(luò)媒體推廣
  • 郴州網(wǎng)站設(shè)計(jì)較好的公司東莞網(wǎng)絡(luò)優(yōu)化公司