|
@@ -1,10 +1,20 @@
|
|
|
package com.tzld.piaoquan.recommend.server.service;
|
|
|
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
+import com.ctrip.framework.apollo.spring.annotation.ApolloJsonValue;
|
|
|
+import com.google.common.cache.CacheBuilder;
|
|
|
+import com.google.common.cache.CacheLoader;
|
|
|
+import com.google.common.cache.LoadingCache;
|
|
|
import com.tzld.piaoquan.recommend.server.gen.common.Result;
|
|
|
import com.tzld.piaoquan.recommend.server.gen.recommend.HomepageRecommendRequest;
|
|
|
import com.tzld.piaoquan.recommend.server.gen.recommend.HomepageRecommendResponse;
|
|
|
import com.tzld.piaoquan.recommend.server.gen.recommend.Video;
|
|
|
import com.tzld.piaoquan.recommend.server.model.param.HomepageRecommendParam;
|
|
|
+import com.tzld.piaoquan.recommend.server.util.DateUtils;
|
|
|
+import com.tzld.piaoquan.recommend.server.util.JSONUtils;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.apache.commons.collections4.MapUtils;
|
|
|
+import org.apache.commons.lang3.RandomUtils;
|
|
|
import org.apache.commons.lang3.StringUtils;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.data.redis.core.RedisTemplate;
|
|
@@ -16,22 +26,46 @@ import javax.annotation.PostConstruct;
|
|
|
import java.text.SimpleDateFormat;
|
|
|
import java.util.*;
|
|
|
import java.util.concurrent.TimeUnit;
|
|
|
+import java.util.concurrent.atomic.AtomicInteger;
|
|
|
|
|
|
|
|
|
* @author dyp
|
|
|
*/
|
|
|
@Service
|
|
|
+@Slf4j
|
|
|
public class RecommendService {
|
|
|
- @Autowired
|
|
|
- private MidService midService;
|
|
|
|
|
|
@Autowired
|
|
|
private RedisTemplate<String, String> redisTemplate;
|
|
|
|
|
|
- private String abExpCode;
|
|
|
|
|
|
private Map<String, String> ab_initial_config_map = new HashMap<>();
|
|
|
|
|
|
+ @ApolloJsonValue("ab_exp_code")
|
|
|
+ private Map<String, Map<String, String>> abExpCodeMap = new HashMap<>();
|
|
|
+
|
|
|
+ @ApolloJsonValue("app_ab_code")
|
|
|
+ private Map<String, Map<String, Map<String, String>>> appAbCodeMap = new HashMap<>();
|
|
|
+
|
|
|
+ private int[] flowPoolIdList = {7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
|
|
|
+
|
|
|
+
|
|
|
+ private LoadingCache<String, Map<String, List<Integer>>> flowPoolConfigCache = CacheBuilder.newBuilder()
|
|
|
+ .maximumSize(10)
|
|
|
+ .refreshAfterWrite(600, TimeUnit.SECONDS)
|
|
|
+ .expireAfterWrite(600, TimeUnit.SECONDS)
|
|
|
+ .expireAfterAccess(600, TimeUnit.SECONDS)
|
|
|
+ .build(new CacheLoader<String, Map<String, List<Integer>>>() {
|
|
|
+ @Override
|
|
|
+ public Map<String, List<Integer>> load(String key) throws Exception {
|
|
|
+ String value = redisTemplate.opsForValue().get(key);
|
|
|
+ if (StringUtils.isEmpty(value)) {
|
|
|
+ return Collections.emptyMap();
|
|
|
+ }
|
|
|
+ return JSONObject.parseObject(value, Map.class);
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
@PostConstruct
|
|
|
public void init() {
|
|
|
ab_initial_config_map.put("VLOG", "095");
|
|
@@ -52,12 +86,48 @@ public class RecommendService {
|
|
|
return specialMidRecommend(request);
|
|
|
}
|
|
|
|
|
|
- HomepageRecommendParam param = genHomepageRecommendParam(request);
|
|
|
+ HomepageRecommendParam param = genHomepageRecommendParam(request, 0);
|
|
|
+ log.info("genHomepageRecommendParam : {}", JSONUtils.toJson(param));
|
|
|
+
|
|
|
+
|
|
|
+ List<Video> videos;
|
|
|
+ String ab_code = param.getAb_code();
|
|
|
+ if (ab_code.equals("60054") || ab_code.equals("60056") || ab_code.equals("60067")
|
|
|
+ || ab_code.equals("60068") || ab_code.equals("60066") || ab_code.equals("60069")
|
|
|
+ || ab_code.equals("60070") || ab_code.equals("60071") || ab_code.equals("60072")
|
|
|
+ || ab_code.equals("60073") || ab_code.equals("60074") || ab_code.equals("60075")
|
|
|
+ || ab_code.equals("60076") || ab_code.equals("60077") || ab_code.equals("60078")
|
|
|
+ || ab_code.equals("60079") || ab_code.equals("60080") || ab_code.equals("60081")
|
|
|
+ || ab_code.equals("60082") || ab_code.equals("60083") || ab_code.equals("60084")
|
|
|
+ || ab_code.equals("60085") || ab_code.equals("60086")) {
|
|
|
+ videos = videoRecommendOld(request, param);
|
|
|
+ } else {
|
|
|
+ videos = videoRecommendNew(request, param);
|
|
|
+ }
|
|
|
+
|
|
|
+ List<Video> result = new ArrayList<>();
|
|
|
+ int i = 0;
|
|
|
+ for (Video v : videos) {
|
|
|
+ result.add(v.toBuilder().setPosition(i++).build());
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ private List<Video> videoRecommendNew(HomepageRecommendRequest request, HomepageRecommendParam param) {
|
|
|
+
|
|
|
return null;
|
|
|
+ }
|
|
|
|
|
|
+ private List<Video> videoRecommendOld(HomepageRecommendRequest request, HomepageRecommendParam param) {
|
|
|
+
|
|
|
+ return null;
|
|
|
}
|
|
|
|
|
|
- private HomepageRecommendParam genHomepageRecommendParam(HomepageRecommendRequest request) {
|
|
|
+ private HomepageRecommendParam genHomepageRecommendParam(HomepageRecommendRequest request, int recommendType) {
|
|
|
HomepageRecommendParam param = new HomepageRecommendParam();
|
|
|
param.setTop_K(3);
|
|
|
param.setFlow_pool_P(0.3);
|
|
@@ -69,22 +139,102 @@ public class RecommendService {
|
|
|
? ab_initial_config_map.get(request.getAppType())
|
|
|
: ab_initial_config_map.get("other");
|
|
|
|
|
|
+ Map<String, String> abExpCode = abExpCodeMap.get(abInitialConfig);
|
|
|
+ param.setAb_code(abExpCode.get("ab_code"));
|
|
|
+ param.setRule_key(abExpCode.get("rule_key"));
|
|
|
+ param.setData_key(abExpCode.get("data_key"));
|
|
|
+ param.setRule_key_30day(abExpCode.get("30day_rule_key"));
|
|
|
+ param.setShield_config("");
|
|
|
+ param.setRank_key_prefix("rank:score1:");
|
|
|
+
|
|
|
+
|
|
|
+ if (StringUtils.isNotBlank(request.getAbExpInfo())) {
|
|
|
+ Map<String, List<Map<String, String>>> map = JSONObject.parseObject(request.getAbExpInfo(), Map.class);
|
|
|
+ Set<String> abExpCodes = new HashSet<>();
|
|
|
+ for (List<Map<String, String>> list : map.values()) {
|
|
|
+ list.stream().forEach(m -> abExpCodes.add(m.get("abExpCode")));
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ if (abExpCodes.contains("211")) {
|
|
|
+ param.setFlow_pool_P(0.9);
|
|
|
+ } else if (abExpCodes.contains("221")) {
|
|
|
+ param.setFlow_pool_P(0.7);
|
|
|
+ } else if (abExpCodes.contains("299")) {
|
|
|
+ param.setFlow_pool_P(0.5);
|
|
|
+ } else if (abExpCodes.contains("300")) {
|
|
|
+ param.setFlow_pool_P(0.4);
|
|
|
+ } else if (abExpCodes.contains("301")) {
|
|
|
+ param.setFlow_pool_P(0.6);
|
|
|
+ } else if (abExpCodes.contains("339")) {
|
|
|
+ param.setFlow_pool_P(0);
|
|
|
+ }
|
|
|
+
|
|
|
+ for (Map.Entry<String, Map<String, String>> entry : abExpCodeMap.entrySet()) {
|
|
|
+ if (abExpCodes.contains(entry.getKey())) {
|
|
|
+ param.setAb_code(entry.getValue().get("ab_code"));
|
|
|
+ param.setRule_key(entry.getValue().get("rule_key"));
|
|
|
+ param.setData_key(entry.getValue().get("data_key"));
|
|
|
+ param.setRank_key_prefix(StringUtils.isNotBlank(entry.getValue().get("rank_key_prefix"))
|
|
|
+ ? entry.getValue().get("rank_key_prefix")
|
|
|
+ : "rank:score1:");
|
|
|
+ param.setRule_key_30day(entry.getValue().get("30day_rule_key"));
|
|
|
+ param.setShield_config(entry.getValue().get("ab_code"));
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ if (StringUtils.isNotBlank(request.getAbInfoData())) {
|
|
|
+ Map<String, Map<String, String>> map = JSONObject.parseObject(request.getAbInfoData(), Map.class);
|
|
|
+ Map<String, String> abInfoAppMap = new HashMap<>();
|
|
|
+
|
|
|
+ for (Map.Entry<String, Map<String, String>> entry : map.entrySet()) {
|
|
|
+ if (MapUtils.isEmpty(entry.getValue())) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ String eventId = entry.getValue().get("eventId");
|
|
|
+ if (StringUtils.isNotBlank(eventId)) {
|
|
|
+ abInfoAppMap.put(entry.getKey(), eventId);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (recommendType == 0) {
|
|
|
+ String eventId = abInfoAppMap.get("10003");
|
|
|
+ Map<String, Map<String, String>> appAbCode = appAbCodeMap.get("10003");
|
|
|
+ if (StringUtils.isNotBlank(eventId) && appAbCode.containsKey(eventId)) {
|
|
|
+ param.setAb_code(appAbCode.get(eventId).get("ab_code"));
|
|
|
+ param.setRule_key(appAbCode.get(eventId).get("rule_key"));
|
|
|
+ param.setData_key(appAbCode.get(eventId).get("data_key"));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ int flowPoolIdChoice = flowPoolIdList[RandomUtils.nextInt(0, flowPoolIdList.length - 1)];
|
|
|
+ param.setFlow_pool_abtest_group("control_group");
|
|
|
+ try {
|
|
|
+ Map<String, List<Integer>> flowPoolConfig = flowPoolConfigCache.get("flow:pool:abtest:config");
|
|
|
+ for (Map.Entry<String, List<Integer>> entry : flowPoolConfig.entrySet()) {
|
|
|
+ if (entry.getValue().contains(flowPoolIdChoice)) {
|
|
|
+ param.setFlow_pool_abtest_group(entry.getKey());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("flowPoolConfigCache get error", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
return param;
|
|
|
}
|
|
|
|
|
|
private HomepageRecommendResponse specialMidRecommend(HomepageRecommendRequest request) {
|
|
|
String keyNamePrefix = "special:videos:item:";
|
|
|
- SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
|
|
|
- Date currentDate = new Date();
|
|
|
- String dateStr = dateFormat.format(currentDate);
|
|
|
+ String dateStr = DateUtils.getCurrentDateStr("yyyyMMdd");
|
|
|
String specialKeyName = keyNamePrefix + dateStr;
|
|
|
if (!redisTemplate.hasKey(specialKeyName)) {
|
|
|
- Calendar calendar = Calendar.getInstance();
|
|
|
- calendar.setTime(currentDate);
|
|
|
- calendar.add(Calendar.DAY_OF_MONTH, -1);
|
|
|
- Date previousDate = calendar.getTime();
|
|
|
- dateStr = dateFormat.format(previousDate);
|
|
|
+ dateStr = DateUtils.getBeforeDaysDateStr("yyyyMMdd", 1);
|
|
|
specialKeyName = keyNamePrefix + dateStr;
|
|
|
}
|
|
|
|
|
@@ -129,4 +279,10 @@ public class RecommendService {
|
|
|
.build();
|
|
|
}
|
|
|
|
|
|
+ public static void main(String[] args) {
|
|
|
+ String json = "{\"ab_test001\":[{\"ab_code\":\"1\",\"config_value\":\"v1\"},{\"ab_code\":\"2\",\"config_value\":\"v2\"}],\"ab_test002\":[{\"ab_code\":\"3\",\"config_value\":\"v3\"},{\"ab_code\":\"4\",\"config_value\":\"v4\"}]}";
|
|
|
+ Map<String, List<Map<String, String>>> map = JSONObject.parseObject(json, Map.class);
|
|
|
+ System.out.println("");
|
|
|
+ }
|
|
|
+
|
|
|
}
|