|
@@ -2,6 +2,7 @@ package com.tzld.piaoquan.recommend.server.service.flowpool;
|
|
|
|
|
|
import com.alibaba.fastjson.JSONObject;
|
|
|
import com.google.common.collect.Lists;
|
|
|
+import com.google.common.collect.Maps;
|
|
|
import com.tzld.piaoquan.recommend.server.common.RedisKeyConstants;
|
|
|
import com.tzld.piaoquan.recommend.server.common.ThreadPoolFactory;
|
|
|
import com.tzld.piaoquan.recommend.server.feign.FlowPoolFeign;
|
|
@@ -23,10 +24,7 @@ import org.springframework.beans.factory.annotation.Value;
|
|
|
import org.springframework.data.redis.core.RedisTemplate;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
-import java.util.ArrayList;
|
|
|
-import java.util.HashMap;
|
|
|
-import java.util.List;
|
|
|
-import java.util.Map;
|
|
|
+import java.util.*;
|
|
|
import java.util.concurrent.ExecutorService;
|
|
|
import java.util.concurrent.TimeUnit;
|
|
|
import java.util.stream.Collectors;
|
|
@@ -153,10 +151,40 @@ public class FlowPoolService {
|
|
|
});
|
|
|
}
|
|
|
|
|
|
+ public void asyncHandleDouHotCache(List<Video> videos, String province) {
|
|
|
+ if (StringUtils.isBlank(province) || CollectionUtils.isEmpty(videos)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ pool.execute(() -> {
|
|
|
+ List<Long> needRemoveVideoIds = new ArrayList<>();
|
|
|
+ for (Video video : videos) {
|
|
|
+ String distributeKey = String.format(RedisKeyConstants.DouHot.LOCAL_DISTRIBUTE_KEY_FORMAT, video.getVideoId(), video.getFlowPool());
|
|
|
+ Long count = redisTemplate.opsForValue().decrement(distributeKey);
|
|
|
+ if (Objects.isNull(count) || count <= 0) {
|
|
|
+ redisTemplate.delete(distributeKey);
|
|
|
+ needRemoveVideoIds.add(video.getVideoId());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (CollectionUtils.isEmpty(needRemoveVideoIds)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 从流量池缓存中移除达到分发次数限制的视频ID
|
|
|
+ String itemKey = String.format(RedisKeyConstants.DouHot.ITEM_REDIS_KEY_FORMAT, province, "1");
|
|
|
+ redisTemplate.opsForSet().remove(itemKey, needRemoveVideoIds);
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
public void syncDouHotFlowPoolVideo() {
|
|
|
+
|
|
|
+ // 获取流量池中 全部热点宝视频
|
|
|
List<FlowPoolVideoInfo> allDouHotVideo = this.findAllDouHotVideoFromFlowPool();
|
|
|
log.info("[DouHot video size]: {}", allDouHotVideo.size());
|
|
|
|
|
|
+ // 获取视频对应的可分发数量
|
|
|
+ Map<String, Integer> videoAndDistributeCountMap = this.findDouHotVideoDistributeCount(allDouHotVideo);
|
|
|
+ log.info("[DouHot view distribute count size]: {}", videoAndDistributeCountMap.size());
|
|
|
+
|
|
|
List<Long> allVideoId = allDouHotVideo.stream()
|
|
|
.map(FlowPoolVideoInfo::getVideoId)
|
|
|
.collect(Collectors.toList());
|
|
@@ -169,6 +197,7 @@ public class FlowPoolService {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ // 过滤掉省份不存在的数据
|
|
|
allDouHotVideo = allDouHotVideo.stream()
|
|
|
.filter(i -> StringUtils.isNotBlank(i.getProvince()))
|
|
|
.collect(Collectors.toList());
|
|
@@ -178,21 +207,35 @@ public class FlowPoolService {
|
|
|
Map<String, List<FlowPoolVideoInfo>> provinceAndVideoListMap = allDouHotVideo.stream()
|
|
|
.collect(Collectors.groupingBy(FlowPoolVideoInfo::getProvince, Collectors.toList()));
|
|
|
|
|
|
+ // 将每个省份的数据写入Redis,并同步写入每个视频在对应流量池中的可分发数量
|
|
|
for (Map.Entry<String, List<FlowPoolVideoInfo>> entry : provinceAndVideoListMap.entrySet()) {
|
|
|
String province = entry.getKey();
|
|
|
- List<String> items = entry.getValue().stream()
|
|
|
- .map(i -> String.format("%d-%s", i.getVideoId(), i.getFlowPool()))
|
|
|
- .collect(Collectors.toList());
|
|
|
-
|
|
|
- log.info("[DouHot province video size]. province: {}, video size: {}", entry.getKey(), items.size());
|
|
|
+ List<FlowPoolVideoInfo> flowPoolVideoInfos = entry.getValue();
|
|
|
|
|
|
String redisKey = String.format(RedisKeyConstants.DouHot.ITEM_REDIS_KEY_FORMAT, province, "1");
|
|
|
- log.info("[DouHot item redis key]: {}", redisKey);
|
|
|
+ log.info("[DouHot item redis key]: redisKey: {}, video size: {}", redisKey, flowPoolVideoInfos.size());
|
|
|
redisTemplate.delete(redisKey);
|
|
|
- redisTemplate.opsForSet().add(redisKey, items.toArray(new String[0]));
|
|
|
+
|
|
|
+ // 将视频添加到Redis缓存中,并设置可分发数量
|
|
|
+ for (FlowPoolVideoInfo flowPoolVideoInfo : flowPoolVideoInfos) {
|
|
|
+ String item = String.format("%d-%s", flowPoolVideoInfo.getVideoId(), flowPoolVideoInfo.getFlowPool());
|
|
|
+
|
|
|
+ // 如果剩余的可分发数量不存在或者小于为 则不添加到Redis中
|
|
|
+ if (!videoAndDistributeCountMap.containsKey(item) || videoAndDistributeCountMap.get(item) <= 0) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ redisTemplate.opsForSet().add(redisKey, item);
|
|
|
+
|
|
|
+ String distributeKey = String.format(RedisKeyConstants.DouHot.LOCAL_DISTRIBUTE_KEY_FORMAT, flowPoolVideoInfo.getVideoId(), flowPoolVideoInfo.getFlowPool());
|
|
|
+ redisTemplate.opsForValue().set(distributeKey, String.valueOf(videoAndDistributeCountMap.get(item)));
|
|
|
+ redisTemplate.expire(distributeKey, 24 * 60 * 60, TimeUnit.SECONDS);
|
|
|
+ }
|
|
|
+
|
|
|
redisTemplate.expire(redisKey, 24 * 60 * 60, TimeUnit.SECONDS);
|
|
|
}
|
|
|
|
|
|
+
|
|
|
}
|
|
|
|
|
|
private Map<Long, String> findAllVideoAndProvinceMap(List<Long> videoIds) {
|
|
@@ -245,5 +288,33 @@ public class FlowPoolService {
|
|
|
}
|
|
|
return result;
|
|
|
}
|
|
|
+
|
|
|
+ private Map<String, Integer> findDouHotVideoDistributeCount(List<FlowPoolVideoInfo> flowPoolVideoInfos) {
|
|
|
+ List<JSONObject> paramJsonList = Lists.newArrayList();
|
|
|
+ for (FlowPoolVideoInfo flowPoolVideoInfo : flowPoolVideoInfos) {
|
|
|
+ JSONObject paramJson = new JSONObject();
|
|
|
+ paramJson.put("videoId", flowPoolVideoInfo.getVideoId());
|
|
|
+ paramJson.put("flowPool", flowPoolVideoInfo.getFlowPool());
|
|
|
+ paramJsonList.add(paramJson);
|
|
|
+ }
|
|
|
+
|
|
|
+ List<FlowPoolVideoInfo> remainFlowPoolVideoInfos = new ArrayList<>(flowPoolVideoInfos.size());
|
|
|
+ List<List<JSONObject>> partition = Lists.partition(paramJsonList, 10);
|
|
|
+ for (List<JSONObject> param : partition) {
|
|
|
+ FlowPoolResponse<List<FlowPoolVideoInfo>> response = flowPoolFeign.remainViewCount(param);
|
|
|
+ if (0 != response.getCode()) {
|
|
|
+ log.error("[remain view count error] responseJson: {}", response);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ remainFlowPoolVideoInfos.addAll(response.getData());
|
|
|
+ }
|
|
|
+
|
|
|
+ Map<String, Integer> distributeCountMap = Maps.newHashMap();
|
|
|
+ for (FlowPoolVideoInfo videoInfo : remainFlowPoolVideoInfos) {
|
|
|
+ String key = String.format("%s-%s", videoInfo.getVideoId(), videoInfo.getFlowPool());
|
|
|
+ distributeCountMap.put(key, videoInfo.getDistributeCount());
|
|
|
+ }
|
|
|
+ return distributeCountMap;
|
|
|
+ }
|
|
|
}
|
|
|
|