Browse Source

ADD: 定义RPC接口

sunxy 1 year ago
parent
commit
bcfd0af2f7

+ 68 - 0
recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/domain/video/base/UserFeatureInfo.java

@@ -0,0 +1,68 @@
+package com.tzld.piaoquan.recommend.feature.domain.video.base;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @author sunxy
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class UserFeatureInfo {
+    private String mid;
+    private String machineinfoBrand;
+    private String machineinfoModel;
+    private String machineinfoSystem;
+    private String machineinfoPlatform;
+    private String gender; // 性别
+    private String country; // 国家
+    private String province; // 省份
+    private String city; // 市
+    /*
+    过去一小时
+    */
+    private Long u1hourExpCnt;
+    private Long u1hourClickCnt;
+    private Long u1hourShareCnt;
+    private Long u1hourReturnCnt;
+    private Double uCtr1hour;
+    private Double uStr1hour;
+    private Double uRov1hour;
+    private Double uRos1hour;
+    /*
+    今天
+     */
+    private Long uTodayExpCnt;
+    private Long uTodayClickCnt;
+    private Long uTodayShareCnt;
+    private Long uTodayReturnCnt;
+    private Double uCtrToday;
+    private Double uStrToday;
+    private Double uRovToday;
+    private Double uRosToday;
+    /*
+    过去一天
+     */
+    private Long u1dayExpCnt;
+    private Long u1dayClickCnt;
+    private Long u1dayShareCnt;
+    private Long u1dayReturnCnt;
+    private Double uCtr1day;
+    private Double uStr1day;
+    private Double uRov1day;
+    private Double uRos1day;
+    /*
+    过去三天
+     */
+    private Long u3dayExpCnt;
+    private Long u3dayClickCnt;
+    private Long u3dayShareCnt;
+    private Long u3dayReturnCnt;
+    private Double uCtr3day;
+    private Double uStr3day;
+    private Double uRov3day;
+    private Double uRos3day;
+
+}

+ 80 - 0
recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/domain/video/base/VideoFeatureInfo.java

@@ -0,0 +1,80 @@
+package com.tzld.piaoquan.recommend.feature.domain.video.base;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @author sunxy
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class VideoFeatureInfo {
+
+    private Long videoId;
+    private Long playCountTotal;
+    private Integer totalTime;
+    private String gmtCreate;
+    /**
+     * 上传者
+     */
+    private Long uid;
+    /**
+     * 过去十五分钟
+     */
+    private Long i15minExpCnt;
+    private Long i15minClickCnt;
+    private Long i15minShareCnt;
+    private Long i15minReturnCnt;
+    private Double iCtr15min;
+    private Double iStr15min;
+    private Double iRov15min;
+    private Double iRos15min;
+    /**
+     * 过去一小时
+     */
+    private Long i1hourExpCnt;
+    private Long i1hourClickCnt;
+    private Long i1hourShareCnt;
+    private Long i1hourReturnCnt;
+    private Double iCtr1hour;
+    private Double iStr1hour;
+    private Double iRov1hour;
+    private Double iRos1hour;
+    /**
+     * 今天
+     */
+    private Long iTodayExpCnt;
+    private Long iTodayClickCnt;
+    private Long iTodayShareCnt;
+    private Long iTodayReturnCnt;
+    private Double iCtrToday;
+    private Double iStrToday;
+    private Double iRovToday;
+    private Double iRosToday;
+    /*
+    过去一天
+     */
+    private Long i1dayExpCnt;
+    private Long i1dayClickCnt;
+    private Long i1dayShareCnt;
+    private Long i1dayReturnCnt;
+    private Double iCtr1day;
+    private Double iStr1day;
+    private Double iRov1day;
+    private Double iRos1day;
+    /*
+    过去三天
+     */
+    private Long i3dayExpCnt;
+    private Long i3dayClickCnt;
+    private Long i3dayShareCnt;
+    private Long i3dayReturnCnt;
+    private Double iCtr3day;
+    private Double iStr3day;
+    private Double iRov3day;
+    private Double iRos3day;
+
+
+}

+ 132 - 19
recommend-feature-client/src/main/proto/com/tzld/piaoquan/recommend/feature/feature.proto

@@ -102,27 +102,139 @@ message GetUserAdFeatureResponse {
 message AdItemFeatureProto {
     string adId = 1;
     string adCode = 2;
-    string advertiserId = 3;
-    string advertiserCode = 4;
-    string campaignId = 5;
-    string campaignCode = 6;
-    string creativeId = 7;
-    string creativeCode = 8;
-    AdActionFeatureProto day1_cnt_features = 9;
-    AdActionFeatureProto day3_cnt_features = 10;
-    AdActionFeatureProto day7_cnt_features = 11;
-    AdActionFeatureProto month3_cnt_features = 12;
-    AdActionFeatureProto creative_1day_cnt_features = 13;
-    AdActionFeatureProto creative_3day_cnt_features = 14;
-    AdActionFeatureProto creative_7day_cnt_features = 15;
-    AdActionFeatureProto creative_3month_cnt_features = 16;
-    AdActionFeatureProto advertiser_1day_cnt_features = 17;
-    AdActionFeatureProto advertiser_3day_cnt_features = 18;
-    AdActionFeatureProto advertiser_7day_cnt_features = 19;
-    AdActionFeatureProto advertiser_3month_cnt_features = 20;
+  string advertiserId = 3;
+  string advertiserCode = 4;
+  string campaignId = 5;
+  string campaignCode = 6;
+  string creativeId = 7;
+  string creativeCode = 8;
+  AdActionFeatureProto day1_cnt_features = 9;
+  AdActionFeatureProto day3_cnt_features = 10;
+  AdActionFeatureProto day7_cnt_features = 11;
+  AdActionFeatureProto month3_cnt_features = 12;
+  AdActionFeatureProto creative_1day_cnt_features = 13;
+  AdActionFeatureProto creative_3day_cnt_features = 14;
+  AdActionFeatureProto creative_7day_cnt_features = 15;
+  AdActionFeatureProto creative_3month_cnt_features = 16;
+  AdActionFeatureProto advertiser_1day_cnt_features = 17;
+  AdActionFeatureProto advertiser_3day_cnt_features = 18;
+  AdActionFeatureProto advertiser_7day_cnt_features = 19;
+  AdActionFeatureProto advertiser_3month_cnt_features = 20;
 }
 
 
+message GetUserFeatureInfoRequest {
+  repeated string mids = 1;
+}
+
+message GetUserFeatureInfoResponse {
+  /*
+  过去一小时
+  */
+  int64 u1hourExpCnt = 1;
+  int64 u1hourClickCnt = 2;
+  int64 u1hourShareCnt = 3;
+  int64 u1hourReturnCnt = 4;
+  double uCtr1hour = 5;
+  double uStr1hour = 6;
+  double uRov1hour = 7;
+  double uRos1hour = 8;
+  /*
+  今天
+   */
+  int64 uTodayExpCnt = 9;
+  int64 uTodayClickCnt = 10;
+  int64 uTodayShareCnt = 11;
+  int64 uTodayReturnCnt = 12;
+  double uCtrToday = 13;
+  double uStrToday = 14;
+  double uRovToday = 15;
+  double uRosToday = 16;
+  /*
+  过去一天
+   */
+  int64 u1dayExpCnt = 17;
+  int64 u1dayClickCnt = 18;
+  int64 u1dayShareCnt = 19;
+  int64 u1dayReturnCnt = 20;
+  double uCtr1day = 21;
+  double uStr1day = 22;
+  double uRov1day = 23;
+  double uRos1day = 24;
+  /*
+  过去三天
+   */
+  int64 u3dayExpCnt = 25;
+  int64 u3dayClickCnt = 26;
+  int64 u3dayShareCnt = 27;
+  int64 u3dayReturnCnt = 28;
+  double uCtr3day = 29;
+  double uStr3day = 30;
+  double uRov3day = 31;
+  double uRos3day = 32;
+
+  string mid = 33;
+  string machineinfoBrand = 34;
+  string machineinfoModel = 35;
+  string machineinfoSystem = 36;
+  string machineinfoPlatform = 37;
+  string gender = 38;
+  string country = 39;
+  string province = 40;
+  string city = 41;
+}
+
+message GetVideoFeatureInfoRequest {
+  repeated int64 videoIds = 1;
+}
+
+message GetVideoFeatureInfoResponse {
+  int64 videoId = 1;
+  int64 playCountTotal = 2;
+  int32 totalTime = 3;
+  string gmtCreate = 4;
+  int64 uid = 5;  // 上传者
+  int64 i15minExpCnt = 6;  // 过去十五分钟
+  int64 i15minClickCnt = 7;
+  int64 i15minShareCnt = 8;
+  int64 i15minReturnCnt = 9;
+  double iCtr15min = 10;
+  double iStr15min = 11;
+  double iRov15min = 12;
+  double iRos15min = 13;
+  int64 i1hourExpCnt = 14;  // 过去一小时
+  int64 i1hourClickCnt = 15;
+  int64 i1hourShareCnt = 16;
+  int64 i1hourReturnCnt = 17;
+  double iCtr1hour = 18;
+  double iStr1hour = 19;
+  double iRov1hour = 20;
+  double iRos1hour = 21;
+  int64 iTodayExpCnt = 22;  // 今天
+  int64 iTodayClickCnt = 23;
+  int64 iTodayShareCnt = 24;
+  int64 iTodayReturnCnt = 25;
+  double iCtrToday = 26;
+  double iStrToday = 27;
+  double iRovToday = 28;
+  double iRosToday = 29;
+  int64 i1dayExpCnt = 30;  // 过去一天
+  int64 i1dayClickCnt = 31;
+  int64 i1dayShareCnt = 32;
+  int64 i1dayReturnCnt = 33;
+  double iCtr1day = 34;
+  double iStr1day = 35;
+  double iRov1day = 36;
+  double iRos1day = 37;
+  int64 i3dayExpCnt = 38;  // 过去三天
+  int64 i3dayClickCnt = 39;
+  int64 i3dayShareCnt = 40;
+  int64 i3dayReturnCnt = 41;
+  double iCtr3day = 42;
+  double iStr3day = 43;
+  double iRov3day = 44;
+  double iRos3day = 45;
+}
 
 message GetAdItemFeatureRequest {
   string ad_id = 1;
@@ -149,5 +261,6 @@ service FeatureService {
   rpc GetUserFeature (GetUserFeatureRequest) returns (GetUserFeatureResponse);
   rpc GetVideoFeature (GetVideoFeatureRequest) returns (GetVideoFeatureResponse);
   rpc GetAllVideoFeature (GetAllVideoFeatureRequest) returns (GetAllVideoFeatureResponse);
-
+  rpc GetUserFeatureInfo (GetUserFeatureInfoRequest) returns (GetUserFeatureInfoResponse);
+  rpc GetVideoFeatureInfo (GetVideoFeatureInfoRequest) returns (GetVideoFeatureInfoResponse);
 }

+ 1 - 1
recommend-feature-service/pom.xml

@@ -91,7 +91,7 @@
         <dependency>
             <groupId>com.tzld.piaoquan</groupId>
             <artifactId>recommend-feature-client</artifactId>
-            <version>1.0.7</version>
+            <version>1.0.8</version>
         </dependency>
         <dependency>
             <groupId>com.google.protobuf</groupId>

+ 4 - 4
recommend-feature-service/src/main/java/com/tzld/piaoquan/recommend/feature/grpcservice/FeatureGrpcService.java

@@ -31,9 +31,9 @@ public class FeatureGrpcService extends FeatureServiceGrpc.FeatureServiceImplBas
 
     @Override
     public void getUserFeature(GetUserFeatureRequest request, StreamObserver<GetUserFeatureResponse> responseObserver) {
-        log.info("FeatureGrpcService getUserFeature request={}", ProtobufUtils.toJson(request));
+        log.info("FeatureGrpcService queryUserFeature request={}", ProtobufUtils.toJson(request));
         GetUserFeatureResponse response = userFeatureService.getUserFeature(request);
-        log.info("FeatureGrpcService getUserFeature response={}", ProtobufUtils.toJson(response));
+        log.info("FeatureGrpcService queryUserFeature response={}", ProtobufUtils.toJson(response));
         responseObserver.onNext(response);
         responseObserver.onCompleted();
     }
@@ -41,9 +41,9 @@ public class FeatureGrpcService extends FeatureServiceGrpc.FeatureServiceImplBas
     @Override
     public void getVideoFeature(GetVideoFeatureRequest request,
                                 StreamObserver<GetVideoFeatureResponse> responseObserver) {
-        log.info("FeatureGrpcService getVideoFeature request={}", ProtobufUtils.toJson(request));
+        log.info("FeatureGrpcService queryVideoFeature request={}", ProtobufUtils.toJson(request));
         GetVideoFeatureResponse response = videoFeatureService.getVideoFeature(request);
-        log.info("FeatureGrpcService getVideoFeature response={}", ProtobufUtils.toJson(response));
+        log.info("FeatureGrpcService queryVideoFeature response={}", ProtobufUtils.toJson(response));
         responseObserver.onNext(response);
         responseObserver.onCompleted();
     }

+ 121 - 0
recommend-feature-service/src/main/java/com/tzld/piaoquan/recommend/feature/service/UserAndVideoFeatureService.java

@@ -0,0 +1,121 @@
+package com.tzld.piaoquan.recommend.feature.service;
+
+import com.alibaba.fastjson.JSONObject;
+import com.tzld.piaoquan.recommend.feature.domain.video.base.UserFeatureInfo;
+import com.tzld.piaoquan.recommend.feature.domain.video.base.VideoFeatureInfo;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+
+import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.*;
+import java.util.stream.Collectors;
+
+/**
+ * @author sunxy
+ */
+@Service
+public class UserAndVideoFeatureService {
+
+    ExecutorService executorService = new ThreadPoolExecutor(16, 16, 0L,
+            TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>());
+
+    private final static Logger log = LoggerFactory.getLogger(UserAndVideoFeatureService.class);
+    private final static String USER_FEATURE_KEY = "recommend.feature.user.recsys.info.{mid}";
+
+    private final static String VIDEO_FEATURE_KEY = "recommend.feature.video.recsys.info.{videoId}";
+
+    @Resource(name = "redisTemplate")
+    private RedisTemplate<String, Object> redisTemplate;
+
+    public List<UserFeatureInfo> queryUserFeature(List<String> mids) {
+        if (CollectionUtils.isEmpty(mids)) {
+            return Collections.emptyList();
+        }
+        // 一次读取不能超过 2000 条
+        if (mids.size() > 2000) {
+            mids = mids.subList(0, 2000);
+        }
+        // 批量读取 Redis
+        List<String> keys = mids.stream().map(mid -> USER_FEATURE_KEY.replace("{mid}", mid)).collect(Collectors.toList());
+        List<Object> resultObjList = redisTemplate.opsForValue().multiGet(keys);
+        if (CollectionUtils.isEmpty(resultObjList)) {
+            return Collections.emptyList();
+        }
+        List<UserFeatureInfo> result = Collections.synchronizedList(new ArrayList<>(resultObjList.size()));
+        // 提交 Callable 任务
+        List<Callable<Void>> callableList = new ArrayList<>(resultObjList.size());
+        for (Object resultObj : resultObjList) {
+            callableList.add(() -> {
+                String resultJsonStr = (String) resultObj;
+                try {
+                    JSONObject resultJson = JSONObject.parseObject(resultJsonStr);
+                    if (resultJson == null) {
+                        return null;
+                    }
+//                    result.add();
+                } catch (Exception e) {
+                    log.error("queryUserFeature error, resultJson:{}", resultJsonStr, e);
+                }
+                return null;
+            });
+        }
+
+        // 并发执行字段转换操作
+        try {
+            executorService.invokeAll(callableList);
+        } catch (InterruptedException e) {
+            log.error("queryUserFeature error, mids:{}", mids, e);
+        }
+
+        return result;
+    }
+
+    public List<VideoFeatureInfo> queryVideoFeature(List<Long> videoIds) {
+        if (CollectionUtils.isEmpty(videoIds)) {
+            return Collections.emptyList();
+        }
+        // 一次读取不能超过 2000 条
+        if (videoIds.size() > 2000) {
+            videoIds = videoIds.subList(0, 2000);
+        }
+        // 批量读取 Redis
+        List<String> keys = videoIds.stream().map(videoId -> VIDEO_FEATURE_KEY.replace("{videoId}", String.valueOf(videoId))).collect(Collectors.toList());
+        List<Object> resultObjList = redisTemplate.opsForValue().multiGet(keys);
+        if (CollectionUtils.isEmpty(resultObjList)) {
+            return Collections.emptyList();
+        }
+        // 提交 Callable 任务
+        List<VideoFeatureInfo> result = Collections.synchronizedList(new ArrayList<>(resultObjList.size()));
+        List<Callable<Void>> callableList = new ArrayList<>(resultObjList.size());
+        for (Object resultObj : resultObjList) {
+            callableList.add(() -> {
+                String resultJsonStr = (String) resultObj;
+                try {
+                    JSONObject resultJson = JSONObject.parseObject(resultJsonStr);
+                    if (resultJson == null) {
+                        return null;
+                    }
+//                    result.add();
+                } catch (Exception e) {
+                    log.error("queryVideoFeature error, resultJson:{}", resultJsonStr, e);
+                }
+                return null;
+            });
+        }
+
+        // 并发执行字段转换操作
+        try {
+            executorService.invokeAll(callableList);
+        } catch (InterruptedException e) {
+            log.error("queryVideoFeature error, videoIds:{}", videoIds, e);
+        }
+
+        return result;
+    }
+}

+ 32 - 0
recommend-feature-service/src/main/java/com/tzld/piaoquan/recommend/feature/web/UserAndVideoFeatureController.java

@@ -0,0 +1,32 @@
+package com.tzld.piaoquan.recommend.feature.web;
+
+import com.tzld.piaoquan.recommend.feature.domain.video.base.UserFeatureInfo;
+import com.tzld.piaoquan.recommend.feature.domain.video.base.VideoFeatureInfo;
+import com.tzld.piaoquan.recommend.feature.service.UserAndVideoFeatureService;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+/**
+ * @author sunxy
+ */
+@RestController
+@RequestMapping("/feature")
+public class UserAndVideoFeatureController {
+
+    @Resource
+    private UserAndVideoFeatureService userAndVideoFeatureService;
+
+    @RequestMapping("/getUserFeature")
+    public List<UserFeatureInfo> getUserFeature(List<String> mids) {
+        return userAndVideoFeatureService.queryUserFeature(mids);
+    }
+
+    @RequestMapping("/getVideoFeature")
+    public List<VideoFeatureInfo> getVideoFeature(List<Long> videoIds) {
+        return userAndVideoFeatureService.queryVideoFeature(videoIds);
+    }
+
+}