Quellcode durchsuchen

feat(尾号实验): ad-engine 接入尾号实验,与 AB 实验完全隔离

jiandong.liu vor 1 Woche
Ursprung
Commit
17e2af5fa6

+ 3 - 0
ad-engine-commons/src/main/java/com/tzld/piaoquan/ad/engine/commons/param/RankRecommendRequestParam.java

@@ -13,6 +13,9 @@ import java.util.Map;
 @ToString(callSuper = true)
 public class RankRecommendRequestParam extends RecommendRequestParam{
      List<AdPlatformCreativeDTO> adIdList;
+     // 尾号(rootSessionId)实验命中列表,由 ad 服务解析后透传;与 adAbExpArr 来源隔离
+     // 值用 Object:tailIndex 透传过来是数字,Map<String,String> 反序列化可能踩 CCE
+     List<Map<String, Object>> tailExpArr;
      String sessionId;
      String subSessionId;
      String rootSessionId;

+ 2 - 0
ad-engine-commons/src/main/java/com/tzld/piaoquan/ad/engine/commons/score/ScoreParam.java

@@ -26,6 +26,8 @@ public class ScoreParam {
 
     private Set<String> expCodeSet;
 
+    private Set<String> tailExpCodeSet;
+
     /**
      * 本次命中的实验
      */

+ 30 - 0
ad-engine-commons/src/main/java/com/tzld/piaoquan/ad/engine/commons/util/AbUtil.java

@@ -46,4 +46,34 @@ public class AbUtil {
         }
         return "";
     }
+
+    /**
+     * ad-engine 尾号实验固定用「广告算法实验」层 = rootSessionId 倒数第6位(index 5)。
+     * 只认这一层,防止别的位的实验被 ID 误命中。
+     * ponytail: 固定常量;若要不停机切层,改成 Apollo 注入到调用处。
+     */
+    public static final int ENGINE_TAIL_INDEX = 5;
+
+    /**
+     * 展开尾号实验命中列表,只保留生效位(tailIndex)== wantIndex 的实验编号。
+     * tailIndex 透传过来可能是数字也可能是字符串,统一转字符串比较。
+     */
+    public static Set<String> unfoldTailExpCode(List<Map<String, Object>> tailArr, int wantIndex) {
+        if (CollectionUtils.isEmpty(tailArr)) {
+            return new HashSet<>();
+        }
+        return tailArr.stream()
+                .filter(m -> Objects.equals(String.valueOf(wantIndex), String.valueOf(m.get("tailIndex"))))
+                .map(m -> m.get("abExpCode"))
+                .filter(Objects::nonNull)
+                .map(Object::toString)
+                .collect(Collectors.toSet());
+    }
+
+    /**
+     * 尾号实验命中判断:与 AB 来源隔离,直接按实验编号匹配,不走新实验分组逻辑
+     */
+    public static boolean isInTailExp(Collection<String> tailExpCodeSet, String expCode) {
+        return CollectionUtils.isNotEmpty(tailExpCodeSet) && tailExpCodeSet.contains(expCode);
+    }
 }

+ 8 - 2
ad-engine-service/src/main/java/com/tzld/piaoquan/ad/engine/service/score/convert/RequestConvert.java

@@ -48,8 +48,14 @@ public class RequestConvert {
         String expCode = AbUtil.chooseAdAlgExpCode(expCodeSet, request.getAppType(), request.getNewExpGroup());
         scoreParam.setExpCode(expCode);
         if (request instanceof RankRecommendRequestParam) {
-            scoreParam.setRootSessionId(((RankRecommendRequestParam) request).getRootSessionId());
-            scoreParam.setEngineInfo(((RankRecommendRequestParam) request).getEngineInfo());
+            RankRecommendRequestParam rankReq = (RankRecommendRequestParam) request;
+            scoreParam.setRootSessionId(rankReq.getRootSessionId());
+            scoreParam.setEngineInfo(rankReq.getEngineInfo());
+
+            // 尾号实验:只认引擎这一层(倒数第6位/index 5),单独存 tailExpCodeSet,与 AB 完全隔离。
+            // 业务侧用 AbUtil.isInTailExp(tailExpCodeSet, code) 单独判断,不和 AB 的 expCode 混用
+            Set<String> tailExpCodeSet = AbUtil.unfoldTailExpCode(rankReq.getTailExpArr(), AbUtil.ENGINE_TAIL_INDEX);
+            scoreParam.setTailExpCodeSet(tailExpCodeSet);
         }
         return scoreParam;
     }

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

@@ -6,6 +6,7 @@ import com.tzld.piaoquan.ad.engine.commons.dto.AdPlatformCreativeDTO;
 import com.tzld.piaoquan.ad.engine.commons.param.RankRecommendRequestParam;
 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.AbUtil;
 import com.tzld.piaoquan.ad.engine.commons.util.RootSessionIdExpConfig;
 import com.tzld.piaoquan.ad.engine.commons.util.RootSessionIdTailUtil;
 import com.tzld.piaoquan.ad.engine.service.log.LogHubService;
@@ -104,16 +105,10 @@ public class RankServiceImpl implements RankService {
         return adRankItems.get(0);
     }
 
-    @Value("${experimental.target.ids:0,1,2,3}")
-    private Set<String> targetList;
-
     public RankStrategy getRankStrategy(ScoreParam scoreParam) {
-        String rootSessionId = scoreParam.getRootSessionId();
-        if (Objects.equals(scoreParam.getAppType(), 0L) && StringUtils.isNotEmpty(rootSessionId) && rootSessionId.length() >= 6) {
-            String tailSixthChar = String.valueOf(rootSessionId.charAt(rootSessionId.length() - 6));
-            if (targetList.contains(tailSixthChar)) {
-                return ServiceBeanFactory.getBean(RankStrategyBy872.class);
-            }
+        // 尾号实验 875(index 5)命中 → 走 872 排序策略;与 AB 的 expCode 完全隔离
+        if (AbUtil.isInTailExp(scoreParam.getTailExpCodeSet(), "875")) {
+            return ServiceBeanFactory.getBean(RankStrategyBy872.class);
         }
         String rankStrategyCode = getRankStrategyCode(scoreParam);
         switch (rankStrategyCode) {