瀏覽代碼

Merge branch 'feature_gufengshou_20240326_threshold_correction' into test

gufengshou1 1 年之前
父節點
當前提交
58515a0ed1
共有 16 個文件被更改,包括 410 次插入385 次删除
  1. 2 2
      ad-engine-server/src/main/resources/application-test.yml
  2. 1 1
      ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/predict/constant/RuleRedisKeyConst.java
  3. 3 60
      ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/predict/container/ThresholdModelContainer.java
  4. 12 44
      ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/predict/impl/PredictModelServiceImpl.java
  5. 65 65
      ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/predict/model/threshold/NoShareUserThresholdPredictModel.java
  6. 44 44
      ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/predict/model/threshold/Random602PredictModel.java
  7. 6 8
      ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/predict/model/threshold/RandomPredictModel.java
  8. 134 134
      ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/predict/model/threshold/ScoreV2ThresholdPredictModel.java
  9. 1 1
      ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/VlogAdCtrCalibrationScorer.java
  10. 1 1
      ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/VlogAdCtrLRScorer.java
  11. 1 1
      ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/VlogAdCvrCalibrationScorer.java
  12. 1 1
      ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/VlogAdCvrLRScorer.java
  13. 1 1
      ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/VlogAdThompsonScorer.java
  14. 2 2
      ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/VlogMergeEcpmScorer.java
  15. 102 0
      ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/container/AdCreativeFeatureContainer.java
  16. 34 20
      ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/impl/RankServiceImpl.java

+ 2 - 2
ad-engine-server/src/main/resources/application-test.yml

@@ -41,8 +41,8 @@ spring:
     password: Wqsd@2019
     timeout: 1000
   redis-algorithm:
-#    hostName: r-bp1ps6my7lzg8rdhwx682.redis.rds.aliyuncs.com
-    hostName: r-bp1fogs2mflr1ybfot.redis.rds.aliyuncs.com
+    hostName: r-bp1ps6my7lzg8rdhwx682.redis.rds.aliyuncs.com
+#    hostName: r-bp1fogs2mflr1ybfot.redis.rds.aliyuncs.com
     port: 6379
     password: Wqsd@2019
     timeout: 1000

+ 1 - 1
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/predict/constant/RuleRedisKeyConst.java

@@ -37,6 +37,6 @@ public class RuleRedisKeyConst {
     public static String AD_ENGINE_USER_FUTURE_KEY="ad:engine:user:features:";
 
     //    用户90分享分组结果存放 redis key 前缀,完整格式:mid:90share:group:{mid}
-    public static String KEY_NAME_PREFIX_90_SHARE_TYPE="mid:90share:group:";
+//    public static String KEY_NAME_PREFIX_90_SHARE_TYPE="mid:90share:group:";
 
 }

+ 3 - 60
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/predict/container/ThresholdModelContainer.java

@@ -1,8 +1,6 @@
 package com.tzld.piaoquan.ad.engine.service.predict.container;
 
 import com.tdunning.math.stats.Centroid;
-import com.tdunning.math.stats.MergingDigest;
-import com.tzld.piaoquan.ad.engine.service.predict.model.threshold.ScoreV2ThresholdPredictModel;
 import com.tzld.piaoquan.ad.engine.service.predict.model.threshold.ThresholdPredictModel;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -17,12 +15,11 @@ import java.util.HashMap;
 import java.util.Map;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
 
 @Component
 public class ThresholdModelContainer {
 
-    private final static Logger log = LoggerFactory.getLogger(ScoreV2ThresholdPredictModel.class);
+    private final static Logger log = LoggerFactory.getLogger(ThresholdModelContainer.class);
 
     @Autowired
     private ApplicationContext applicationContext;
@@ -30,7 +27,7 @@ public class ThresholdModelContainer {
     private double position;
 
     public static Map<String,ThresholdPredictModel> modelMap=new HashMap<>();
-//    public static Map<Integer,MergingDigest> mergingDigestMap=new HashMap<>();
+
 
     private static final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
     @PostConstruct
@@ -39,22 +36,7 @@ public class ThresholdModelContainer {
         beanMap.forEach((s,model)->{
             modelMap.put(model.getName(), model);
         });
-        //只关注重点app
-//        mergingDigestMap.put(0, new MergingDigest(10000));
-//        mergingDigestMap.put(3, new MergingDigest(10000));
-//        mergingDigestMap.put(4, new MergingDigest(10000));
-//        mergingDigestMap.put(5, new MergingDigest(10000));
-//        mergingDigestMap.put(21, new MergingDigest(10000));
-//        final Runnable task = new Runnable() {
-//            public void run() {
-//                try {
-//                    printDigestThreshold();
-//                }catch (Exception e){
-//                    e.printStackTrace();
-//                }
-//            }
-//        };
-//        scheduler.scheduleAtFixedRate(task, 0, 1, TimeUnit.MINUTES); // 10分钟
+
     }
 
     public static ThresholdPredictModel getThresholdPredictModel(String modelName){
@@ -65,44 +47,5 @@ public class ThresholdModelContainer {
         return modelMap.get("basic");
     }
 
-//    public static void mergingDigestAddScore(Integer appType,Double score){
-//        mergingDigestMap.getOrDefault(appType,new MergingDigest(1)).add(score);
-//    }
-
-//    public static double getThresholdByTDigest(Integer appType,Double sortPosition){
-//        return  mergingDigestMap.getOrDefault(appType,new MergingDigest(1)).quantile(sortPosition);
-//    }
-
-//    public void printDigestThreshold(){
-//        try {
-//            for(Map.Entry<Integer,MergingDigest> entry:mergingDigestMap.entrySet()){
-//                log.info("svc=printDigestThreshold modelName=modelV2 appType={} mergingDigestThreshold={}"
-//                        , entry.getKey(),entry.getValue().quantile(position));
-//            }
-//
-//        }catch (Exception e){
-//            e.printStackTrace();
-//        }
-//    }
-
 
-//    public static void main(String[] args){
-//        MergingDigest mergingDigest = new MergingDigest(100);
-//        for(long i=0;i<1000;i++){
-//            double newDataPoint = Math.random() * 100;
-//            // 向MergingDigest中添加新数据
-//            mergingDigest.add(newDataPoint);
-//        }
-//        System.out.println(mergingDigest.quantile(0.12));
-//        System.out.println(mergingDigest.quantile(0.6));
-//        Iterable<Centroid> centroids = mergingDigest.centroids();
-//        Integer totalW=0;
-//        Integer totalS=0;
-//        // 遍历质点列表并输出
-//        for (Centroid centroid : centroids) {
-//            System.out.println("值: " + centroid.mean() + ", 权重: " + centroid.count());
-//        }
-//        System.out.println(totalW);
-//        System.out.println(totalS);
-//    }
 }

+ 12 - 44
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/predict/impl/PredictModelServiceImpl.java

@@ -48,16 +48,11 @@ public class PredictModelServiceImpl implements PredictModelService {
     @Autowired
     RoiModelConfig roiModelConfig;
 
-    @Value("${ad.predict.break.switch:false}")
-    private boolean adPredictBreakSwitch;
-    @Value("${ad.predict.break.exp.code:570}")
-    private String adPredictBreakExpCode;
-
     @Value("${ad.predict.share0.exp.code:000}")
     private String adPredictNoShareUserExpCode;
 
-    @Value("${ad.predict.90d.share0.exp.code:612}")
-    private String adPredict90DNoShareUserExpCode;
+//    @Value("${ad.predict.90d.share0.exp.code:612}")
+//    private String adPredict90DNoShareUserExpCode;
 
     @Value("${ad.predict.immersion.exp.code:607}")
     private String adPredictImmersionExpCode;
@@ -91,17 +86,12 @@ public class PredictModelServiceImpl implements PredictModelService {
         Map<String,List<JSONObject>> configMap=new HashMap<>();
         //该用户所有实验合集
         Set<String> expCodes=new HashSet<>();
-        boolean isHit = false;
         for(Map<String,Object> map:mapList){
             String expCode=map.getOrDefault("abExpCode","").toString();
             expCodes.add(expCode);
             if("555".equals(expCode)){
                 configMap=JSONObject.parseObject(map.get("configValue").toString(),Map.class);
             }
-            //判断570是否命中
-            if (StringUtils.equals(expCode, adPredictBreakExpCode)) {
-                isHit = true;
-            }
         }
 
         int hourOfDay= DateUtils.getCurrentHour();
@@ -142,12 +132,12 @@ public class PredictModelServiceImpl implements PredictModelService {
         // Determine the group to which mid belongs
         String groupClassKey = (String) abtestParam.get("group_class_key");
         String midGroupKeyName = RuleRedisKeyConst.KEY_NAME_PREFIX_MID_GROUP + groupClassKey + ":" + requestParam.getMid();
-        String midGroup=null;
-        if(expCodes.contains(adPredict90DNoShareUserExpCode)){
-            midGroup = redisHelper.getString(RuleRedisKeyConst.KEY_NAME_PREFIX_90_SHARE_TYPE+requestParam.getMid());
-        }else {
-            midGroup = redisHelper.getString(midGroupKeyName);
-        }
+        String midGroup = redisHelper.getString(midGroupKeyName);;
+//        if(expCodes.contains(adPredict90DNoShareUserExpCode)){
+//            midGroup = redisHelper.getString(RuleRedisKeyConst.KEY_NAME_PREFIX_90_SHARE_TYPE+requestParam.getMid());
+//        }else {
+//            midGroup = redisHelper.getString(midGroupKeyName);
+//        }
 
         //没有时为新用户或者无分享用户
         String shareType =midGroup;
@@ -200,17 +190,8 @@ public class PredictModelServiceImpl implements PredictModelService {
         modelParam.setExtraParam(new HashMap<>());
         modelParam.addUserExtraFuture("shareType",shareType);
         setExtraParam(modelParam);
-        if(expCodes.contains("602")){
-            String userEngineFuture=redisHelper.getString(RuleRedisKeyConst.AD_ENGINE_USER_FUTURE_KEY+requestParam.getMid());
-            if(userEngineFuture!=null){
-                modelParam.addAllIntoUserExtraFuture(JSONObject.parseObject(userEngineFuture,Map.class));
-            }else {
-                modelParam.addUserExtraFuture("30rp","0");
-            }
-            result = ThresholdModelContainer.
-                    getThresholdPredictModel("random602")
-                    .predict(modelParam);
-        } else if(expCodes.contains("599")||expCodes.contains(adPredict90DNoShareUserExpCode)){
+
+          if(expCodes.contains("599")){
 //        if(randomModelExpCode!=null){
 //            modelParam.addUserExtraFuture("randomModelKey",ExpCodeEnum.valueOfExpCode(randomModelExpCode).getRandomModelKey());
             result = ThresholdModelContainer.
@@ -222,21 +203,8 @@ public class PredictModelServiceImpl implements PredictModelService {
             result = ThresholdModelContainer.
                     getThresholdPredictModel("immersion")
                     .predict(modelParam);
-        } else if (adPredictBreakSwitch || isHit) {
-            if(expCodes.contains(adPredictNoShareUserExpCode)&&"noShare".equals(shareType)){
-                result = ThresholdModelContainer.
-                        getThresholdPredictModel("share0")
-                        .predict(modelParam);
-            }else if(expCodes.contains(adPredictNoShareUserExpCode)&&"return25_nmids".equals(shareType)){
-                result.put("mid_group", midGroup);
-                result.put("ad_predict", 1);
-                result.put("no_ad_strategy", adPredictNoShareUserExpCode+"_"+midGroup);
-            }else {
-                result = ThresholdModelContainer.
-                        getThresholdPredictModel("modelV2")
-                        .predict(modelParam);
-            }
-        } else {
+        }
+        else {
             Object thresholdMixFunc = abtestParam.getOrDefault("threshold_mix_func", "basic");
             result = ThresholdModelContainer.
                     getThresholdPredictModel(thresholdMixFunc.toString())

+ 65 - 65
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/predict/model/threshold/NoShareUserThresholdPredictModel.java

@@ -1,65 +1,65 @@
-package com.tzld.piaoquan.ad.engine.service.predict.model.threshold;
-
-import com.alibaba.fastjson.JSONObject;
-import com.tzld.piaoquan.ad.engine.commons.score.AdConfig;
-import com.tzld.piaoquan.ad.engine.commons.score.ScoreParam;
-import com.tzld.piaoquan.ad.engine.commons.score.ScorerUtils;
-import com.tzld.piaoquan.ad.engine.commons.util.CommonCollectionUtils;
-import com.tzld.piaoquan.ad.engine.service.predict.container.PredictPidContainer;
-import com.tzld.piaoquan.ad.engine.service.predict.container.RandWContainer;
-import com.tzld.piaoquan.ad.engine.service.predict.container.ThresholdModelContainer;
-import com.tzld.piaoquan.ad.engine.service.predict.param.ThresholdPredictModelParam;
-import com.tzld.piaoquan.ad.engine.service.remote.FeatureRemoteService;
-import com.tzld.piaoquan.recommend.feature.domain.ad.base.AdRankItem;
-import com.tzld.piaoquan.recommend.feature.domain.ad.base.AdRequestContext;
-import com.tzld.piaoquan.recommend.feature.domain.ad.base.UserAdFeature;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.stereotype.Component;
-
-import javax.annotation.PostConstruct;
-import java.time.LocalDateTime;
-import java.time.format.DateTimeFormatter;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Random;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-
-import static com.tzld.piaoquan.ad.engine.commons.score.ScorerUtils.BREAK_CONFIG;
-import static com.tzld.piaoquan.ad.engine.commons.score.ScorerUtils.SHARE0_CONFIG;
-
-@Component
-public class NoShareUserThresholdPredictModel extends ThresholdPredictModel {
-    private final static Logger log = LoggerFactory.getLogger(NoShareUserThresholdPredictModel.class);
-
-    @Value("${ad.predict.threshold.share0:0.4}")
-    private double threshold;
-    @Value("${ad.model.pid.type.share0:-1}")
-    private double pidType;
-
-
-    @Override
-    String initName() {
-        return "share0";
-    }
-
-    @Override
-    public Map<String, Object> predict(ThresholdPredictModelParam modelParam) {
-
-        double score=(modelParam.getMid().hashCode()+ RandWContainer.getRandW())%100/100d;
-        score=score<0?-score:score;
-
-        Map<String, Object> result = new HashMap<>();
-//        result.put("threshold", realThreshold);
-//        result.put("score", maxItem == null ? -1 : maxItem.getScore());
-        result.put("ad_predict", score<threshold?2:1);
-        result.put("score", score);
-
-        return result;
-    }
-}
+//package com.tzld.piaoquan.ad.engine.service.predict.model.threshold;
+//
+//import com.alibaba.fastjson.JSONObject;
+//import com.tzld.piaoquan.ad.engine.commons.score.AdConfig;
+//import com.tzld.piaoquan.ad.engine.commons.score.ScoreParam;
+//import com.tzld.piaoquan.ad.engine.commons.score.ScorerUtils;
+//import com.tzld.piaoquan.ad.engine.commons.util.CommonCollectionUtils;
+//import com.tzld.piaoquan.ad.engine.service.predict.container.PredictPidContainer;
+//import com.tzld.piaoquan.ad.engine.service.predict.container.RandWContainer;
+//import com.tzld.piaoquan.ad.engine.service.predict.container.ThresholdModelContainer;
+//import com.tzld.piaoquan.ad.engine.service.predict.param.ThresholdPredictModelParam;
+//import com.tzld.piaoquan.ad.engine.service.remote.FeatureRemoteService;
+//import com.tzld.piaoquan.recommend.feature.domain.ad.base.AdRankItem;
+//import com.tzld.piaoquan.recommend.feature.domain.ad.base.AdRequestContext;
+//import com.tzld.piaoquan.recommend.feature.domain.ad.base.UserAdFeature;
+//import org.slf4j.Logger;
+//import org.slf4j.LoggerFactory;
+//import org.springframework.beans.factory.annotation.Autowired;
+//import org.springframework.beans.factory.annotation.Value;
+//import org.springframework.stereotype.Component;
+//
+//import javax.annotation.PostConstruct;
+//import java.time.LocalDateTime;
+//import java.time.format.DateTimeFormatter;
+//import java.util.HashMap;
+//import java.util.List;
+//import java.util.Map;
+//import java.util.Random;
+//import java.util.concurrent.Executors;
+//import java.util.concurrent.ScheduledExecutorService;
+//import java.util.concurrent.TimeUnit;
+//
+//import static com.tzld.piaoquan.ad.engine.commons.score.ScorerUtils.BREAK_CONFIG;
+//import static com.tzld.piaoquan.ad.engine.commons.score.ScorerUtils.SHARE0_CONFIG;
+//
+//@Component
+//public class NoShareUserThresholdPredictModel extends ThresholdPredictModel {
+//    private final static Logger log = LoggerFactory.getLogger(NoShareUserThresholdPredictModel.class);
+//
+//    @Value("${ad.predict.threshold.share0:0.4}")
+//    private double threshold;
+//    @Value("${ad.model.pid.type.share0:-1}")
+//    private double pidType;
+//
+//
+//    @Override
+//    String initName() {
+//        return "share0";
+//    }
+//
+//    @Override
+//    public Map<String, Object> predict(ThresholdPredictModelParam modelParam) {
+//
+//        double score=(modelParam.getMid().hashCode()+ RandWContainer.getRandW())%100/100d;
+//        score=score<0?-score:score;
+//
+//        Map<String, Object> result = new HashMap<>();
+////        result.put("threshold", realThreshold);
+////        result.put("score", maxItem == null ? -1 : maxItem.getScore());
+//        result.put("ad_predict", score<threshold?2:1);
+//        result.put("score", score);
+//
+//        return result;
+//    }
+//}

+ 44 - 44
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/predict/model/threshold/Random602PredictModel.java

@@ -1,44 +1,44 @@
-package com.tzld.piaoquan.ad.engine.service.predict.model.threshold;
-
-import com.tzld.piaoquan.ad.engine.service.predict.container.RandWContainer;
-import com.tzld.piaoquan.ad.engine.service.predict.param.ThresholdPredictModelParam;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.stereotype.Component;
-
-import java.util.HashMap;
-import java.util.Map;
-
-@Component
-public class Random602PredictModel extends ThresholdPredictModel {
-    private final static Logger log = LoggerFactory.getLogger(Random602PredictModel.class);
-
-    @Override
-    String initName() {
-        return "random602";
-    }
-
-
-    @Override
-    public Map<String, Object> predict(ThresholdPredictModelParam modelParam) {
-        int hash=modelParam.getMid().hashCode();
-        hash=hash<0?-hash:hash;
-        double score=(hash+ RandWContainer.getRandW())%100/100d;
-        double threshold=Double.parseDouble(
-                modelParam.getExtraParam().getOrDefault(modelParam.getAppType()+"_30rp_"+modelParam.getUserExtraFuture("30rp").toString(),-1
-                ).toString());
-        if(threshold<0d){
-            threshold=Double.parseDouble(
-                    modelParam.getExtraParam().getOrDefault("default_threshold","0.5")
-                            .toString());
-        }
-        Map<String, Object> result = new HashMap<>();
-        result.put("ad_predict", score<threshold?2:1);
-        result.put("score", score);
-        result.put("threshold", threshold);
-        result.put("model", "random600");
-
-        return result;
-    }
-
-}
+//package com.tzld.piaoquan.ad.engine.service.predict.model.threshold;
+//
+//import com.tzld.piaoquan.ad.engine.service.predict.container.RandWContainer;
+//import com.tzld.piaoquan.ad.engine.service.predict.param.ThresholdPredictModelParam;
+//import org.slf4j.Logger;
+//import org.slf4j.LoggerFactory;
+//import org.springframework.stereotype.Component;
+//
+//import java.util.HashMap;
+//import java.util.Map;
+//
+//@Component
+//public class Random602PredictModel extends ThresholdPredictModel {
+//    private final static Logger log = LoggerFactory.getLogger(Random602PredictModel.class);
+//
+//    @Override
+//    String initName() {
+//        return "random602";
+//    }
+//
+//
+//    @Override
+//    public Map<String, Object> predict(ThresholdPredictModelParam modelParam) {
+//        int hash=modelParam.getMid().hashCode();
+//        hash=hash<0?-hash:hash;
+//        double score=(hash+ RandWContainer.getRandW())%100/100d;
+//        double threshold=Double.parseDouble(
+//                modelParam.getExtraParam().getOrDefault(modelParam.getAppType()+"_30rp_"+modelParam.getUserExtraFuture("30rp").toString(),-1
+//                ).toString());
+//        if(threshold<0d){
+//            threshold=Double.parseDouble(
+//                    modelParam.getExtraParam().getOrDefault("default_threshold","0.5")
+//                            .toString());
+//        }
+//        Map<String, Object> result = new HashMap<>();
+//        result.put("ad_predict", score<threshold?2:1);
+//        result.put("score", score);
+//        result.put("threshold", threshold);
+//        result.put("model", "random600");
+//
+//        return result;
+//    }
+//
+//}

+ 6 - 8
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/predict/model/threshold/RandomPredictModel.java

@@ -1,21 +1,14 @@
 package com.tzld.piaoquan.ad.engine.service.predict.model.threshold;
 
+import com.tzld.piaoquan.ad.engine.commons.util.DateUtils;
 import com.tzld.piaoquan.ad.engine.service.predict.container.RandWContainer;
 import com.tzld.piaoquan.ad.engine.service.predict.param.ThresholdPredictModelParam;
-import com.tzld.piaoquan.ad.engine.service.remote.FeatureRemoteService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Component;
 
-import javax.annotation.PostConstruct;
 import java.util.HashMap;
 import java.util.Map;
-import java.util.Random;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
 
 @Component
 public class RandomPredictModel extends ThresholdPredictModel {
@@ -40,6 +33,11 @@ public class RandomPredictModel extends ThresholdPredictModel {
                     modelParam.getExtraParam().getOrDefault("default_threshold","0.5")
                     .toString());
         }
+        double correction=Double.parseDouble(
+                modelParam.getExtraParam()
+                        .getOrDefault("E620_"+modelParam.getAppType()+"_"+DateUtils.getCurrentHour(),1
+                ).toString());
+        threshold=threshold*correction;
         Map<String, Object> result = new HashMap<>();
         result.put("ad_predict", score<threshold?2:1);
         result.put("score", score);

+ 134 - 134
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/predict/model/threshold/ScoreV2ThresholdPredictModel.java

@@ -1,134 +1,134 @@
-package com.tzld.piaoquan.ad.engine.service.predict.model.threshold;
-
-import com.alibaba.fastjson.JSONArray;
-import com.alibaba.fastjson.JSONObject;
-import com.tzld.piaoquan.ad.engine.commons.score.AdConfig;
-import com.tzld.piaoquan.ad.engine.commons.score.ScoreParam;
-import com.tzld.piaoquan.ad.engine.commons.score.ScorerUtils;
-import com.tzld.piaoquan.ad.engine.commons.util.CommonCollectionUtils;
-import com.tzld.piaoquan.ad.engine.commons.util.TimerWatchUtil;
-import com.tzld.piaoquan.ad.engine.service.predict.container.PredictPidContainer;
-import com.tzld.piaoquan.ad.engine.service.predict.impl.PredictModelServiceImpl;
-import com.tzld.piaoquan.ad.engine.service.predict.param.ThresholdPredictModelParam;
-import com.tzld.piaoquan.ad.engine.service.remote.FeatureRemoteService;
-import com.tzld.piaoquan.recommend.feature.domain.ad.base.AdRankItem;
-import com.tzld.piaoquan.recommend.feature.domain.ad.base.AdRequestContext;
-import com.tzld.piaoquan.recommend.feature.domain.ad.base.UserAdFeature;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.stereotype.Component;
-
-import java.time.LocalDateTime;
-import java.time.format.DateTimeFormatter;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import static com.tzld.piaoquan.ad.engine.commons.score.ScorerUtils.BREAK_CONFIG;
-
-@Component
-public class ScoreV2ThresholdPredictModel extends ThresholdPredictModel {
-    private final static Logger log = LoggerFactory.getLogger(ScoreV2ThresholdPredictModel.class);
-    @Autowired
-    private FeatureRemoteService featureRemoteService;
-
-    @Value("${ad.predict.threshold:1}")
-    private double threshold;
-    @Value("${ad.model.pid.type:0.0}")
-    private double pidType;
-
-    @Override
-    String initName() {
-        return "modelV2";
-    }
-
-    @Override
-    public Map<String, Object> predict(ThresholdPredictModelParam modelParam) {
-
-        UserAdFeature userAdFeature = featureRemoteService.getUserAdFeature(modelParam.getMid());
-        if (userAdFeature == null) {
-            userAdFeature = new UserAdFeature();
-        }
-        List<AdRankItem> rankItems = featureRemoteService.getAllAdFeatureList(CommonCollectionUtils.toList(AdConfig.getAdIds(), id -> id.toString()));
-
-        // scoreParam
-        AdRequestContext context = new AdRequestContext();
-        context.setApptype(modelParam.getAppType().toString());
-        context.setMachineinfoBrand(modelParam.getMachineInfo().getBrand());
-        context.setMachineinfoModel(modelParam.getMachineInfo().getModel());
-        context.setMachineinfoSdkversion(modelParam.getMachineInfo().getSdkVersion());
-        context.setMachineinfoWchatversion(modelParam.getMachineInfo().getWeChatVersion());
-        LocalDateTime date = LocalDateTime.now();
-        context.setHour(date.getHour() + "");
-        context.setDay(date.format(DateTimeFormatter.ofPattern("yyyyMMdd")));
-        context.setWeek(date.getDayOfWeek().getValue() + "");
-
-        ScoreParam scoreParam = new ScoreParam();
-        scoreParam.setRequestContext(context);
-        scoreParam.getRequestContext().setRegion(modelParam.getRegion().replace("省", ""));
-        scoreParam.getRequestContext().setCity(modelParam.getCity().replace("市", ""));
-        scoreParam.setVideoId(modelParam.getVideoId());
-        scoreParam.setMid(modelParam.getMid());
-        scoreParam.setUid("");
-        scoreParam.setProvince(modelParam.getRegion());
-        scoreParam.setCity(modelParam.getCity());
-        scoreParam.setExtraParam(modelParam.getExtraParam());
-
-        List<AdRankItem> scoreResult = ScorerUtils
-                .getScorerPipeline(BREAK_CONFIG)
-                .scoring(scoreParam, userAdFeature, rankItems);
-
-        // 找出ctr*cvr最大的
-        double max = -1;
-        AdRankItem maxItem = null;
-        for (int i = 0; i < scoreResult.size(); i++) {
-            AdRankItem item = scoreResult.get(i);
-            double ctrCvr = item.getCtr() * item.getCvr();
-            if (ctrCvr > max) {
-                max = ctrCvr;
-                maxItem = item;
-            }
-        }
-
-        double realThreshold=Double.parseDouble(
-                scoreParam.getExtraParam().getOrDefault("ScoreV2ThresholdPredict_"+modelParam.getAppType(),threshold).toString()
-        );
-        int adPredict;
-        //加入pid逻辑
-        if(pidType>1){
-            realThreshold=realThreshold+ PredictPidContainer.getPidLambda(
-                    scoreParam.getExtraParam().getOrDefault("predict_test_id","default")+"_"+modelParam.getAppType());
-        }else if(pidType>=0){
-            realThreshold=PredictPidContainer.getLatestThreshold(
-                    scoreParam.getExtraParam().getOrDefault("predict_test_id","default")+"_"+modelParam.getAppType());
-        }
-
-
-        if (maxItem != null && maxItem.getScore() < realThreshold) {
-            // If final score is below threshold, do not show the ad
-            adPredict = 1;
-        } else {
-            // Otherwise, show the ad
-            adPredict = 2;
-        }
-        if(maxItem != null){
-//            ThresholdModelContainer.mergingDigestAddScore(modelParam.getAppType(),maxItem.getScore());
-            //删除多余打印
-            maxItem.setItemFeature(null);
-            maxItem.setLrSampleString(null);
-            maxItem.setLrSampleStringOrgin(null);
-            log.info("svc=ScoreV2ThresholdPredictModel_predict modelName=ScoreV2ThresholdPredictModel maxItem={} extraParam={} app_type={} realThreshold={}",
-                    JSONObject.toJSONString(maxItem), JSONObject.toJSONString(scoreParam.getExtraParam()),modelParam.getAppType(),realThreshold);
-        }
-
-        Map<String, Object> result = new HashMap<>();
-        result.put("threshold", realThreshold);
-        result.put("score", maxItem == null ? -1 : maxItem.getScore());
-        result.put("ad_predict", adPredict);
-
-
-        return result;
-    }
-}
+//package com.tzld.piaoquan.ad.engine.service.predict.model.threshold;
+//
+//import com.alibaba.fastjson.JSONArray;
+//import com.alibaba.fastjson.JSONObject;
+//import com.tzld.piaoquan.ad.engine.commons.score.AdConfig;
+//import com.tzld.piaoquan.ad.engine.commons.score.ScoreParam;
+//import com.tzld.piaoquan.ad.engine.commons.score.ScorerUtils;
+//import com.tzld.piaoquan.ad.engine.commons.util.CommonCollectionUtils;
+//import com.tzld.piaoquan.ad.engine.commons.util.TimerWatchUtil;
+//import com.tzld.piaoquan.ad.engine.service.predict.container.PredictPidContainer;
+//import com.tzld.piaoquan.ad.engine.service.predict.impl.PredictModelServiceImpl;
+//import com.tzld.piaoquan.ad.engine.service.predict.param.ThresholdPredictModelParam;
+//import com.tzld.piaoquan.ad.engine.service.remote.FeatureRemoteService;
+//import com.tzld.piaoquan.recommend.feature.domain.ad.base.AdRankItem;
+//import com.tzld.piaoquan.recommend.feature.domain.ad.base.AdRequestContext;
+//import com.tzld.piaoquan.recommend.feature.domain.ad.base.UserAdFeature;
+//import org.slf4j.Logger;
+//import org.slf4j.LoggerFactory;
+//import org.springframework.beans.factory.annotation.Autowired;
+//import org.springframework.beans.factory.annotation.Value;
+//import org.springframework.stereotype.Component;
+//
+//import java.time.LocalDateTime;
+//import java.time.format.DateTimeFormatter;
+//import java.util.HashMap;
+//import java.util.List;
+//import java.util.Map;
+//
+//import static com.tzld.piaoquan.ad.engine.commons.score.ScorerUtils.BREAK_CONFIG;
+//
+//@Component
+//public class ScoreV2ThresholdPredictModel extends ThresholdPredictModel {
+//    private final static Logger log = LoggerFactory.getLogger(ScoreV2ThresholdPredictModel.class);
+//    @Autowired
+//    private FeatureRemoteService featureRemoteService;
+//
+//    @Value("${ad.predict.threshold:1}")
+//    private double threshold;
+//    @Value("${ad.model.pid.type:0.0}")
+//    private double pidType;
+//
+//    @Override
+//    String initName() {
+//        return "modelV2";
+//    }
+//
+//    @Override
+//    public Map<String, Object> predict(ThresholdPredictModelParam modelParam) {
+//
+//        UserAdFeature userAdFeature = featureRemoteService.getUserAdFeature(modelParam.getMid());
+//        if (userAdFeature == null) {
+//            userAdFeature = new UserAdFeature();
+//        }
+//        List<AdRankItem> rankItems = featureRemoteService.getAllAdFeatureList(CommonCollectionUtils.toList(AdConfig.getAdIds(), id -> id.toString()));
+//
+//        // scoreParam
+//        AdRequestContext context = new AdRequestContext();
+//        context.setApptype(modelParam.getAppType().toString());
+//        context.setMachineinfoBrand(modelParam.getMachineInfo().getBrand());
+//        context.setMachineinfoModel(modelParam.getMachineInfo().getModel());
+//        context.setMachineinfoSdkversion(modelParam.getMachineInfo().getSdkVersion());
+//        context.setMachineinfoWchatversion(modelParam.getMachineInfo().getWeChatVersion());
+//        LocalDateTime date = LocalDateTime.now();
+//        context.setHour(date.getHour() + "");
+//        context.setDay(date.format(DateTimeFormatter.ofPattern("yyyyMMdd")));
+//        context.setWeek(date.getDayOfWeek().getValue() + "");
+//
+//        ScoreParam scoreParam = new ScoreParam();
+//        scoreParam.setRequestContext(context);
+//        scoreParam.getRequestContext().setRegion(modelParam.getRegion().replace("省", ""));
+//        scoreParam.getRequestContext().setCity(modelParam.getCity().replace("市", ""));
+//        scoreParam.setVideoId(modelParam.getVideoId());
+//        scoreParam.setMid(modelParam.getMid());
+//        scoreParam.setUid("");
+//        scoreParam.setProvince(modelParam.getRegion());
+//        scoreParam.setCity(modelParam.getCity());
+//        scoreParam.setExtraParam(modelParam.getExtraParam());
+//
+//        List<AdRankItem> scoreResult = ScorerUtils
+//                .getScorerPipeline(BREAK_CONFIG)
+//                .scoring(scoreParam, userAdFeature, rankItems);
+//
+//        // 找出ctr*cvr最大的
+//        double max = -1;
+//        AdRankItem maxItem = null;
+//        for (int i = 0; i < scoreResult.size(); i++) {
+//            AdRankItem item = scoreResult.get(i);
+//            double ctrCvr = item.getCtr() * item.getCvr();
+//            if (ctrCvr > max) {
+//                max = ctrCvr;
+//                maxItem = item;
+//            }
+//        }
+//
+//        double realThreshold=Double.parseDouble(
+//                scoreParam.getExtraParam().getOrDefault("ScoreV2ThresholdPredict_"+modelParam.getAppType(),threshold).toString()
+//        );
+//        int adPredict;
+//        //加入pid逻辑
+//        if(pidType>1){
+//            realThreshold=realThreshold+ PredictPidContainer.getPidLambda(
+//                    scoreParam.getExtraParam().getOrDefault("predict_test_id","default")+"_"+modelParam.getAppType());
+//        }else if(pidType>=0){
+//            realThreshold=PredictPidContainer.getLatestThreshold(
+//                    scoreParam.getExtraParam().getOrDefault("predict_test_id","default")+"_"+modelParam.getAppType());
+//        }
+//
+//
+//        if (maxItem != null && maxItem.getScore() < realThreshold) {
+//            // If final score is below threshold, do not show the ad
+//            adPredict = 1;
+//        } else {
+//            // Otherwise, show the ad
+//            adPredict = 2;
+//        }
+//        if(maxItem != null){
+////            ThresholdModelContainer.mergingDigestAddScore(modelParam.getAppType(),maxItem.getScore());
+//            //删除多余打印
+//            maxItem.setItemFeature(null);
+//            maxItem.setLrSampleString(null);
+//            maxItem.setLrSampleStringOrgin(null);
+//            log.info("svc=ScoreV2ThresholdPredictModel_predict modelName=ScoreV2ThresholdPredictModel maxItem={} extraParam={} app_type={} realThreshold={}",
+//                    JSONObject.toJSONString(maxItem), JSONObject.toJSONString(scoreParam.getExtraParam()),modelParam.getAppType(),realThreshold);
+//        }
+//
+//        Map<String, Object> result = new HashMap<>();
+//        result.put("threshold", realThreshold);
+//        result.put("score", maxItem == null ? -1 : maxItem.getScore());
+//        result.put("ad_predict", adPredict);
+//
+//
+//        return result;
+//    }
+//}

+ 1 - 1
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/VlogAdCtrCalibrationScorer.java

@@ -23,7 +23,7 @@ public class VlogAdCtrCalibrationScorer extends BaseCalibrationScorer {
 
     private static final int LOCAL_TIME_OUT = 150;
     private final static Logger LOGGER = LoggerFactory.getLogger(VlogAdCtrCalibrationScorer.class);
-    private static final ExecutorService executorService = Executors.newFixedThreadPool(128);
+    private static final ExecutorService executorService = Executors.newFixedThreadPool(8);
 
     public VlogAdCtrCalibrationScorer(ScorerConfigInfo configInfo) {
         super(configInfo);

+ 1 - 1
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/VlogAdCtrLRScorer.java

@@ -29,7 +29,7 @@ public class VlogAdCtrLRScorer extends BaseLRModelScorer {
 
     private static final int LOCAL_TIME_OUT = 150000;
     private final static Logger LOGGER = LoggerFactory.getLogger(VlogAdCtrLRScorer.class);
-    private static final ExecutorService executorService = Executors.newFixedThreadPool(128);
+    private static final ExecutorService executorService = Executors.newFixedThreadPool(8);
     private static final double defaultUserCtrGroupNumber = 10.0;
     private static final int enterFeedsScoreRatio = 10;
     private static final int enterFeedsScoreNum = 20;

+ 1 - 1
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/VlogAdCvrCalibrationScorer.java

@@ -23,7 +23,7 @@ public class VlogAdCvrCalibrationScorer extends BaseCalibrationScorer {
 
     private static final int LOCAL_TIME_OUT = 150;
     private final static Logger LOGGER = LoggerFactory.getLogger(VlogAdCvrCalibrationScorer.class);
-    private static final ExecutorService executorService = Executors.newFixedThreadPool(128);
+    private static final ExecutorService executorService = Executors.newFixedThreadPool(8);
 
     public VlogAdCvrCalibrationScorer(ScorerConfigInfo configInfo) {
         super(configInfo);

+ 1 - 1
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/VlogAdCvrLRScorer.java

@@ -26,7 +26,7 @@ public class VlogAdCvrLRScorer extends BaseLRModelScorer {
 
     private static final int LOCAL_TIME_OUT = 150;
     private final static Logger LOGGER = LoggerFactory.getLogger(VlogAdCvrLRScorer.class);
-    private static final ExecutorService executorService = Executors.newFixedThreadPool(128);
+    private static final ExecutorService executorService = Executors.newFixedThreadPool(8);
     private static final double defaultUserCtrGroupNumber = 10.0;
     private static final int enterFeedsScoreRatio = 10;
     private static final int enterFeedsScoreNum = 20;

+ 1 - 1
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/VlogAdThompsonScorer.java

@@ -25,7 +25,7 @@ public class VlogAdThompsonScorer extends BaseThompsonSamplingScorer {
 
     private static final int LOCAL_TIME_OUT = 150;
     private final static Logger LOGGER = LoggerFactory.getLogger(VlogAdThompsonScorer.class);
-    private static final ExecutorService executorService = Executors.newFixedThreadPool(128);
+    private static final ExecutorService executorService = Executors.newFixedThreadPool(8);
 
     public VlogAdThompsonScorer(ScorerConfigInfo configInfo) {
         super(configInfo);

+ 2 - 2
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/VlogMergeEcpmScorer.java

@@ -23,7 +23,7 @@ import java.util.concurrent.*;
 public class VlogMergeEcpmScorer extends BaseLRModelScorer {
 
     private final static Logger LOGGER = LoggerFactory.getLogger(VlogMergeEcpmScorer.class);
-    private static final ExecutorService executorService = Executors.newFixedThreadPool(128);
+    private static final ExecutorService executorService = Executors.newFixedThreadPool(8);
     private static final int LOCAL_TIME_OUT = 150;
     public VlogMergeEcpmScorer(ScorerConfigInfo configInfo) {
         super(configInfo);
@@ -84,7 +84,7 @@ public class VlogMergeEcpmScorer extends BaseLRModelScorer {
             item.setScore(ecpm/1000d);
         } catch (Exception e) {
             LOGGER.error("merge Ecpm Score: {} error", "");
-            item.setCtr(0.0);
+            item.setScore(0.0);
         }finally {
             countDownLatch.countDown();
         }

+ 102 - 0
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/container/AdCreativeFeatureContainer.java

@@ -0,0 +1,102 @@
+package com.tzld.piaoquan.ad.engine.service.score.container;
+
+import com.alibaba.fastjson.JSONObject;
+import com.google.common.cache.Cache;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+import com.google.common.collect.ImmutableMap;
+import com.tzld.piaoquan.ad.engine.service.remote.FeatureRemoteService;
+import com.tzld.piaoquan.recommend.feature.domain.ad.base.AdRankItem;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.PostConstruct;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+@Component
+public class AdCreativeFeatureContainer {
+    private final static Logger log = LoggerFactory.getLogger(AdCreativeFeatureContainer.class);
+    @Autowired
+    FeatureRemoteService featureRemoteService;
+    protected Function<Long, AdRankItem> defaultValueFunc= k -> null;;
+    private static LoadingCache<Long, AdRankItem> cache = null;
+
+
+    public static void putIntoCache(Long key, AdRankItem value) {
+        cache.put(key, value);
+    }
+
+    @PostConstruct
+    public void initCache(){
+        cache = CacheBuilder.newBuilder()
+                .maximumSize(1000)
+                .refreshAfterWrite(10, TimeUnit.MINUTES)
+                .expireAfterWrite(10,TimeUnit.MINUTES)
+                .expireAfterAccess(10, TimeUnit.MINUTES)
+                .concurrencyLevel(5)
+                .build(new CacheLoader<Long, AdRankItem>() {
+                    @Override
+                    public AdRankItem load(Long key) {
+                        return AdCreativeFeatureContainer.this.load(key);
+                    }
+
+                    @Override
+                    public Map<Long, AdRankItem> loadAll(Iterable<? extends Long> keys) {
+                        return AdCreativeFeatureContainer.this.loadAll(keys);
+                    }
+                });
+    }
+
+    private AdRankItem load(Long key) {
+        AdRankItem feature = getFromCache(key);
+        if (feature == null) {
+            feature = defaultValueFunc.apply(key);
+        }
+        log.info("svc=load_from_recommend_feature  id={}", JSONObject.toJSONString(key));
+        return feature;
+    }
+
+    private AdRankItem getFromCache(Long key) {
+
+        return  featureRemoteService.getAdFeature(key);
+    }
+
+    private  Map<Long, AdRankItem> loadAll(Iterable<? extends Long> keys) {
+        Iterator<? extends Long> ite = keys.iterator();
+        List<String> keyList = new ArrayList<>();
+        while (ite.hasNext()) {
+            keyList.add(ite.next().toString());
+        }
+        List<AdRankItem> resultList=featureRemoteService.getAllAdFeatureList(keyList);
+        Map<Long, AdRankItem> result = new HashMap<>();
+        for (int i = 0; i < resultList.size(); i++) {
+            result.put(resultList.get(i).getAdId(),resultList.get(i));
+        }
+        log.info("svc=load_from_recommend_feature  idList={}", JSONObject.toJSONString(keyList));
+        return result;
+    }
+    public Map<Long, AdRankItem>  getAll(List<Long> creativeIds) {
+        try {
+            return cache.getAll(creativeIds);
+        } catch (Exception e) {
+            log.error("get all failed {}", e);
+        }
+        return Collections.emptyMap();
+    }
+
+    public AdRankItem get(Long creativeIds) {
+        assert cache != null;
+        try {
+            return cache.getUnchecked(creativeIds);
+        } catch (Exception e) {
+            log.error("get local cache error", e);
+        }
+        return null;
+    }
+}

+ 34 - 20
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/impl/RankServiceImpl.java

@@ -1,6 +1,7 @@
 package com.tzld.piaoquan.ad.engine.service.score.impl;
 
 import com.alibaba.fastjson.JSONObject;
+import com.tzld.piaoquan.ad.engine.service.score.container.AdCreativeFeatureContainer;
 import com.tzld.piaoquan.ad.engine.service.score.container.PidLambdaContainer;
 import com.tzld.piaoquan.ad.engine.service.score.container.PidLambdaV2Container;
 import com.tzld.piaoquan.ad.engine.service.score.dto.AdPlatformBidCreativeDTO;
@@ -40,6 +41,9 @@ public class RankServiceImpl implements RankService {
     FeatureRemoteService featureRemoteService;
     @Autowired
     RankServiceThompsonImpl rankServiceThompson;
+
+    @Autowired
+    AdCreativeFeatureContainer adCreativeFeatureContainer;
     @Value("${ad.model.cpm.max:200}")
     Double cpmMax=200d;
     @Value("${ad.model.cpm.min:30}")
@@ -60,10 +64,16 @@ public class RankServiceImpl implements RankService {
         if(userAdFeature==null){
             userAdFeature=new UserAdFeature();
         }
-        List<AdRankItem> rankItems=featureRemoteService.
-                getAllAdFeatureList(
-                        CommonCollectionUtils.toList(request.getAdIdList(),id->id.toString())
-                );
+
+
+        Map<Long, AdRankItem> cache=adCreativeFeatureContainer.getAll(request.getAdIdList());
+        List<AdRankItem> rankItems=Collections.emptyList();
+        if(!cache.isEmpty()){
+            rankItems=new LinkedList<>(cache.values());
+        }
+//        List<AdRankItem> rankItems=adCreativeFeatureContainer.getAll(request.getAdIdList());
+
+
         //避免recommend-feature出问题
         if(rankItems==null|| rankItems.size()==0){
             rankItems=new LinkedList<>();
@@ -124,19 +134,21 @@ public class RankServiceImpl implements RankService {
         if(userAdFeature==null){
             userAdFeature=new UserAdFeature();
         }
-        Map<String,List<AdPlatformBidCreativeDTO>> groupMap=request
+        Map<Long,List<AdPlatformBidCreativeDTO>> groupMap=request
                 .getCreativeList()
                 .stream()
-                .collect(Collectors.groupingBy(creativeDTO -> creativeDTO.getCreativeId()+""));
+                .collect(Collectors.groupingBy(creativeDTO -> creativeDTO.getCreativeId()));
 
-        List<AdRankItem> rankItems=featureRemoteService.
-                getAllAdFeatureList(
-                        new ArrayList<>(groupMap.keySet())
-                );
 
+        Map<Long, AdRankItem> cache=adCreativeFeatureContainer.getAll(new ArrayList<>(groupMap.keySet()));
+        List<AdRankItem> rankItems=Collections.emptyList();
+        if(!cache.isEmpty()){
+            rankItems=new LinkedList<>(cache.values());
+        }
         for(AdRankItem item:rankItems){
             try {
-                AdPlatformBidCreativeDTO dto=groupMap.get(item.getAdId()+"").get(0);
+//                AdPlatformBidCreativeDTO dto=groupMap.get(item.getAdId()+"").get(0);
+                AdPlatformBidCreativeDTO dto=groupMap.get(item.getAdId()).get(0);
                 item.setBid1(dto.getBid1());
                 item.setBid2(dto.getBid2());
                 item.setCpa(dto.getCpa());
@@ -173,7 +185,8 @@ public class RankServiceImpl implements RankService {
         result.setCreativeId(topItem.getAdId());
         result.setPctr(topItem.getCtr());
         result.setPcvr(topItem.getCvr());
-        result.setCreativeCode(groupMap.get(topItem.getAdId()+"").get(0).getCreativeCode());
+//        result.setCreativeCode(groupMap.get(topItem.getAdId()+"").get(0).getCreativeCode());
+        result.setCreativeCode(groupMap.get(topItem.getAdId()).get(0).getCreativeCode());
         double realECpm=0d;
             //经验值 待定
         realECpm=topItem.getEcpm1();
@@ -222,19 +235,20 @@ public class RankServiceImpl implements RankService {
         if(userAdFeature==null){
             userAdFeature=new UserAdFeature();
         }
-        Map<String,List<AdPlatformBidCreativeDTO>> groupMap=request
+        Map<Long,List<AdPlatformBidCreativeDTO>> groupMap=request
                 .getCreativeList()
                 .stream()
-                .collect(Collectors.groupingBy(creativeDTO -> creativeDTO.getCreativeId()+""));
+                .collect(Collectors.groupingBy(creativeDTO -> creativeDTO.getCreativeId()));
 
-        List<AdRankItem> rankItems=featureRemoteService.
-                getAllAdFeatureList(
-                        new ArrayList<>(groupMap.keySet())
-                );
 
+        Map<Long, AdRankItem> cache=adCreativeFeatureContainer.getAll(new ArrayList<>(groupMap.keySet()));
+        List<AdRankItem> rankItems=Collections.emptyList();
+        if(!cache.isEmpty()){
+            rankItems=new LinkedList<>(cache.values());
+        }
         for(AdRankItem item:rankItems){
             try {
-                AdPlatformBidCreativeDTO dto=groupMap.get(item.getAdId()+"").get(0);
+                AdPlatformBidCreativeDTO dto=groupMap.get(item.getAdId()).get(0);
                 item.setBid1(dto.getBid1());
                 item.setBid2(dto.getBid2());
                 item.setCpa(dto.getCpa());
@@ -270,7 +284,7 @@ public class RankServiceImpl implements RankService {
         result.setCreativeId(topItem.getAdId());
         result.setPctr(topItem.getCtr());
         result.setPcvr(topItem.getCvr());
-        result.setCreativeCode(groupMap.get(topItem.getAdId()+"").get(0).getCreativeCode());
+        result.setCreativeCode(groupMap.get(topItem.getAdId()).get(0).getCreativeCode());
         double realECpm=0d;
         //经验值 待定
         realECpm=topItem.getEcpm1();