Explorar o código

Merge branch 'wyp/1205-simAccountAuto' of Server/long-article-recommend into master

wangyunpeng hai 7 meses
pai
achega
9ecf1325e2

+ 5 - 0
long-article-recommend-service/pom.xml

@@ -60,6 +60,11 @@
             <groupId>com.ctrip.framework.apollo</groupId>
             <artifactId>apollo-client</artifactId>
         </dependency>
+        <dependency>
+            <groupId>com.ctrip.framework.apollo</groupId>
+            <artifactId>apollo-openapi</artifactId>
+            <version>1.9.1</version>
+        </dependency>
         <dependency>
             <groupId>org.apache.httpcomponents</groupId>
             <artifactId>httpclient</artifactId>

+ 39 - 0
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/common/ApolloConfigModifier.java

@@ -0,0 +1,39 @@
+package com.tzld.longarticle.recommend.server.common;
+
+import com.ctrip.framework.apollo.openapi.client.ApolloOpenApiClient;
+import com.ctrip.framework.apollo.openapi.dto.NamespaceReleaseDTO;
+import com.ctrip.framework.apollo.openapi.dto.OpenItemDTO;
+import com.tzld.longarticle.recommend.server.util.DateUtils;
+
+public class ApolloConfigModifier {
+
+    public static void modifyConfig(String key, String value, String env) {
+        // 1. Apollo OpenAPI 客户端配置
+        ApolloOpenApiClient client = ApolloOpenApiClient.newBuilder()
+                .withPortalUrl("http://apolloportal-internal.piaoquantv.com/")
+                .withToken("a3234bae4cd0eab36be8107a13106d4a8c04f895")
+                .build();
+
+        // 2. 定义修改参数
+        String appId = "longarticle-recommend";
+        String clusterName = "default";
+        String namespace = "application";
+
+        // 3. 创建配置项
+        OpenItemDTO item = new OpenItemDTO();
+        item.setKey(key);
+        item.setValue(value);
+        item.setDataChangeCreatedBy("wangyunpeng");
+
+        // 4. 调用 API 更新配置
+        client.createOrUpdateItem(appId, env, clusterName, namespace, item);
+
+        // 5. 发布配置
+        NamespaceReleaseDTO releaseDTO = new NamespaceReleaseDTO();
+        releaseDTO.setReleaseTitle(DateUtils.getCurrentDateStr("yyyyMMddHHmmss") + "-release");
+        releaseDTO.setReleaseComment("Release Comment");
+        releaseDTO.setReleasedBy("wangyunpeng");
+        client.publishNamespace(appId, env, clusterName, namespace, releaseDTO);
+        System.out.println("配置已修改并发布成功!");
+    }
+}

+ 1 - 1
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/common/HttpPoolFactory.java

@@ -14,7 +14,7 @@ public final class HttpPoolFactory {
             HttpClientFactory.create(60000, 60000, 200, 200, 0, 60000);
 
     private static CloseableHttpClient NLP =
-            HttpClientFactory.create(15000, 15000, 200, 200, 0, 15000);
+            HttpClientFactory.create(1000, 30000, 200, 200, 0, 5000);
 
     private static CloseableHttpClient ThirtySecond =
             HttpClientFactory.create(30000, 30000, 200, 200, 0, 30000);

+ 1 - 0
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/model/param/RecommendParam.java

@@ -27,5 +27,6 @@ public class RecommendParam {
     private boolean excludeLog = false;
     private String scene;
     private List<Integer> userGroupIds;
+    private Boolean replaceSimilarityAccount = false;
 }
 

+ 1 - 1
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/remote/NLPRemoteService.java

@@ -68,7 +68,7 @@ public class NLPRemoteService {
             bodyParam.put("min_time", accountScoreMinTimeMap.get(accountName));
         }
         int retry = 0;
-        while (retry < 3) {
+        while (retry < 2) {
             retry++;
             try {
                 HttpPost httpPost = new HttpPost(url);

+ 6 - 2
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/service/recommend/RecommendService.java

@@ -101,6 +101,11 @@ public class RecommendService {
     }
 
     private void setStrategy(RecommendRequest request, RecommendParam param) {
+        int historyCount = articleRepository.countByGhIdAndTypeAndItemIndex(request.getGhId(),
+                ArticleTypeEnum.QUNFA.getVal(), 1);
+        if (historyCount < 10) {
+            param.setReplaceSimilarityAccount(true);
+        }
         // 无限发表,设置为无限发表策略
         if (Objects.equals(request.getPushType(), PushTypeEnum.AUTO_PUBLISH.getVal())
                 || Objects.equals(request.getPushType(), PushTypeEnum.ROBOPOST.getVal())) {
@@ -114,8 +119,6 @@ public class RecommendService {
             param.setStrategy(strategyConfig);
         }
         // 历史群发头条小于10条,且开启配置,则走历史表现随机策略
-        int historyCount = articleRepository.countByGhIdAndTypeAndItemIndex(request.getGhId(),
-                ArticleTypeEnum.QUNFA.getVal(), 1);
         if (historyCount < 10 && accountHisJumpStrategyList.contains(request.getGhId())) {
             param.setStrategy(RankStrategyEnum.HIS_JUMP_STRATEGY.getStrategy());
         }
@@ -258,6 +261,7 @@ public class RecommendService {
         rankParam.setScene(param.getScene());
         rankParam.setUserGroupIds(param.getUserGroupIds());
         rankParam.setType(param.getType());
+        rankParam.setReplaceSimilarityAccount(param.getReplaceSimilarityAccount());
 
         return rankParam;
     }

+ 1 - 0
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/service/recommend/rank/RankParam.java

@@ -19,5 +19,6 @@ public class RankParam {
     private String scene;
     private List<Integer> userGroupIds;
     private String type;
+    private Boolean replaceSimilarityAccount = false;
 
 }

+ 1 - 0
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/service/recommend/rank/RankStrategy.java

@@ -64,6 +64,7 @@ public interface RankStrategy {
         scoreParam.setContents(param.getContents());
         scoreParam.setStrategy(param.getStrategy());
         scoreParam.setScene(param.getScene());
+        scoreParam.setReplaceSimilarityAccount(param.getReplaceSimilarityAccount());
         return scoreParam;
     }
 

+ 1 - 0
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/service/recommend/score/ScoreParam.java

@@ -21,4 +21,5 @@ public class ScoreParam {
     private List<Content> contents;
     private String strategy;
     private String scene;
+    private Boolean replaceSimilarityAccount = false;
 }

+ 53 - 14
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/service/recommend/score/strategy/SimilarityStrategy.java

@@ -1,7 +1,8 @@
 package com.tzld.longarticle.recommend.server.service.recommend.score.strategy;
 
 import com.ctrip.framework.apollo.spring.annotation.ApolloJsonValue;
-import com.tzld.longarticle.recommend.server.common.enums.recommend.ArticleTypeEnum;
+import com.tzld.longarticle.recommend.server.model.dto.kimi.KimiResult;
+import com.tzld.longarticle.recommend.server.remote.KimiApiService;
 import com.tzld.longarticle.recommend.server.remote.NLPRemoteService;
 import com.tzld.longarticle.recommend.server.repository.crawler.ArticleRepository;
 import com.tzld.longarticle.recommend.server.service.recommend.score.Score;
@@ -9,13 +10,18 @@ import com.tzld.longarticle.recommend.server.service.recommend.score.ScoreParam;
 import com.tzld.longarticle.recommend.server.service.recommend.score.ScoreStrategy;
 import com.tzld.longarticle.recommend.server.util.CommonCollectionUtils;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.RandomUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.stereotype.Component;
-import org.springframework.util.CollectionUtils;
+import org.springframework.util.StringUtils;
 
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.TimeUnit;
 
 /**
  * @author dyp
@@ -28,9 +34,21 @@ public class SimilarityStrategy implements ScoreStrategy {
     private NLPRemoteService nlpRemoteService;
     @Autowired
     private ArticleRepository articleRepository;
+    @Autowired
+    private KimiApiService kimiApiService;
+
+    @Autowired
+    private RedisTemplate<String, String> redisTemplate;
 
     @ApolloJsonValue("${account.score.sim.replace:{}}")
     private Map<String, String> accountSimScoreReplaceMap;
+    @Value("${kimiSimilarityTypePrompt:}")
+    private String kimiSimilarityTypePrompt;
+    @ApolloJsonValue("${similarityTypeAccountMap:}")
+    private Map<String, List<String>> similarityTypeAccountMap;
+
+    @Value("${spring.profiles.active:prod}")
+    private String env;
 
     @Override
     public List<Score> score(ScoreParam param) {
@@ -40,27 +58,48 @@ public class SimilarityStrategy implements ScoreStrategy {
             return Collections.emptyList();
         }
         String ghId = param.getGhId();
-        if (accountSimScoreReplaceMap.containsKey(ghId)) {
-            int historyCount = articleRepository.countByGhIdAndTypeAndItemIndex(ghId,
-                    ArticleTypeEnum.QUNFA.getVal(), 1);
-            if (historyCount < 10) {
+        if (param.getReplaceSimilarityAccount()) {
+            if (accountSimScoreReplaceMap.containsKey(ghId)) {
                 ghId = accountSimScoreReplaceMap.get(ghId);
+            } else {
+                String redisKey = "AccountSimType_" + param.getAccountName();
+                String type = redisTemplate.opsForValue().get(redisKey);
+                if (!StringUtils.hasText(type)) {
+                    String prompt = kimiSimilarityTypePrompt.replace("accountName", param.getAccountName());
+                    // 调用kimi判断账号类型
+                    KimiResult kimiResult = kimiApiService.requestOfficialApi(prompt, null, null);
+                    if (kimiResult.isSuccess()) {
+                        try {
+                            type = kimiResult.getResponse().getChoices().get(0).getMessage().getContent();
+                            log.info("SimilarityStrategy kimiResultType:{}", type);
+                            redisTemplate.opsForValue().set(redisKey, type, 10L, TimeUnit.DAYS);
+                        } catch (Exception e) {
+                            log.error(kimiResult.getResponse().getChoices().get(0).getMessage().getContent());
+                        }
+                    }
+                }
+                // 根据类型随机再类型池中选取账号
+                List<String> ghIds = similarityTypeAccountMap.get(type);
+                if (CollectionUtils.isNotEmpty(ghIds)) {
+                    ghId = ghIds.get(RandomUtils.nextInt(0, ghIds.size()));
+//                    try {
+//                        Map<String, String> value = accountSimScoreReplaceMap;
+//                        value.put(param.getGhId(), ghId);
+//                        ApolloConfigModifier.modifyConfig("account.score.sim.replace", JSONObject.toJSONString(value), env.toUpperCase());
+//                        log.info("SimilarityStrategy 更新apollo配置 account.score.sim.replace 成功 {}:{}", param.getGhId(), ghId);
+//                    } catch (Exception e) {
+//                        log.error("SimilarityStrategy 更新apollo配置失败", e);
+//                    }
+                }
+                log.info("SimilarityStrategy 排序账号:{} 替换账号:{}", param.getGhId(), ghId);
             }
         }
         Map<String, Double> scoreMap = nlpRemoteService.score(ghId, param.getAccountName(), param.getContents());
 
-//        double min = scoreMap.values().stream()
-//                .min(Double::compareTo)
-//                .orElse(0.0);
-//        double max = scoreMap.values().stream()
-//                .max(Double::compareTo)
-//                .orElse(0.0);
-
         List<Score> scores = CommonCollectionUtils.toList(param.getContents(), c -> {
             Score score = new Score();
             score.setContentId(c.getId());
             double val = scoreMap.get(c.getId()) == null ? 0.0 : scoreMap.get(c.getId());
-            // score.setScore(NormalizationUtils.minMax(val, min, max));
             score.setScore(val);
             score.setStrategy(this);
             return score;