Browse Source

Merge branch 'feature_modelRPCForAd' of algorithm/recommend-server into master

dingyunpeng 1 year ago
parent
commit
aad94505b6
39 changed files with 3152 additions and 21 deletions
  1. 41 0
      recommend-server-client/src/main/java/com/tzld/piaoquan/recommend/server/client/ModelClient.java
  2. 17 0
      recommend-server-client/src/main/java/com/tzld/piaoquan/recommend/server/client/ModelType.java
  3. 1 0
      recommend-server-client/src/main/java/com/tzld/piaoquan/recommend/server/client/RecommendHttpRequest.java
  4. 80 0
      recommend-server-client/src/main/java/com/tzld/piaoquan/recommend/server/gen/model/Model.java
  5. 237 0
      recommend-server-client/src/main/java/com/tzld/piaoquan/recommend/server/gen/model/ModelService.java
  6. 288 0
      recommend-server-client/src/main/java/com/tzld/piaoquan/recommend/server/gen/model/ModelServiceGrpc.java
  7. 1036 0
      recommend-server-client/src/main/java/com/tzld/piaoquan/recommend/server/gen/model/ScoreRequest.java
  8. 63 0
      recommend-server-client/src/main/java/com/tzld/piaoquan/recommend/server/gen/model/ScoreRequestOrBuilder.java
  9. 893 0
      recommend-server-client/src/main/java/com/tzld/piaoquan/recommend/server/gen/model/ScoreResponse.java
  10. 58 0
      recommend-server-client/src/main/java/com/tzld/piaoquan/recommend/server/gen/model/ScoreResponseOrBuilder.java
  11. 24 0
      recommend-server-client/src/main/proto/com/tzld/piaoquan/recommend/server/model.proto
  12. 4 1
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/Application.java
  13. 5 0
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/common/base/RankItem.java
  14. 57 0
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/config/FeatureRedisTemplateConfig.java
  15. 7 11
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/config/RedisTemplateConfig.java
  16. 30 0
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/grpcservice/GrpcAspect.java
  17. 32 0
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/grpcservice/ModelGrpcService.java
  18. 185 0
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/ModelService.java
  19. 2 0
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/PreViewedService.java
  20. 2 0
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/RecommendService.java
  21. 3 0
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/WarmUpService.java
  22. 2 0
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/flowpool/FlowPoolConfigService.java
  23. 2 0
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/flowpool/FlowPoolService.java
  24. 2 0
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/rank/RankService.java
  25. 2 0
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/AbstractFlowPoolWithLevelRecallStrategy.java
  26. 2 0
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/AbstractFlowPoolWithLevelScoreRecallStrategy.java
  27. 2 0
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/AbstractFlowPoolWithScoreRecallStrategy.java
  28. 2 0
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/AbstractRegionRecallStrategy.java
  29. 2 0
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/AbstractVideoRecallStrategy.java
  30. 2 0
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/SpecialRecallStrategy.java
  31. 3 1
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/score/ScorerPipeline.java
  32. 2 1
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/score/ScorerUtils.java
  33. 4 1
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/score/model/ModelManager.java
  34. 3 3
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/util/CommonCollectionUtils.java
  35. 12 1
      recommend-server-service/src/main/resources/application-dev.yml
  36. 11 1
      recommend-server-service/src/main/resources/application-pre.yml
  37. 11 1
      recommend-server-service/src/main/resources/application-prod.yml
  38. 11 0
      recommend-server-service/src/main/resources/application-test.yml
  39. 12 0
      recommend-server-service/src/main/resources/video_score_config_for_ad.conf

+ 41 - 0
recommend-server-client/src/main/java/com/tzld/piaoquan/recommend/server/client/ModelClient.java

@@ -0,0 +1,41 @@
+package com.tzld.piaoquan.recommend.server.client;
+
+import com.tzld.piaoquan.recommend.server.gen.model.ModelServiceGrpc;
+import com.tzld.piaoquan.recommend.server.gen.model.ScoreRequest;
+import com.tzld.piaoquan.recommend.server.gen.model.ScoreResponse;
+import lombok.extern.slf4j.Slf4j;
+import net.devh.boot.grpc.client.inject.GrpcClient;
+import org.springframework.stereotype.Component;
+
+import java.util.Map;
+
+/**
+ * @author dyp
+ */
+@Component
+@Slf4j
+public class ModelClient {
+    @GrpcClient("recommend-server")
+    private ModelServiceGrpc.ModelServiceBlockingStub client;
+
+    public Map<String, Double> getScore(long videoId, String mid, String uid, String city, String province) {
+        ScoreRequest request = ScoreRequest.newBuilder()
+                .setVideoId(videoId)
+                .setMid(mid)
+                .setUid(uid)
+                .setCity(city)
+                .setProvince(province)
+                .build();
+        ScoreResponse response = client.score(request);
+        if (response == null || !response.hasResult()) {
+            log.info("score grpc error");
+            return null;
+        }
+        if (response.getResult().getCode() != 1) {
+            log.info("score grpc code={}, msg={}", response.getResult().getCode(),
+                    response.getResult().getMessage());
+            return null;
+        }
+        return response.getScoreMap();
+    }
+}

+ 17 - 0
recommend-server-client/src/main/java/com/tzld/piaoquan/recommend/server/client/ModelType.java

@@ -0,0 +1,17 @@
+package com.tzld.piaoquan.recommend.server.client;
+
+public enum ModelType {
+    STR("str"),
+    ROS("ros"),
+    ;
+
+    private String key;
+
+    ModelType(String key) {
+        this.key = key;
+    }
+
+    public String getKey() {
+        return key;
+    }
+}

+ 1 - 0
recommend-server-client/src/main/java/com/tzld/piaoquan/recommend/server/client/RecommendHttpRequest.java

@@ -6,6 +6,7 @@ import java.util.Map;
 /**
  * @author dyp
  */
+@Deprecated
 public class RecommendHttpRequest {
     private String requestId;
     private String mid;

+ 80 - 0
recommend-server-client/src/main/java/com/tzld/piaoquan/recommend/server/gen/model/Model.java

@@ -0,0 +1,80 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: com/tzld/piaoquan/recommend/server/model.proto
+
+package com.tzld.piaoquan.recommend.server.gen.model;
+
+public final class Model {
+  private Model() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistryLite registry) {
+  }
+
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+    registerAllExtensions(
+        (com.google.protobuf.ExtensionRegistryLite) registry);
+  }
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_ScoreRequest_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_ScoreRequest_fieldAccessorTable;
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_ScoreResponse_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_ScoreResponse_fieldAccessorTable;
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_ScoreResponse_ScoreEntry_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_ScoreResponse_ScoreEntry_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static  com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n.com/tzld/piaoquan/recommend/server/mod" +
+      "el.proto\032/com/tzld/piaoquan/recommend/se" +
+      "rver/common.proto\"Z\n\014ScoreRequest\022\020\n\010vid" +
+      "eo_id\030\001 \001(\003\022\013\n\003mid\030\002 \001(\t\022\013\n\003uid\030\003 \001(\t\022\014\n" +
+      "\004city\030\004 \001(\t\022\020\n\010province\030\005 \001(\t\"\200\001\n\rScoreR" +
+      "esponse\022\027\n\006result\030\001 \001(\0132\007.Result\022(\n\005scor" +
+      "e\030\002 \003(\0132\031.ScoreResponse.ScoreEntry\032,\n\nSc" +
+      "oreEntry\022\013\n\003key\030\001 \001(\t\022\r\n\005value\030\002 \001(\001:\0028\001" +
+      "26\n\014ModelService\022&\n\005Score\022\r.ScoreRequest" +
+      "\032\016.ScoreResponseB3\n,com.tzld.piaoquan.re" +
+      "commend.server.gen.modelP\001\210\001\001b\006proto3"
+    };
+    descriptor = com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+          com.tzld.piaoquan.recommend.server.gen.common.Common.getDescriptor(),
+        });
+    internal_static_ScoreRequest_descriptor =
+      getDescriptor().getMessageTypes().get(0);
+    internal_static_ScoreRequest_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_ScoreRequest_descriptor,
+        new java.lang.String[] { "VideoId", "Mid", "Uid", "City", "Province", });
+    internal_static_ScoreResponse_descriptor =
+      getDescriptor().getMessageTypes().get(1);
+    internal_static_ScoreResponse_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_ScoreResponse_descriptor,
+        new java.lang.String[] { "Result", "Score", });
+    internal_static_ScoreResponse_ScoreEntry_descriptor =
+      internal_static_ScoreResponse_descriptor.getNestedTypes().get(0);
+    internal_static_ScoreResponse_ScoreEntry_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_ScoreResponse_ScoreEntry_descriptor,
+        new java.lang.String[] { "Key", "Value", });
+    com.tzld.piaoquan.recommend.server.gen.common.Common.getDescriptor();
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}

+ 237 - 0
recommend-server-client/src/main/java/com/tzld/piaoquan/recommend/server/gen/model/ModelService.java

@@ -0,0 +1,237 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: com/tzld/piaoquan/recommend/server/model.proto
+
+package com.tzld.piaoquan.recommend.server.gen.model;
+
+/**
+ * Protobuf service {@code ModelService}
+ */
+public  abstract class ModelService
+    implements com.google.protobuf.Service {
+  protected ModelService() {}
+
+  public interface Interface {
+    /**
+     * <code>rpc Score(.ScoreRequest) returns (.ScoreResponse);</code>
+     */
+    public abstract void score(
+        com.google.protobuf.RpcController controller,
+        com.tzld.piaoquan.recommend.server.gen.model.ScoreRequest request,
+        com.google.protobuf.RpcCallback<com.tzld.piaoquan.recommend.server.gen.model.ScoreResponse> done);
+
+  }
+
+  public static com.google.protobuf.Service newReflectiveService(
+      final Interface impl) {
+    return new ModelService() {
+      @java.lang.Override
+      public  void score(
+          com.google.protobuf.RpcController controller,
+          com.tzld.piaoquan.recommend.server.gen.model.ScoreRequest request,
+          com.google.protobuf.RpcCallback<com.tzld.piaoquan.recommend.server.gen.model.ScoreResponse> done) {
+        impl.score(controller, request, done);
+      }
+
+    };
+  }
+
+  public static com.google.protobuf.BlockingService
+      newReflectiveBlockingService(final BlockingInterface impl) {
+    return new com.google.protobuf.BlockingService() {
+      public final com.google.protobuf.Descriptors.ServiceDescriptor
+          getDescriptorForType() {
+        return getDescriptor();
+      }
+
+      public final com.google.protobuf.Message callBlockingMethod(
+          com.google.protobuf.Descriptors.MethodDescriptor method,
+          com.google.protobuf.RpcController controller,
+          com.google.protobuf.Message request)
+          throws com.google.protobuf.ServiceException {
+        if (method.getService() != getDescriptor()) {
+          throw new java.lang.IllegalArgumentException(
+            "Service.callBlockingMethod() given method descriptor for " +
+            "wrong service type.");
+        }
+        switch(method.getIndex()) {
+          case 0:
+            return impl.score(controller, (com.tzld.piaoquan.recommend.server.gen.model.ScoreRequest)request);
+          default:
+            throw new java.lang.AssertionError("Can't get here.");
+        }
+      }
+
+      public final com.google.protobuf.Message
+          getRequestPrototype(
+          com.google.protobuf.Descriptors.MethodDescriptor method) {
+        if (method.getService() != getDescriptor()) {
+          throw new java.lang.IllegalArgumentException(
+            "Service.getRequestPrototype() given method " +
+            "descriptor for wrong service type.");
+        }
+        switch(method.getIndex()) {
+          case 0:
+            return com.tzld.piaoquan.recommend.server.gen.model.ScoreRequest.getDefaultInstance();
+          default:
+            throw new java.lang.AssertionError("Can't get here.");
+        }
+      }
+
+      public final com.google.protobuf.Message
+          getResponsePrototype(
+          com.google.protobuf.Descriptors.MethodDescriptor method) {
+        if (method.getService() != getDescriptor()) {
+          throw new java.lang.IllegalArgumentException(
+            "Service.getResponsePrototype() given method " +
+            "descriptor for wrong service type.");
+        }
+        switch(method.getIndex()) {
+          case 0:
+            return com.tzld.piaoquan.recommend.server.gen.model.ScoreResponse.getDefaultInstance();
+          default:
+            throw new java.lang.AssertionError("Can't get here.");
+        }
+      }
+
+    };
+  }
+
+  /**
+   * <code>rpc Score(.ScoreRequest) returns (.ScoreResponse);</code>
+   */
+  public abstract void score(
+      com.google.protobuf.RpcController controller,
+      com.tzld.piaoquan.recommend.server.gen.model.ScoreRequest request,
+      com.google.protobuf.RpcCallback<com.tzld.piaoquan.recommend.server.gen.model.ScoreResponse> done);
+
+  public static final
+      com.google.protobuf.Descriptors.ServiceDescriptor
+      getDescriptor() {
+    return com.tzld.piaoquan.recommend.server.gen.model.Model.getDescriptor().getServices().get(0);
+  }
+  public final com.google.protobuf.Descriptors.ServiceDescriptor
+      getDescriptorForType() {
+    return getDescriptor();
+  }
+
+  public final void callMethod(
+      com.google.protobuf.Descriptors.MethodDescriptor method,
+      com.google.protobuf.RpcController controller,
+      com.google.protobuf.Message request,
+      com.google.protobuf.RpcCallback<
+        com.google.protobuf.Message> done) {
+    if (method.getService() != getDescriptor()) {
+      throw new java.lang.IllegalArgumentException(
+        "Service.callMethod() given method descriptor for wrong " +
+        "service type.");
+    }
+    switch(method.getIndex()) {
+      case 0:
+        this.score(controller, (com.tzld.piaoquan.recommend.server.gen.model.ScoreRequest)request,
+          com.google.protobuf.RpcUtil.<com.tzld.piaoquan.recommend.server.gen.model.ScoreResponse>specializeCallback(
+            done));
+        return;
+      default:
+        throw new java.lang.AssertionError("Can't get here.");
+    }
+  }
+
+  public final com.google.protobuf.Message
+      getRequestPrototype(
+      com.google.protobuf.Descriptors.MethodDescriptor method) {
+    if (method.getService() != getDescriptor()) {
+      throw new java.lang.IllegalArgumentException(
+        "Service.getRequestPrototype() given method " +
+        "descriptor for wrong service type.");
+    }
+    switch(method.getIndex()) {
+      case 0:
+        return com.tzld.piaoquan.recommend.server.gen.model.ScoreRequest.getDefaultInstance();
+      default:
+        throw new java.lang.AssertionError("Can't get here.");
+    }
+  }
+
+  public final com.google.protobuf.Message
+      getResponsePrototype(
+      com.google.protobuf.Descriptors.MethodDescriptor method) {
+    if (method.getService() != getDescriptor()) {
+      throw new java.lang.IllegalArgumentException(
+        "Service.getResponsePrototype() given method " +
+        "descriptor for wrong service type.");
+    }
+    switch(method.getIndex()) {
+      case 0:
+        return com.tzld.piaoquan.recommend.server.gen.model.ScoreResponse.getDefaultInstance();
+      default:
+        throw new java.lang.AssertionError("Can't get here.");
+    }
+  }
+
+  public static Stub newStub(
+      com.google.protobuf.RpcChannel channel) {
+    return new Stub(channel);
+  }
+
+  public static final class Stub extends com.tzld.piaoquan.recommend.server.gen.model.ModelService implements Interface {
+    private Stub(com.google.protobuf.RpcChannel channel) {
+      this.channel = channel;
+    }
+
+    private final com.google.protobuf.RpcChannel channel;
+
+    public com.google.protobuf.RpcChannel getChannel() {
+      return channel;
+    }
+
+    public  void score(
+        com.google.protobuf.RpcController controller,
+        com.tzld.piaoquan.recommend.server.gen.model.ScoreRequest request,
+        com.google.protobuf.RpcCallback<com.tzld.piaoquan.recommend.server.gen.model.ScoreResponse> done) {
+      channel.callMethod(
+        getDescriptor().getMethods().get(0),
+        controller,
+        request,
+        com.tzld.piaoquan.recommend.server.gen.model.ScoreResponse.getDefaultInstance(),
+        com.google.protobuf.RpcUtil.generalizeCallback(
+          done,
+          com.tzld.piaoquan.recommend.server.gen.model.ScoreResponse.class,
+          com.tzld.piaoquan.recommend.server.gen.model.ScoreResponse.getDefaultInstance()));
+    }
+  }
+
+  public static BlockingInterface newBlockingStub(
+      com.google.protobuf.BlockingRpcChannel channel) {
+    return new BlockingStub(channel);
+  }
+
+  public interface BlockingInterface {
+    public com.tzld.piaoquan.recommend.server.gen.model.ScoreResponse score(
+        com.google.protobuf.RpcController controller,
+        com.tzld.piaoquan.recommend.server.gen.model.ScoreRequest request)
+        throws com.google.protobuf.ServiceException;
+  }
+
+  private static final class BlockingStub implements BlockingInterface {
+    private BlockingStub(com.google.protobuf.BlockingRpcChannel channel) {
+      this.channel = channel;
+    }
+
+    private final com.google.protobuf.BlockingRpcChannel channel;
+
+    public com.tzld.piaoquan.recommend.server.gen.model.ScoreResponse score(
+        com.google.protobuf.RpcController controller,
+        com.tzld.piaoquan.recommend.server.gen.model.ScoreRequest request)
+        throws com.google.protobuf.ServiceException {
+      return (com.tzld.piaoquan.recommend.server.gen.model.ScoreResponse) channel.callBlockingMethod(
+        getDescriptor().getMethods().get(0),
+        controller,
+        request,
+        com.tzld.piaoquan.recommend.server.gen.model.ScoreResponse.getDefaultInstance());
+    }
+
+  }
+
+  // @@protoc_insertion_point(class_scope:ModelService)
+}
+

+ 288 - 0
recommend-server-client/src/main/java/com/tzld/piaoquan/recommend/server/gen/model/ModelServiceGrpc.java

@@ -0,0 +1,288 @@
+package com.tzld.piaoquan.recommend.server.gen.model;
+
+import static io.grpc.MethodDescriptor.generateFullMethodName;
+import static io.grpc.stub.ClientCalls.asyncBidiStreamingCall;
+import static io.grpc.stub.ClientCalls.asyncClientStreamingCall;
+import static io.grpc.stub.ClientCalls.asyncServerStreamingCall;
+import static io.grpc.stub.ClientCalls.asyncUnaryCall;
+import static io.grpc.stub.ClientCalls.blockingServerStreamingCall;
+import static io.grpc.stub.ClientCalls.blockingUnaryCall;
+import static io.grpc.stub.ClientCalls.futureUnaryCall;
+import static io.grpc.stub.ServerCalls.asyncBidiStreamingCall;
+import static io.grpc.stub.ServerCalls.asyncClientStreamingCall;
+import static io.grpc.stub.ServerCalls.asyncServerStreamingCall;
+import static io.grpc.stub.ServerCalls.asyncUnaryCall;
+import static io.grpc.stub.ServerCalls.asyncUnimplementedStreamingCall;
+import static io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall;
+
+/**
+ */
+@javax.annotation.Generated(
+    value = "by gRPC proto compiler (version 1.34.1)",
+    comments = "Source: com/tzld/piaoquan/recommend/server/model.proto")
+public final class ModelServiceGrpc {
+
+  private ModelServiceGrpc() {}
+
+  public static final String SERVICE_NAME = "ModelService";
+
+  // Static method descriptors that strictly reflect the proto.
+  private static volatile io.grpc.MethodDescriptor<com.tzld.piaoquan.recommend.server.gen.model.ScoreRequest,
+      com.tzld.piaoquan.recommend.server.gen.model.ScoreResponse> getScoreMethod;
+
+  @io.grpc.stub.annotations.RpcMethod(
+      fullMethodName = SERVICE_NAME + '/' + "Score",
+      requestType = com.tzld.piaoquan.recommend.server.gen.model.ScoreRequest.class,
+      responseType = com.tzld.piaoquan.recommend.server.gen.model.ScoreResponse.class,
+      methodType = io.grpc.MethodDescriptor.MethodType.UNARY)
+  public static io.grpc.MethodDescriptor<com.tzld.piaoquan.recommend.server.gen.model.ScoreRequest,
+      com.tzld.piaoquan.recommend.server.gen.model.ScoreResponse> getScoreMethod() {
+    io.grpc.MethodDescriptor<com.tzld.piaoquan.recommend.server.gen.model.ScoreRequest, com.tzld.piaoquan.recommend.server.gen.model.ScoreResponse> getScoreMethod;
+    if ((getScoreMethod = ModelServiceGrpc.getScoreMethod) == null) {
+      synchronized (ModelServiceGrpc.class) {
+        if ((getScoreMethod = ModelServiceGrpc.getScoreMethod) == null) {
+          ModelServiceGrpc.getScoreMethod = getScoreMethod =
+              io.grpc.MethodDescriptor.<com.tzld.piaoquan.recommend.server.gen.model.ScoreRequest, com.tzld.piaoquan.recommend.server.gen.model.ScoreResponse>newBuilder()
+              .setType(io.grpc.MethodDescriptor.MethodType.UNARY)
+              .setFullMethodName(generateFullMethodName(SERVICE_NAME, "Score"))
+              .setSampledToLocalTracing(true)
+              .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  com.tzld.piaoquan.recommend.server.gen.model.ScoreRequest.getDefaultInstance()))
+              .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  com.tzld.piaoquan.recommend.server.gen.model.ScoreResponse.getDefaultInstance()))
+              .setSchemaDescriptor(new ModelServiceMethodDescriptorSupplier("Score"))
+              .build();
+        }
+      }
+    }
+    return getScoreMethod;
+  }
+
+  /**
+   * Creates a new async stub that supports all call types for the service
+   */
+  public static ModelServiceStub newStub(io.grpc.Channel channel) {
+    io.grpc.stub.AbstractStub.StubFactory<ModelServiceStub> factory =
+      new io.grpc.stub.AbstractStub.StubFactory<ModelServiceStub>() {
+        @java.lang.Override
+        public ModelServiceStub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
+          return new ModelServiceStub(channel, callOptions);
+        }
+      };
+    return ModelServiceStub.newStub(factory, channel);
+  }
+
+  /**
+   * Creates a new blocking-style stub that supports unary and streaming output calls on the service
+   */
+  public static ModelServiceBlockingStub newBlockingStub(
+      io.grpc.Channel channel) {
+    io.grpc.stub.AbstractStub.StubFactory<ModelServiceBlockingStub> factory =
+      new io.grpc.stub.AbstractStub.StubFactory<ModelServiceBlockingStub>() {
+        @java.lang.Override
+        public ModelServiceBlockingStub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
+          return new ModelServiceBlockingStub(channel, callOptions);
+        }
+      };
+    return ModelServiceBlockingStub.newStub(factory, channel);
+  }
+
+  /**
+   * Creates a new ListenableFuture-style stub that supports unary calls on the service
+   */
+  public static ModelServiceFutureStub newFutureStub(
+      io.grpc.Channel channel) {
+    io.grpc.stub.AbstractStub.StubFactory<ModelServiceFutureStub> factory =
+      new io.grpc.stub.AbstractStub.StubFactory<ModelServiceFutureStub>() {
+        @java.lang.Override
+        public ModelServiceFutureStub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
+          return new ModelServiceFutureStub(channel, callOptions);
+        }
+      };
+    return ModelServiceFutureStub.newStub(factory, channel);
+  }
+
+  /**
+   */
+  public static abstract class ModelServiceImplBase implements io.grpc.BindableService {
+
+    /**
+     */
+    public void score(com.tzld.piaoquan.recommend.server.gen.model.ScoreRequest request,
+        io.grpc.stub.StreamObserver<com.tzld.piaoquan.recommend.server.gen.model.ScoreResponse> responseObserver) {
+      asyncUnimplementedUnaryCall(getScoreMethod(), responseObserver);
+    }
+
+    @java.lang.Override public final io.grpc.ServerServiceDefinition bindService() {
+      return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor())
+          .addMethod(
+            getScoreMethod(),
+            asyncUnaryCall(
+              new MethodHandlers<
+                com.tzld.piaoquan.recommend.server.gen.model.ScoreRequest,
+                com.tzld.piaoquan.recommend.server.gen.model.ScoreResponse>(
+                  this, METHODID_SCORE)))
+          .build();
+    }
+  }
+
+  /**
+   */
+  public static final class ModelServiceStub extends io.grpc.stub.AbstractAsyncStub<ModelServiceStub> {
+    private ModelServiceStub(
+        io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
+      super(channel, callOptions);
+    }
+
+    @java.lang.Override
+    protected ModelServiceStub build(
+        io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
+      return new ModelServiceStub(channel, callOptions);
+    }
+
+    /**
+     */
+    public void score(com.tzld.piaoquan.recommend.server.gen.model.ScoreRequest request,
+        io.grpc.stub.StreamObserver<com.tzld.piaoquan.recommend.server.gen.model.ScoreResponse> responseObserver) {
+      asyncUnaryCall(
+          getChannel().newCall(getScoreMethod(), getCallOptions()), request, responseObserver);
+    }
+  }
+
+  /**
+   */
+  public static final class ModelServiceBlockingStub extends io.grpc.stub.AbstractBlockingStub<ModelServiceBlockingStub> {
+    private ModelServiceBlockingStub(
+        io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
+      super(channel, callOptions);
+    }
+
+    @java.lang.Override
+    protected ModelServiceBlockingStub build(
+        io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
+      return new ModelServiceBlockingStub(channel, callOptions);
+    }
+
+    /**
+     */
+    public com.tzld.piaoquan.recommend.server.gen.model.ScoreResponse score(com.tzld.piaoquan.recommend.server.gen.model.ScoreRequest request) {
+      return blockingUnaryCall(
+          getChannel(), getScoreMethod(), getCallOptions(), request);
+    }
+  }
+
+  /**
+   */
+  public static final class ModelServiceFutureStub extends io.grpc.stub.AbstractFutureStub<ModelServiceFutureStub> {
+    private ModelServiceFutureStub(
+        io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
+      super(channel, callOptions);
+    }
+
+    @java.lang.Override
+    protected ModelServiceFutureStub build(
+        io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
+      return new ModelServiceFutureStub(channel, callOptions);
+    }
+
+    /**
+     */
+    public com.google.common.util.concurrent.ListenableFuture<com.tzld.piaoquan.recommend.server.gen.model.ScoreResponse> score(
+        com.tzld.piaoquan.recommend.server.gen.model.ScoreRequest request) {
+      return futureUnaryCall(
+          getChannel().newCall(getScoreMethod(), getCallOptions()), request);
+    }
+  }
+
+  private static final int METHODID_SCORE = 0;
+
+  private static final class MethodHandlers<Req, Resp> implements
+      io.grpc.stub.ServerCalls.UnaryMethod<Req, Resp>,
+      io.grpc.stub.ServerCalls.ServerStreamingMethod<Req, Resp>,
+      io.grpc.stub.ServerCalls.ClientStreamingMethod<Req, Resp>,
+      io.grpc.stub.ServerCalls.BidiStreamingMethod<Req, Resp> {
+    private final ModelServiceImplBase serviceImpl;
+    private final int methodId;
+
+    MethodHandlers(ModelServiceImplBase serviceImpl, int methodId) {
+      this.serviceImpl = serviceImpl;
+      this.methodId = methodId;
+    }
+
+    @java.lang.Override
+    @java.lang.SuppressWarnings("unchecked")
+    public void invoke(Req request, io.grpc.stub.StreamObserver<Resp> responseObserver) {
+      switch (methodId) {
+        case METHODID_SCORE:
+          serviceImpl.score((com.tzld.piaoquan.recommend.server.gen.model.ScoreRequest) request,
+              (io.grpc.stub.StreamObserver<com.tzld.piaoquan.recommend.server.gen.model.ScoreResponse>) responseObserver);
+          break;
+        default:
+          throw new AssertionError();
+      }
+    }
+
+    @java.lang.Override
+    @java.lang.SuppressWarnings("unchecked")
+    public io.grpc.stub.StreamObserver<Req> invoke(
+        io.grpc.stub.StreamObserver<Resp> responseObserver) {
+      switch (methodId) {
+        default:
+          throw new AssertionError();
+      }
+    }
+  }
+
+  private static abstract class ModelServiceBaseDescriptorSupplier
+      implements io.grpc.protobuf.ProtoFileDescriptorSupplier, io.grpc.protobuf.ProtoServiceDescriptorSupplier {
+    ModelServiceBaseDescriptorSupplier() {}
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.FileDescriptor getFileDescriptor() {
+      return com.tzld.piaoquan.recommend.server.gen.model.Model.getDescriptor();
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.ServiceDescriptor getServiceDescriptor() {
+      return getFileDescriptor().findServiceByName("ModelService");
+    }
+  }
+
+  private static final class ModelServiceFileDescriptorSupplier
+      extends ModelServiceBaseDescriptorSupplier {
+    ModelServiceFileDescriptorSupplier() {}
+  }
+
+  private static final class ModelServiceMethodDescriptorSupplier
+      extends ModelServiceBaseDescriptorSupplier
+      implements io.grpc.protobuf.ProtoMethodDescriptorSupplier {
+    private final String methodName;
+
+    ModelServiceMethodDescriptorSupplier(String methodName) {
+      this.methodName = methodName;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.MethodDescriptor getMethodDescriptor() {
+      return getServiceDescriptor().findMethodByName(methodName);
+    }
+  }
+
+  private static volatile io.grpc.ServiceDescriptor serviceDescriptor;
+
+  public static io.grpc.ServiceDescriptor getServiceDescriptor() {
+    io.grpc.ServiceDescriptor result = serviceDescriptor;
+    if (result == null) {
+      synchronized (ModelServiceGrpc.class) {
+        result = serviceDescriptor;
+        if (result == null) {
+          serviceDescriptor = result = io.grpc.ServiceDescriptor.newBuilder(SERVICE_NAME)
+              .setSchemaDescriptor(new ModelServiceFileDescriptorSupplier())
+              .addMethod(getScoreMethod())
+              .build();
+        }
+      }
+    }
+    return result;
+  }
+}

+ 1036 - 0
recommend-server-client/src/main/java/com/tzld/piaoquan/recommend/server/gen/model/ScoreRequest.java

@@ -0,0 +1,1036 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: com/tzld/piaoquan/recommend/server/model.proto
+
+package com.tzld.piaoquan.recommend.server.gen.model;
+
+/**
+ * Protobuf type {@code ScoreRequest}
+ */
+public final class ScoreRequest extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:ScoreRequest)
+    ScoreRequestOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use ScoreRequest.newBuilder() to construct.
+  private ScoreRequest(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private ScoreRequest() {
+    mid_ = "";
+    uid_ = "";
+    city_ = "";
+    province_ = "";
+  }
+
+  @java.lang.Override
+  @SuppressWarnings({"unused"})
+  protected java.lang.Object newInstance(
+      UnusedPrivateParameter unused) {
+    return new ScoreRequest();
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private ScoreRequest(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          case 8: {
+
+            videoId_ = input.readInt64();
+            break;
+          }
+          case 18: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            mid_ = s;
+            break;
+          }
+          case 26: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            uid_ = s;
+            break;
+          }
+          case 34: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            city_ = s;
+            break;
+          }
+          case 42: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            province_ = s;
+            break;
+          }
+          default: {
+            if (!parseUnknownField(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return com.tzld.piaoquan.recommend.server.gen.model.Model.internal_static_ScoreRequest_descriptor;
+  }
+
+  @java.lang.Override
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return com.tzld.piaoquan.recommend.server.gen.model.Model.internal_static_ScoreRequest_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            com.tzld.piaoquan.recommend.server.gen.model.ScoreRequest.class, com.tzld.piaoquan.recommend.server.gen.model.ScoreRequest.Builder.class);
+  }
+
+  public static final int VIDEO_ID_FIELD_NUMBER = 1;
+  private long videoId_;
+  /**
+   * <code>int64 video_id = 1;</code>
+   * @return The videoId.
+   */
+  @java.lang.Override
+  public long getVideoId() {
+    return videoId_;
+  }
+
+  public static final int MID_FIELD_NUMBER = 2;
+  private volatile java.lang.Object mid_;
+  /**
+   * <code>string mid = 2;</code>
+   * @return The mid.
+   */
+  @java.lang.Override
+  public java.lang.String getMid() {
+    java.lang.Object ref = mid_;
+    if (ref instanceof java.lang.String) {
+      return (java.lang.String) ref;
+    } else {
+      com.google.protobuf.ByteString bs = 
+          (com.google.protobuf.ByteString) ref;
+      java.lang.String s = bs.toStringUtf8();
+      mid_ = s;
+      return s;
+    }
+  }
+  /**
+   * <code>string mid = 2;</code>
+   * @return The bytes for mid.
+   */
+  @java.lang.Override
+  public com.google.protobuf.ByteString
+      getMidBytes() {
+    java.lang.Object ref = mid_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      mid_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  public static final int UID_FIELD_NUMBER = 3;
+  private volatile java.lang.Object uid_;
+  /**
+   * <code>string uid = 3;</code>
+   * @return The uid.
+   */
+  @java.lang.Override
+  public java.lang.String getUid() {
+    java.lang.Object ref = uid_;
+    if (ref instanceof java.lang.String) {
+      return (java.lang.String) ref;
+    } else {
+      com.google.protobuf.ByteString bs = 
+          (com.google.protobuf.ByteString) ref;
+      java.lang.String s = bs.toStringUtf8();
+      uid_ = s;
+      return s;
+    }
+  }
+  /**
+   * <code>string uid = 3;</code>
+   * @return The bytes for uid.
+   */
+  @java.lang.Override
+  public com.google.protobuf.ByteString
+      getUidBytes() {
+    java.lang.Object ref = uid_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      uid_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  public static final int CITY_FIELD_NUMBER = 4;
+  private volatile java.lang.Object city_;
+  /**
+   * <code>string city = 4;</code>
+   * @return The city.
+   */
+  @java.lang.Override
+  public java.lang.String getCity() {
+    java.lang.Object ref = city_;
+    if (ref instanceof java.lang.String) {
+      return (java.lang.String) ref;
+    } else {
+      com.google.protobuf.ByteString bs = 
+          (com.google.protobuf.ByteString) ref;
+      java.lang.String s = bs.toStringUtf8();
+      city_ = s;
+      return s;
+    }
+  }
+  /**
+   * <code>string city = 4;</code>
+   * @return The bytes for city.
+   */
+  @java.lang.Override
+  public com.google.protobuf.ByteString
+      getCityBytes() {
+    java.lang.Object ref = city_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      city_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  public static final int PROVINCE_FIELD_NUMBER = 5;
+  private volatile java.lang.Object province_;
+  /**
+   * <code>string province = 5;</code>
+   * @return The province.
+   */
+  @java.lang.Override
+  public java.lang.String getProvince() {
+    java.lang.Object ref = province_;
+    if (ref instanceof java.lang.String) {
+      return (java.lang.String) ref;
+    } else {
+      com.google.protobuf.ByteString bs = 
+          (com.google.protobuf.ByteString) ref;
+      java.lang.String s = bs.toStringUtf8();
+      province_ = s;
+      return s;
+    }
+  }
+  /**
+   * <code>string province = 5;</code>
+   * @return The bytes for province.
+   */
+  @java.lang.Override
+  public com.google.protobuf.ByteString
+      getProvinceBytes() {
+    java.lang.Object ref = province_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      province_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  private byte memoizedIsInitialized = -1;
+  @java.lang.Override
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  @java.lang.Override
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (videoId_ != 0L) {
+      output.writeInt64(1, videoId_);
+    }
+    if (!getMidBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 2, mid_);
+    }
+    if (!getUidBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 3, uid_);
+    }
+    if (!getCityBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 4, city_);
+    }
+    if (!getProvinceBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 5, province_);
+    }
+    unknownFields.writeTo(output);
+  }
+
+  @java.lang.Override
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (videoId_ != 0L) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeInt64Size(1, videoId_);
+    }
+    if (!getMidBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, mid_);
+    }
+    if (!getUidBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(3, uid_);
+    }
+    if (!getCityBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(4, city_);
+    }
+    if (!getProvinceBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(5, province_);
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof com.tzld.piaoquan.recommend.server.gen.model.ScoreRequest)) {
+      return super.equals(obj);
+    }
+    com.tzld.piaoquan.recommend.server.gen.model.ScoreRequest other = (com.tzld.piaoquan.recommend.server.gen.model.ScoreRequest) obj;
+
+    if (getVideoId()
+        != other.getVideoId()) return false;
+    if (!getMid()
+        .equals(other.getMid())) return false;
+    if (!getUid()
+        .equals(other.getUid())) return false;
+    if (!getCity()
+        .equals(other.getCity())) return false;
+    if (!getProvince()
+        .equals(other.getProvince())) return false;
+    if (!unknownFields.equals(other.unknownFields)) return false;
+    return true;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    hash = (37 * hash) + VIDEO_ID_FIELD_NUMBER;
+    hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
+        getVideoId());
+    hash = (37 * hash) + MID_FIELD_NUMBER;
+    hash = (53 * hash) + getMid().hashCode();
+    hash = (37 * hash) + UID_FIELD_NUMBER;
+    hash = (53 * hash) + getUid().hashCode();
+    hash = (37 * hash) + CITY_FIELD_NUMBER;
+    hash = (53 * hash) + getCity().hashCode();
+    hash = (37 * hash) + PROVINCE_FIELD_NUMBER;
+    hash = (53 * hash) + getProvince().hashCode();
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static com.tzld.piaoquan.recommend.server.gen.model.ScoreRequest parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static com.tzld.piaoquan.recommend.server.gen.model.ScoreRequest parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static com.tzld.piaoquan.recommend.server.gen.model.ScoreRequest parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static com.tzld.piaoquan.recommend.server.gen.model.ScoreRequest parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static com.tzld.piaoquan.recommend.server.gen.model.ScoreRequest parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static com.tzld.piaoquan.recommend.server.gen.model.ScoreRequest parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static com.tzld.piaoquan.recommend.server.gen.model.ScoreRequest parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static com.tzld.piaoquan.recommend.server.gen.model.ScoreRequest parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static com.tzld.piaoquan.recommend.server.gen.model.ScoreRequest parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static com.tzld.piaoquan.recommend.server.gen.model.ScoreRequest parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static com.tzld.piaoquan.recommend.server.gen.model.ScoreRequest parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static com.tzld.piaoquan.recommend.server.gen.model.ScoreRequest parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  @java.lang.Override
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(com.tzld.piaoquan.recommend.server.gen.model.ScoreRequest prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  @java.lang.Override
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * Protobuf type {@code ScoreRequest}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:ScoreRequest)
+      com.tzld.piaoquan.recommend.server.gen.model.ScoreRequestOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return com.tzld.piaoquan.recommend.server.gen.model.Model.internal_static_ScoreRequest_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return com.tzld.piaoquan.recommend.server.gen.model.Model.internal_static_ScoreRequest_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              com.tzld.piaoquan.recommend.server.gen.model.ScoreRequest.class, com.tzld.piaoquan.recommend.server.gen.model.ScoreRequest.Builder.class);
+    }
+
+    // Construct using com.tzld.piaoquan.recommend.server.gen.model.ScoreRequest.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    @java.lang.Override
+    public Builder clear() {
+      super.clear();
+      videoId_ = 0L;
+
+      mid_ = "";
+
+      uid_ = "";
+
+      city_ = "";
+
+      province_ = "";
+
+      return this;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return com.tzld.piaoquan.recommend.server.gen.model.Model.internal_static_ScoreRequest_descriptor;
+    }
+
+    @java.lang.Override
+    public com.tzld.piaoquan.recommend.server.gen.model.ScoreRequest getDefaultInstanceForType() {
+      return com.tzld.piaoquan.recommend.server.gen.model.ScoreRequest.getDefaultInstance();
+    }
+
+    @java.lang.Override
+    public com.tzld.piaoquan.recommend.server.gen.model.ScoreRequest build() {
+      com.tzld.piaoquan.recommend.server.gen.model.ScoreRequest result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    @java.lang.Override
+    public com.tzld.piaoquan.recommend.server.gen.model.ScoreRequest buildPartial() {
+      com.tzld.piaoquan.recommend.server.gen.model.ScoreRequest result = new com.tzld.piaoquan.recommend.server.gen.model.ScoreRequest(this);
+      result.videoId_ = videoId_;
+      result.mid_ = mid_;
+      result.uid_ = uid_;
+      result.city_ = city_;
+      result.province_ = province_;
+      onBuilt();
+      return result;
+    }
+
+    @java.lang.Override
+    public Builder clone() {
+      return super.clone();
+    }
+    @java.lang.Override
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.setField(field, value);
+    }
+    @java.lang.Override
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return super.clearField(field);
+    }
+    @java.lang.Override
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return super.clearOneof(oneof);
+    }
+    @java.lang.Override
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return super.setRepeatedField(field, index, value);
+    }
+    @java.lang.Override
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.addRepeatedField(field, value);
+    }
+    @java.lang.Override
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof com.tzld.piaoquan.recommend.server.gen.model.ScoreRequest) {
+        return mergeFrom((com.tzld.piaoquan.recommend.server.gen.model.ScoreRequest)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(com.tzld.piaoquan.recommend.server.gen.model.ScoreRequest other) {
+      if (other == com.tzld.piaoquan.recommend.server.gen.model.ScoreRequest.getDefaultInstance()) return this;
+      if (other.getVideoId() != 0L) {
+        setVideoId(other.getVideoId());
+      }
+      if (!other.getMid().isEmpty()) {
+        mid_ = other.mid_;
+        onChanged();
+      }
+      if (!other.getUid().isEmpty()) {
+        uid_ = other.uid_;
+        onChanged();
+      }
+      if (!other.getCity().isEmpty()) {
+        city_ = other.city_;
+        onChanged();
+      }
+      if (!other.getProvince().isEmpty()) {
+        province_ = other.province_;
+        onChanged();
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    @java.lang.Override
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    @java.lang.Override
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      com.tzld.piaoquan.recommend.server.gen.model.ScoreRequest parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (com.tzld.piaoquan.recommend.server.gen.model.ScoreRequest) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+
+    private long videoId_ ;
+    /**
+     * <code>int64 video_id = 1;</code>
+     * @return The videoId.
+     */
+    @java.lang.Override
+    public long getVideoId() {
+      return videoId_;
+    }
+    /**
+     * <code>int64 video_id = 1;</code>
+     * @param value The videoId to set.
+     * @return This builder for chaining.
+     */
+    public Builder setVideoId(long value) {
+      
+      videoId_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>int64 video_id = 1;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearVideoId() {
+      
+      videoId_ = 0L;
+      onChanged();
+      return this;
+    }
+
+    private java.lang.Object mid_ = "";
+    /**
+     * <code>string mid = 2;</code>
+     * @return The mid.
+     */
+    public java.lang.String getMid() {
+      java.lang.Object ref = mid_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        mid_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <code>string mid = 2;</code>
+     * @return The bytes for mid.
+     */
+    public com.google.protobuf.ByteString
+        getMidBytes() {
+      java.lang.Object ref = mid_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        mid_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <code>string mid = 2;</code>
+     * @param value The mid to set.
+     * @return This builder for chaining.
+     */
+    public Builder setMid(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      mid_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string mid = 2;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearMid() {
+      
+      mid_ = getDefaultInstance().getMid();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string mid = 2;</code>
+     * @param value The bytes for mid to set.
+     * @return This builder for chaining.
+     */
+    public Builder setMidBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      mid_ = value;
+      onChanged();
+      return this;
+    }
+
+    private java.lang.Object uid_ = "";
+    /**
+     * <code>string uid = 3;</code>
+     * @return The uid.
+     */
+    public java.lang.String getUid() {
+      java.lang.Object ref = uid_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        uid_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <code>string uid = 3;</code>
+     * @return The bytes for uid.
+     */
+    public com.google.protobuf.ByteString
+        getUidBytes() {
+      java.lang.Object ref = uid_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        uid_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <code>string uid = 3;</code>
+     * @param value The uid to set.
+     * @return This builder for chaining.
+     */
+    public Builder setUid(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      uid_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string uid = 3;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearUid() {
+      
+      uid_ = getDefaultInstance().getUid();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string uid = 3;</code>
+     * @param value The bytes for uid to set.
+     * @return This builder for chaining.
+     */
+    public Builder setUidBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      uid_ = value;
+      onChanged();
+      return this;
+    }
+
+    private java.lang.Object city_ = "";
+    /**
+     * <code>string city = 4;</code>
+     * @return The city.
+     */
+    public java.lang.String getCity() {
+      java.lang.Object ref = city_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        city_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <code>string city = 4;</code>
+     * @return The bytes for city.
+     */
+    public com.google.protobuf.ByteString
+        getCityBytes() {
+      java.lang.Object ref = city_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        city_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <code>string city = 4;</code>
+     * @param value The city to set.
+     * @return This builder for chaining.
+     */
+    public Builder setCity(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      city_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string city = 4;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearCity() {
+      
+      city_ = getDefaultInstance().getCity();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string city = 4;</code>
+     * @param value The bytes for city to set.
+     * @return This builder for chaining.
+     */
+    public Builder setCityBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      city_ = value;
+      onChanged();
+      return this;
+    }
+
+    private java.lang.Object province_ = "";
+    /**
+     * <code>string province = 5;</code>
+     * @return The province.
+     */
+    public java.lang.String getProvince() {
+      java.lang.Object ref = province_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        province_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <code>string province = 5;</code>
+     * @return The bytes for province.
+     */
+    public com.google.protobuf.ByteString
+        getProvinceBytes() {
+      java.lang.Object ref = province_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        province_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <code>string province = 5;</code>
+     * @param value The province to set.
+     * @return This builder for chaining.
+     */
+    public Builder setProvince(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      province_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string province = 5;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearProvince() {
+      
+      province_ = getDefaultInstance().getProvince();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string province = 5;</code>
+     * @param value The bytes for province to set.
+     * @return This builder for chaining.
+     */
+    public Builder setProvinceBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      province_ = value;
+      onChanged();
+      return this;
+    }
+    @java.lang.Override
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFields(unknownFields);
+    }
+
+    @java.lang.Override
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:ScoreRequest)
+  }
+
+  // @@protoc_insertion_point(class_scope:ScoreRequest)
+  private static final com.tzld.piaoquan.recommend.server.gen.model.ScoreRequest DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new com.tzld.piaoquan.recommend.server.gen.model.ScoreRequest();
+  }
+
+  public static com.tzld.piaoquan.recommend.server.gen.model.ScoreRequest getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<ScoreRequest>
+      PARSER = new com.google.protobuf.AbstractParser<ScoreRequest>() {
+    @java.lang.Override
+    public ScoreRequest parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new ScoreRequest(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<ScoreRequest> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<ScoreRequest> getParserForType() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.tzld.piaoquan.recommend.server.gen.model.ScoreRequest getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+

+ 63 - 0
recommend-server-client/src/main/java/com/tzld/piaoquan/recommend/server/gen/model/ScoreRequestOrBuilder.java

@@ -0,0 +1,63 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: com/tzld/piaoquan/recommend/server/model.proto
+
+package com.tzld.piaoquan.recommend.server.gen.model;
+
+public interface ScoreRequestOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:ScoreRequest)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>int64 video_id = 1;</code>
+   * @return The videoId.
+   */
+  long getVideoId();
+
+  /**
+   * <code>string mid = 2;</code>
+   * @return The mid.
+   */
+  java.lang.String getMid();
+  /**
+   * <code>string mid = 2;</code>
+   * @return The bytes for mid.
+   */
+  com.google.protobuf.ByteString
+      getMidBytes();
+
+  /**
+   * <code>string uid = 3;</code>
+   * @return The uid.
+   */
+  java.lang.String getUid();
+  /**
+   * <code>string uid = 3;</code>
+   * @return The bytes for uid.
+   */
+  com.google.protobuf.ByteString
+      getUidBytes();
+
+  /**
+   * <code>string city = 4;</code>
+   * @return The city.
+   */
+  java.lang.String getCity();
+  /**
+   * <code>string city = 4;</code>
+   * @return The bytes for city.
+   */
+  com.google.protobuf.ByteString
+      getCityBytes();
+
+  /**
+   * <code>string province = 5;</code>
+   * @return The province.
+   */
+  java.lang.String getProvince();
+  /**
+   * <code>string province = 5;</code>
+   * @return The bytes for province.
+   */
+  com.google.protobuf.ByteString
+      getProvinceBytes();
+}

+ 893 - 0
recommend-server-client/src/main/java/com/tzld/piaoquan/recommend/server/gen/model/ScoreResponse.java

@@ -0,0 +1,893 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: com/tzld/piaoquan/recommend/server/model.proto
+
+package com.tzld.piaoquan.recommend.server.gen.model;
+
+/**
+ * Protobuf type {@code ScoreResponse}
+ */
+public final class ScoreResponse extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:ScoreResponse)
+    ScoreResponseOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use ScoreResponse.newBuilder() to construct.
+  private ScoreResponse(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private ScoreResponse() {
+  }
+
+  @java.lang.Override
+  @SuppressWarnings({"unused"})
+  protected java.lang.Object newInstance(
+      UnusedPrivateParameter unused) {
+    return new ScoreResponse();
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private ScoreResponse(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          case 10: {
+            com.tzld.piaoquan.recommend.server.gen.common.Result.Builder subBuilder = null;
+            if (result_ != null) {
+              subBuilder = result_.toBuilder();
+            }
+            result_ = input.readMessage(com.tzld.piaoquan.recommend.server.gen.common.Result.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom(result_);
+              result_ = subBuilder.buildPartial();
+            }
+
+            break;
+          }
+          case 18: {
+            if (!((mutable_bitField0_ & 0x00000001) != 0)) {
+              score_ = com.google.protobuf.MapField.newMapField(
+                  ScoreDefaultEntryHolder.defaultEntry);
+              mutable_bitField0_ |= 0x00000001;
+            }
+            com.google.protobuf.MapEntry<java.lang.String, java.lang.Double>
+            score__ = input.readMessage(
+                ScoreDefaultEntryHolder.defaultEntry.getParserForType(), extensionRegistry);
+            score_.getMutableMap().put(
+                score__.getKey(), score__.getValue());
+            break;
+          }
+          default: {
+            if (!parseUnknownField(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return com.tzld.piaoquan.recommend.server.gen.model.Model.internal_static_ScoreResponse_descriptor;
+  }
+
+  @SuppressWarnings({"rawtypes"})
+  @java.lang.Override
+  protected com.google.protobuf.MapField internalGetMapField(
+      int number) {
+    switch (number) {
+      case 2:
+        return internalGetScore();
+      default:
+        throw new RuntimeException(
+            "Invalid map field number: " + number);
+    }
+  }
+  @java.lang.Override
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return com.tzld.piaoquan.recommend.server.gen.model.Model.internal_static_ScoreResponse_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            com.tzld.piaoquan.recommend.server.gen.model.ScoreResponse.class, com.tzld.piaoquan.recommend.server.gen.model.ScoreResponse.Builder.class);
+  }
+
+  public static final int RESULT_FIELD_NUMBER = 1;
+  private com.tzld.piaoquan.recommend.server.gen.common.Result result_;
+  /**
+   * <code>.Result result = 1;</code>
+   * @return Whether the result field is set.
+   */
+  @java.lang.Override
+  public boolean hasResult() {
+    return result_ != null;
+  }
+  /**
+   * <code>.Result result = 1;</code>
+   * @return The result.
+   */
+  @java.lang.Override
+  public com.tzld.piaoquan.recommend.server.gen.common.Result getResult() {
+    return result_ == null ? com.tzld.piaoquan.recommend.server.gen.common.Result.getDefaultInstance() : result_;
+  }
+  /**
+   * <code>.Result result = 1;</code>
+   */
+  @java.lang.Override
+  public com.tzld.piaoquan.recommend.server.gen.common.ResultOrBuilder getResultOrBuilder() {
+    return getResult();
+  }
+
+  public static final int SCORE_FIELD_NUMBER = 2;
+  private static final class ScoreDefaultEntryHolder {
+    static final com.google.protobuf.MapEntry<
+        java.lang.String, java.lang.Double> defaultEntry =
+            com.google.protobuf.MapEntry
+            .<java.lang.String, java.lang.Double>newDefaultInstance(
+                com.tzld.piaoquan.recommend.server.gen.model.Model.internal_static_ScoreResponse_ScoreEntry_descriptor, 
+                com.google.protobuf.WireFormat.FieldType.STRING,
+                "",
+                com.google.protobuf.WireFormat.FieldType.DOUBLE,
+                0D);
+  }
+  private com.google.protobuf.MapField<
+      java.lang.String, java.lang.Double> score_;
+  private com.google.protobuf.MapField<java.lang.String, java.lang.Double>
+  internalGetScore() {
+    if (score_ == null) {
+      return com.google.protobuf.MapField.emptyMapField(
+          ScoreDefaultEntryHolder.defaultEntry);
+    }
+    return score_;
+  }
+
+  public int getScoreCount() {
+    return internalGetScore().getMap().size();
+  }
+  /**
+   * <code>map&lt;string, double&gt; score = 2;</code>
+   */
+
+  @java.lang.Override
+  public boolean containsScore(
+      java.lang.String key) {
+    if (key == null) { throw new java.lang.NullPointerException(); }
+    return internalGetScore().getMap().containsKey(key);
+  }
+  /**
+   * Use {@link #getScoreMap()} instead.
+   */
+  @java.lang.Override
+  @java.lang.Deprecated
+  public java.util.Map<java.lang.String, java.lang.Double> getScore() {
+    return getScoreMap();
+  }
+  /**
+   * <code>map&lt;string, double&gt; score = 2;</code>
+   */
+  @java.lang.Override
+
+  public java.util.Map<java.lang.String, java.lang.Double> getScoreMap() {
+    return internalGetScore().getMap();
+  }
+  /**
+   * <code>map&lt;string, double&gt; score = 2;</code>
+   */
+  @java.lang.Override
+
+  public double getScoreOrDefault(
+      java.lang.String key,
+      double defaultValue) {
+    if (key == null) { throw new java.lang.NullPointerException(); }
+    java.util.Map<java.lang.String, java.lang.Double> map =
+        internalGetScore().getMap();
+    return map.containsKey(key) ? map.get(key) : defaultValue;
+  }
+  /**
+   * <code>map&lt;string, double&gt; score = 2;</code>
+   */
+  @java.lang.Override
+
+  public double getScoreOrThrow(
+      java.lang.String key) {
+    if (key == null) { throw new java.lang.NullPointerException(); }
+    java.util.Map<java.lang.String, java.lang.Double> map =
+        internalGetScore().getMap();
+    if (!map.containsKey(key)) {
+      throw new java.lang.IllegalArgumentException();
+    }
+    return map.get(key);
+  }
+
+  private byte memoizedIsInitialized = -1;
+  @java.lang.Override
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  @java.lang.Override
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (result_ != null) {
+      output.writeMessage(1, getResult());
+    }
+    com.google.protobuf.GeneratedMessageV3
+      .serializeStringMapTo(
+        output,
+        internalGetScore(),
+        ScoreDefaultEntryHolder.defaultEntry,
+        2);
+    unknownFields.writeTo(output);
+  }
+
+  @java.lang.Override
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (result_ != null) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(1, getResult());
+    }
+    for (java.util.Map.Entry<java.lang.String, java.lang.Double> entry
+         : internalGetScore().getMap().entrySet()) {
+      com.google.protobuf.MapEntry<java.lang.String, java.lang.Double>
+      score__ = ScoreDefaultEntryHolder.defaultEntry.newBuilderForType()
+          .setKey(entry.getKey())
+          .setValue(entry.getValue())
+          .build();
+      size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(2, score__);
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof com.tzld.piaoquan.recommend.server.gen.model.ScoreResponse)) {
+      return super.equals(obj);
+    }
+    com.tzld.piaoquan.recommend.server.gen.model.ScoreResponse other = (com.tzld.piaoquan.recommend.server.gen.model.ScoreResponse) obj;
+
+    if (hasResult() != other.hasResult()) return false;
+    if (hasResult()) {
+      if (!getResult()
+          .equals(other.getResult())) return false;
+    }
+    if (!internalGetScore().equals(
+        other.internalGetScore())) return false;
+    if (!unknownFields.equals(other.unknownFields)) return false;
+    return true;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    if (hasResult()) {
+      hash = (37 * hash) + RESULT_FIELD_NUMBER;
+      hash = (53 * hash) + getResult().hashCode();
+    }
+    if (!internalGetScore().getMap().isEmpty()) {
+      hash = (37 * hash) + SCORE_FIELD_NUMBER;
+      hash = (53 * hash) + internalGetScore().hashCode();
+    }
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static com.tzld.piaoquan.recommend.server.gen.model.ScoreResponse parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static com.tzld.piaoquan.recommend.server.gen.model.ScoreResponse parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static com.tzld.piaoquan.recommend.server.gen.model.ScoreResponse parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static com.tzld.piaoquan.recommend.server.gen.model.ScoreResponse parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static com.tzld.piaoquan.recommend.server.gen.model.ScoreResponse parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static com.tzld.piaoquan.recommend.server.gen.model.ScoreResponse parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static com.tzld.piaoquan.recommend.server.gen.model.ScoreResponse parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static com.tzld.piaoquan.recommend.server.gen.model.ScoreResponse parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static com.tzld.piaoquan.recommend.server.gen.model.ScoreResponse parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static com.tzld.piaoquan.recommend.server.gen.model.ScoreResponse parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static com.tzld.piaoquan.recommend.server.gen.model.ScoreResponse parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static com.tzld.piaoquan.recommend.server.gen.model.ScoreResponse parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  @java.lang.Override
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(com.tzld.piaoquan.recommend.server.gen.model.ScoreResponse prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  @java.lang.Override
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * Protobuf type {@code ScoreResponse}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:ScoreResponse)
+      com.tzld.piaoquan.recommend.server.gen.model.ScoreResponseOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return com.tzld.piaoquan.recommend.server.gen.model.Model.internal_static_ScoreResponse_descriptor;
+    }
+
+    @SuppressWarnings({"rawtypes"})
+    protected com.google.protobuf.MapField internalGetMapField(
+        int number) {
+      switch (number) {
+        case 2:
+          return internalGetScore();
+        default:
+          throw new RuntimeException(
+              "Invalid map field number: " + number);
+      }
+    }
+    @SuppressWarnings({"rawtypes"})
+    protected com.google.protobuf.MapField internalGetMutableMapField(
+        int number) {
+      switch (number) {
+        case 2:
+          return internalGetMutableScore();
+        default:
+          throw new RuntimeException(
+              "Invalid map field number: " + number);
+      }
+    }
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return com.tzld.piaoquan.recommend.server.gen.model.Model.internal_static_ScoreResponse_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              com.tzld.piaoquan.recommend.server.gen.model.ScoreResponse.class, com.tzld.piaoquan.recommend.server.gen.model.ScoreResponse.Builder.class);
+    }
+
+    // Construct using com.tzld.piaoquan.recommend.server.gen.model.ScoreResponse.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    @java.lang.Override
+    public Builder clear() {
+      super.clear();
+      if (resultBuilder_ == null) {
+        result_ = null;
+      } else {
+        result_ = null;
+        resultBuilder_ = null;
+      }
+      internalGetMutableScore().clear();
+      return this;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return com.tzld.piaoquan.recommend.server.gen.model.Model.internal_static_ScoreResponse_descriptor;
+    }
+
+    @java.lang.Override
+    public com.tzld.piaoquan.recommend.server.gen.model.ScoreResponse getDefaultInstanceForType() {
+      return com.tzld.piaoquan.recommend.server.gen.model.ScoreResponse.getDefaultInstance();
+    }
+
+    @java.lang.Override
+    public com.tzld.piaoquan.recommend.server.gen.model.ScoreResponse build() {
+      com.tzld.piaoquan.recommend.server.gen.model.ScoreResponse result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    @java.lang.Override
+    public com.tzld.piaoquan.recommend.server.gen.model.ScoreResponse buildPartial() {
+      com.tzld.piaoquan.recommend.server.gen.model.ScoreResponse result = new com.tzld.piaoquan.recommend.server.gen.model.ScoreResponse(this);
+      int from_bitField0_ = bitField0_;
+      if (resultBuilder_ == null) {
+        result.result_ = result_;
+      } else {
+        result.result_ = resultBuilder_.build();
+      }
+      result.score_ = internalGetScore();
+      result.score_.makeImmutable();
+      onBuilt();
+      return result;
+    }
+
+    @java.lang.Override
+    public Builder clone() {
+      return super.clone();
+    }
+    @java.lang.Override
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.setField(field, value);
+    }
+    @java.lang.Override
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return super.clearField(field);
+    }
+    @java.lang.Override
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return super.clearOneof(oneof);
+    }
+    @java.lang.Override
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return super.setRepeatedField(field, index, value);
+    }
+    @java.lang.Override
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.addRepeatedField(field, value);
+    }
+    @java.lang.Override
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof com.tzld.piaoquan.recommend.server.gen.model.ScoreResponse) {
+        return mergeFrom((com.tzld.piaoquan.recommend.server.gen.model.ScoreResponse)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(com.tzld.piaoquan.recommend.server.gen.model.ScoreResponse other) {
+      if (other == com.tzld.piaoquan.recommend.server.gen.model.ScoreResponse.getDefaultInstance()) return this;
+      if (other.hasResult()) {
+        mergeResult(other.getResult());
+      }
+      internalGetMutableScore().mergeFrom(
+          other.internalGetScore());
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    @java.lang.Override
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    @java.lang.Override
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      com.tzld.piaoquan.recommend.server.gen.model.ScoreResponse parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (com.tzld.piaoquan.recommend.server.gen.model.ScoreResponse) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+    private int bitField0_;
+
+    private com.tzld.piaoquan.recommend.server.gen.common.Result result_;
+    private com.google.protobuf.SingleFieldBuilderV3<
+        com.tzld.piaoquan.recommend.server.gen.common.Result, com.tzld.piaoquan.recommend.server.gen.common.Result.Builder, com.tzld.piaoquan.recommend.server.gen.common.ResultOrBuilder> resultBuilder_;
+    /**
+     * <code>.Result result = 1;</code>
+     * @return Whether the result field is set.
+     */
+    public boolean hasResult() {
+      return resultBuilder_ != null || result_ != null;
+    }
+    /**
+     * <code>.Result result = 1;</code>
+     * @return The result.
+     */
+    public com.tzld.piaoquan.recommend.server.gen.common.Result getResult() {
+      if (resultBuilder_ == null) {
+        return result_ == null ? com.tzld.piaoquan.recommend.server.gen.common.Result.getDefaultInstance() : result_;
+      } else {
+        return resultBuilder_.getMessage();
+      }
+    }
+    /**
+     * <code>.Result result = 1;</code>
+     */
+    public Builder setResult(com.tzld.piaoquan.recommend.server.gen.common.Result value) {
+      if (resultBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        result_ = value;
+        onChanged();
+      } else {
+        resultBuilder_.setMessage(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.Result result = 1;</code>
+     */
+    public Builder setResult(
+        com.tzld.piaoquan.recommend.server.gen.common.Result.Builder builderForValue) {
+      if (resultBuilder_ == null) {
+        result_ = builderForValue.build();
+        onChanged();
+      } else {
+        resultBuilder_.setMessage(builderForValue.build());
+      }
+
+      return this;
+    }
+    /**
+     * <code>.Result result = 1;</code>
+     */
+    public Builder mergeResult(com.tzld.piaoquan.recommend.server.gen.common.Result value) {
+      if (resultBuilder_ == null) {
+        if (result_ != null) {
+          result_ =
+            com.tzld.piaoquan.recommend.server.gen.common.Result.newBuilder(result_).mergeFrom(value).buildPartial();
+        } else {
+          result_ = value;
+        }
+        onChanged();
+      } else {
+        resultBuilder_.mergeFrom(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.Result result = 1;</code>
+     */
+    public Builder clearResult() {
+      if (resultBuilder_ == null) {
+        result_ = null;
+        onChanged();
+      } else {
+        result_ = null;
+        resultBuilder_ = null;
+      }
+
+      return this;
+    }
+    /**
+     * <code>.Result result = 1;</code>
+     */
+    public com.tzld.piaoquan.recommend.server.gen.common.Result.Builder getResultBuilder() {
+      
+      onChanged();
+      return getResultFieldBuilder().getBuilder();
+    }
+    /**
+     * <code>.Result result = 1;</code>
+     */
+    public com.tzld.piaoquan.recommend.server.gen.common.ResultOrBuilder getResultOrBuilder() {
+      if (resultBuilder_ != null) {
+        return resultBuilder_.getMessageOrBuilder();
+      } else {
+        return result_ == null ?
+            com.tzld.piaoquan.recommend.server.gen.common.Result.getDefaultInstance() : result_;
+      }
+    }
+    /**
+     * <code>.Result result = 1;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        com.tzld.piaoquan.recommend.server.gen.common.Result, com.tzld.piaoquan.recommend.server.gen.common.Result.Builder, com.tzld.piaoquan.recommend.server.gen.common.ResultOrBuilder> 
+        getResultFieldBuilder() {
+      if (resultBuilder_ == null) {
+        resultBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            com.tzld.piaoquan.recommend.server.gen.common.Result, com.tzld.piaoquan.recommend.server.gen.common.Result.Builder, com.tzld.piaoquan.recommend.server.gen.common.ResultOrBuilder>(
+                getResult(),
+                getParentForChildren(),
+                isClean());
+        result_ = null;
+      }
+      return resultBuilder_;
+    }
+
+    private com.google.protobuf.MapField<
+        java.lang.String, java.lang.Double> score_;
+    private com.google.protobuf.MapField<java.lang.String, java.lang.Double>
+    internalGetScore() {
+      if (score_ == null) {
+        return com.google.protobuf.MapField.emptyMapField(
+            ScoreDefaultEntryHolder.defaultEntry);
+      }
+      return score_;
+    }
+    private com.google.protobuf.MapField<java.lang.String, java.lang.Double>
+    internalGetMutableScore() {
+      onChanged();;
+      if (score_ == null) {
+        score_ = com.google.protobuf.MapField.newMapField(
+            ScoreDefaultEntryHolder.defaultEntry);
+      }
+      if (!score_.isMutable()) {
+        score_ = score_.copy();
+      }
+      return score_;
+    }
+
+    public int getScoreCount() {
+      return internalGetScore().getMap().size();
+    }
+    /**
+     * <code>map&lt;string, double&gt; score = 2;</code>
+     */
+
+    @java.lang.Override
+    public boolean containsScore(
+        java.lang.String key) {
+      if (key == null) { throw new java.lang.NullPointerException(); }
+      return internalGetScore().getMap().containsKey(key);
+    }
+    /**
+     * Use {@link #getScoreMap()} instead.
+     */
+    @java.lang.Override
+    @java.lang.Deprecated
+    public java.util.Map<java.lang.String, java.lang.Double> getScore() {
+      return getScoreMap();
+    }
+    /**
+     * <code>map&lt;string, double&gt; score = 2;</code>
+     */
+    @java.lang.Override
+
+    public java.util.Map<java.lang.String, java.lang.Double> getScoreMap() {
+      return internalGetScore().getMap();
+    }
+    /**
+     * <code>map&lt;string, double&gt; score = 2;</code>
+     */
+    @java.lang.Override
+
+    public double getScoreOrDefault(
+        java.lang.String key,
+        double defaultValue) {
+      if (key == null) { throw new java.lang.NullPointerException(); }
+      java.util.Map<java.lang.String, java.lang.Double> map =
+          internalGetScore().getMap();
+      return map.containsKey(key) ? map.get(key) : defaultValue;
+    }
+    /**
+     * <code>map&lt;string, double&gt; score = 2;</code>
+     */
+    @java.lang.Override
+
+    public double getScoreOrThrow(
+        java.lang.String key) {
+      if (key == null) { throw new java.lang.NullPointerException(); }
+      java.util.Map<java.lang.String, java.lang.Double> map =
+          internalGetScore().getMap();
+      if (!map.containsKey(key)) {
+        throw new java.lang.IllegalArgumentException();
+      }
+      return map.get(key);
+    }
+
+    public Builder clearScore() {
+      internalGetMutableScore().getMutableMap()
+          .clear();
+      return this;
+    }
+    /**
+     * <code>map&lt;string, double&gt; score = 2;</code>
+     */
+
+    public Builder removeScore(
+        java.lang.String key) {
+      if (key == null) { throw new java.lang.NullPointerException(); }
+      internalGetMutableScore().getMutableMap()
+          .remove(key);
+      return this;
+    }
+    /**
+     * Use alternate mutation accessors instead.
+     */
+    @java.lang.Deprecated
+    public java.util.Map<java.lang.String, java.lang.Double>
+    getMutableScore() {
+      return internalGetMutableScore().getMutableMap();
+    }
+    /**
+     * <code>map&lt;string, double&gt; score = 2;</code>
+     */
+    public Builder putScore(
+        java.lang.String key,
+        double value) {
+      if (key == null) { throw new java.lang.NullPointerException(); }
+      
+      internalGetMutableScore().getMutableMap()
+          .put(key, value);
+      return this;
+    }
+    /**
+     * <code>map&lt;string, double&gt; score = 2;</code>
+     */
+
+    public Builder putAllScore(
+        java.util.Map<java.lang.String, java.lang.Double> values) {
+      internalGetMutableScore().getMutableMap()
+          .putAll(values);
+      return this;
+    }
+    @java.lang.Override
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFields(unknownFields);
+    }
+
+    @java.lang.Override
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:ScoreResponse)
+  }
+
+  // @@protoc_insertion_point(class_scope:ScoreResponse)
+  private static final com.tzld.piaoquan.recommend.server.gen.model.ScoreResponse DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new com.tzld.piaoquan.recommend.server.gen.model.ScoreResponse();
+  }
+
+  public static com.tzld.piaoquan.recommend.server.gen.model.ScoreResponse getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<ScoreResponse>
+      PARSER = new com.google.protobuf.AbstractParser<ScoreResponse>() {
+    @java.lang.Override
+    public ScoreResponse parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new ScoreResponse(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<ScoreResponse> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<ScoreResponse> getParserForType() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.tzld.piaoquan.recommend.server.gen.model.ScoreResponse getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+

+ 58 - 0
recommend-server-client/src/main/java/com/tzld/piaoquan/recommend/server/gen/model/ScoreResponseOrBuilder.java

@@ -0,0 +1,58 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: com/tzld/piaoquan/recommend/server/model.proto
+
+package com.tzld.piaoquan.recommend.server.gen.model;
+
+public interface ScoreResponseOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:ScoreResponse)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>.Result result = 1;</code>
+   * @return Whether the result field is set.
+   */
+  boolean hasResult();
+  /**
+   * <code>.Result result = 1;</code>
+   * @return The result.
+   */
+  com.tzld.piaoquan.recommend.server.gen.common.Result getResult();
+  /**
+   * <code>.Result result = 1;</code>
+   */
+  com.tzld.piaoquan.recommend.server.gen.common.ResultOrBuilder getResultOrBuilder();
+
+  /**
+   * <code>map&lt;string, double&gt; score = 2;</code>
+   */
+  int getScoreCount();
+  /**
+   * <code>map&lt;string, double&gt; score = 2;</code>
+   */
+  boolean containsScore(
+      java.lang.String key);
+  /**
+   * Use {@link #getScoreMap()} instead.
+   */
+  @java.lang.Deprecated
+  java.util.Map<java.lang.String, java.lang.Double>
+  getScore();
+  /**
+   * <code>map&lt;string, double&gt; score = 2;</code>
+   */
+  java.util.Map<java.lang.String, java.lang.Double>
+  getScoreMap();
+  /**
+   * <code>map&lt;string, double&gt; score = 2;</code>
+   */
+
+  double getScoreOrDefault(
+      java.lang.String key,
+      double defaultValue);
+  /**
+   * <code>map&lt;string, double&gt; score = 2;</code>
+   */
+
+  double getScoreOrThrow(
+      java.lang.String key);
+}

+ 24 - 0
recommend-server-client/src/main/proto/com/tzld/piaoquan/recommend/server/model.proto

@@ -0,0 +1,24 @@
+syntax = "proto3";
+
+import "com/tzld/piaoquan/recommend/server/common.proto";
+
+option java_multiple_files = true;
+option java_package = "com.tzld.piaoquan.recommend.server.gen.model";
+option java_generic_services = true;
+
+message ScoreRequest {
+  int64 video_id = 1;
+  string mid = 2;
+  string uid = 3;
+  string city = 4;
+  string province = 5;
+}
+
+message ScoreResponse {
+  Result result = 1;
+  map<string, double> score = 2;
+}
+
+service ModelService {
+  rpc Score (ScoreRequest) returns (ScoreResponse);
+}

+ 4 - 1
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/Application.java

@@ -5,6 +5,7 @@ package com.tzld.piaoquan.recommend.server;
 import com.tzld.piaoquan.recommend.feature.client.FeatureClient;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.data.redis.RedisReactiveAutoConfiguration;
 import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.ComponentScan;
@@ -15,7 +16,9 @@ import org.springframework.http.converter.protobuf.ProtobufHttpMessageConverter;
 /**
  * https://github.com/grpc-swagger/grpc-swagger/blob/master/README_CN.md
  */
-@SpringBootApplication
+@SpringBootApplication(exclude = {
+        RedisReactiveAutoConfiguration.class
+})
 @ComponentScan({
         "com.tzld.piaoquan.recommend.server.service",
         "com.tzld.piaoquan.recommend.server.grpcservice",

+ 5 - 0
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/common/base/RankItem.java

@@ -30,6 +30,11 @@ public class RankItem implements Comparable<RankItem> {
         this.video = video;
     }
 
+    public RankItem(Long videoId) {
+        this.videoId = videoId;
+        this.score = 0.0;
+    }
+
     private Map<String, Double> rankerScore = new HashMap<>();
     private Map<String, Integer> rankerIndex = new HashMap<>();
 

+ 57 - 0
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/config/FeatureRedisTemplateConfig.java

@@ -0,0 +1,57 @@
+package com.tzld.piaoquan.recommend.server.config;
+
+import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Primary;
+import org.springframework.data.redis.connection.RedisConnectionFactory;
+import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
+import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration;
+import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
+import org.springframework.data.redis.connection.lettuce.LettucePoolingClientConfiguration;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.serializer.StringRedisSerializer;
+
+@Configuration
+public class FeatureRedisTemplateConfig {
+
+    @Bean("featureRedisPool")
+    @ConfigurationProperties(prefix = "spring.feature-redis.lettuce.pool")
+    public GenericObjectPoolConfig<LettucePoolingClientConfiguration> featureRedisPool() {
+        return new GenericObjectPoolConfig<>();
+    }
+
+    @Bean("featureRedisConfig")
+    @ConfigurationProperties(prefix = "spring.feature-redis")
+    public RedisStandaloneConfiguration featureRedisConfig() {
+        return new RedisStandaloneConfiguration();
+    }
+
+    @Bean("featureRedisFactory")
+    @Primary
+    public LettuceConnectionFactory factory(@Qualifier("featureRedisPool") GenericObjectPoolConfig<LettucePoolingClientConfiguration> tairPool,
+                                            @Qualifier("featureRedisConfig") RedisStandaloneConfiguration tairConfig) {
+        LettuceClientConfiguration lettuceClientConfiguration =
+                LettucePoolingClientConfiguration.builder().poolConfig(tairPool).build();
+        return new LettuceConnectionFactory(tairConfig, lettuceClientConfiguration);
+    }
+
+    @Bean(name = "featureRedisTemplate")
+    public RedisTemplate<String, String> getFeatureRedisTemplate(@Qualifier("featureRedisFactory") RedisConnectionFactory factory) {
+        return buildFeatureRedisTemplateByString(factory);
+    }
+
+    private RedisTemplate<String, String> buildFeatureRedisTemplateByString(RedisConnectionFactory factory) {
+        RedisTemplate<String, String> redisTemplate = new RedisTemplate<>();
+        redisTemplate.setConnectionFactory(factory);
+        // key的序列化类型 保证可读性
+        redisTemplate.setKeySerializer(new StringRedisSerializer());
+        redisTemplate.setValueSerializer(new StringRedisSerializer());
+        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
+        redisTemplate.setHashValueSerializer(new StringRedisSerializer());
+        return redisTemplate;
+    }
+
+}

+ 7 - 11
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/config/RedisTemplateConfig.java

@@ -14,36 +14,32 @@ import org.springframework.data.redis.connection.lettuce.LettucePoolingClientCon
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.data.redis.serializer.StringRedisSerializer;
 
-/**
- * @author supeng
- * @date 2020/11/10
- */
 @Configuration
 public class RedisTemplateConfig {
 
-    @Bean
+    @Bean("redisPool")
     @ConfigurationProperties(prefix = "spring.redis.lettuce.pool")
     public GenericObjectPoolConfig<LettucePoolingClientConfiguration> redisPool() {
         return new GenericObjectPoolConfig<>();
     }
 
-    @Bean
+    @Bean("redisConfig")
     @ConfigurationProperties(prefix = "spring.redis")
-    public RedisStandaloneConfiguration redisConfig() {
+    public RedisStandaloneConfiguration tairConfig() {
         return new RedisStandaloneConfiguration();
     }
 
-    @Bean("factory")
+    @Bean("redisFactory")
     @Primary
-    public LettuceConnectionFactory factory(GenericObjectPoolConfig<LettucePoolingClientConfiguration> config,
+    public LettuceConnectionFactory factory(GenericObjectPoolConfig<LettucePoolingClientConfiguration> redisPool,
                                             RedisStandaloneConfiguration redisConfig) {
         LettuceClientConfiguration lettuceClientConfiguration =
-                LettucePoolingClientConfiguration.builder().poolConfig(config).build();
+                LettucePoolingClientConfiguration.builder().poolConfig(redisPool).build();
         return new LettuceConnectionFactory(redisConfig, lettuceClientConfiguration);
     }
 
     @Bean(name = "redisTemplate")
-    public RedisTemplate<String, String> getRedisTemplate(@Qualifier("factory") RedisConnectionFactory factory) {
+    public RedisTemplate<String, String> getRedisTemplate(@Qualifier("redisFactory") RedisConnectionFactory factory) {
         return buildRedisTemplateByString(factory);
     }
 

+ 30 - 0
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/grpcservice/GrpcAspect.java

@@ -0,0 +1,30 @@
+package com.tzld.piaoquan.recommend.server.grpcservice;
+
+import com.tzld.piaoquan.recommend.server.util.TraceUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.springframework.stereotype.Component;
+
+/**
+ * @author dyp
+ */
+@Aspect
+@Component
+@Slf4j
+public class GrpcAspect {
+
+    @Around("execution(* com.tzld.piaoquan.recommend.server.grpcservice.*GrpcService.*(..))")
+    public Object around(ProceedingJoinPoint pjp) throws Throwable {
+        TraceUtils.setMDC();
+//
+//        String className = pjp.getTarget().getClass().getSimpleName();
+//        MethodSignature signature = (MethodSignature) pjp.getSignature();
+//        Stopwatch stopwatch = Stopwatch.createStarted();
+        Object result = pjp.proceed();
+
+        TraceUtils.removeMDC();
+        return result;
+    }
+}

+ 32 - 0
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/grpcservice/ModelGrpcService.java

@@ -0,0 +1,32 @@
+package com.tzld.piaoquan.recommend.server.grpcservice;
+
+import com.tzld.piaoquan.recommend.feature.client.ProtobufUtils;
+import com.tzld.piaoquan.recommend.server.gen.model.ModelServiceGrpc;
+import com.tzld.piaoquan.recommend.server.gen.model.ScoreRequest;
+import com.tzld.piaoquan.recommend.server.gen.model.ScoreResponse;
+import com.tzld.piaoquan.recommend.server.service.ModelService;
+import io.grpc.stub.StreamObserver;
+import lombok.extern.slf4j.Slf4j;
+import net.devh.boot.grpc.server.service.GrpcService;
+import org.springframework.beans.factory.annotation.Autowired;
+
+/**
+ * @author dyp
+ */
+@GrpcService
+@Slf4j
+public class ModelGrpcService extends ModelServiceGrpc.ModelServiceImplBase {
+    @Autowired
+    private ModelService modelService;
+
+    @Override
+    public void score(ScoreRequest request, StreamObserver<ScoreResponse> responseObserver) {
+        log.info("ModelGrpcService score request={}", ProtobufUtils.toJson(request));
+        ScoreResponse response = modelService.score(request);
+        log.info("ModelGrpcService score response={}", ProtobufUtils.toJson(response));
+
+        responseObserver.onNext(response);
+        responseObserver.onCompleted();
+    }
+
+}

+ 185 - 0
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/ModelService.java

@@ -0,0 +1,185 @@
+package com.tzld.piaoquan.recommend.server.service;
+
+import com.google.common.collect.Lists;
+import com.google.common.reflect.TypeToken;
+import com.tzld.piaoquan.recommend.server.client.ModelType;
+import com.tzld.piaoquan.recommend.server.common.base.RankItem;
+import com.tzld.piaoquan.recommend.server.gen.common.Result;
+import com.tzld.piaoquan.recommend.server.gen.model.ScoreRequest;
+import com.tzld.piaoquan.recommend.server.gen.model.ScoreResponse;
+import com.tzld.piaoquan.recommend.server.service.score.ScorerUtils;
+import com.tzld.piaoquan.recommend.server.util.JSONUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.CollectionUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.PostConstruct;
+import java.text.SimpleDateFormat;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * @author dyp
+ */
+@Service
+@Slf4j
+public class ModelService {
+
+    @Qualifier("featureRedisTemplate")
+    @Autowired
+    private RedisTemplate<String, String> featureRedisTemplate;
+
+    private Map<String, String> modelNameMap = new HashMap<>();
+
+    @PostConstruct
+    public void init() {
+        modelNameMap.put("VlogShareLRScorer", ModelType.STR.getKey());
+    }
+
+    /**
+     * workaround 广告调用返回分数
+     * <p>
+     * 因为是重复代码,尽量保持不变
+     */
+    public ScoreResponse score(ScoreRequest request) {
+
+        Map<String, String> userFeatureMap = new HashMap<>();
+        if (request.getMid() != null && !request.getMid().isEmpty()) {
+            String midKey = "user_info_4video_" + request.getMid();
+            String userFeatureStr = featureRedisTemplate.opsForValue().get(midKey);
+            if (userFeatureStr != null) {
+                try {
+                    userFeatureMap = JSONUtils.fromJson(userFeatureStr,
+                            new TypeToken<Map<String, String>>() {
+                            },
+                            userFeatureMap);
+                } catch (Exception e) {
+                    log.error(String.format("parse user json is wrong in {} with {}",
+                            this.getClass().getSimpleName(), e));
+                }
+            } else {
+                userFeatureMap = new HashMap<>();
+//                return ScoreResponse.newBuilder()
+//                        .setResult(Result.newBuilder().setCode(1))
+//                        .build();
+            }
+        }
+        final Set<String> userFeatureSet = new HashSet<>(Arrays.asList(
+                "machineinfo_brand", "machineinfo_model", "machineinfo_platform", "machineinfo_system",
+                "u_1day_exp_cnt", "u_1day_click_cnt", "u_1day_share_cnt", "u_1day_return_cnt",
+                "u_ctr_1day", "u_str_1day", "u_rov_1day", "u_ros_1day",
+                "u_3day_exp_cnt", "u_3day_click_cnt", "u_3day_share_cnt", "u_3day_return_cnt",
+                "u_ctr_3day", "u_str_3day", "u_rov_3day", "u_ros_3day"
+        ));
+        Iterator<Map.Entry<String, String>> iterator = userFeatureMap.entrySet().iterator();
+        while (iterator.hasNext()) {
+            Map.Entry<String, String> entry = iterator.next();
+            if (!userFeatureSet.contains(entry.getKey())) {
+                // 删除键值对
+                iterator.remove();
+            }
+        }
+
+        log.info("userFeature in model = {}", JSONUtils.toJson(userFeatureMap));
+
+        final Set<String> itemFeatureSet = new HashSet<>(Arrays.asList(
+                "total_time", "play_count_total",
+                "i_1day_exp_cnt", "i_1day_click_cnt", "i_1day_share_cnt", "i_1day_return_cnt",
+                "i_ctr_1day", "i_str_1day", "i_rov_1day", "i_ros_1day",
+                "i_3day_exp_cnt", "i_3day_click_cnt", "i_3day_share_cnt", "i_3day_return_cnt",
+                "i_ctr_3day", "i_str_3day", "i_rov_3day", "i_ros_3day"
+        ));
+
+        List<RankItem> rankItems = Lists.newArrayList(new RankItem(request.getVideoId()));
+        List<Long> videoIds = Lists.newArrayList(request.getVideoId());
+        List<String> videoFeatureKeys = videoIds.stream().map(r -> "video_info_" + r)
+                .collect(Collectors.toList());
+        List<String> videoFeatures = featureRedisTemplate.opsForValue().multiGet(videoFeatureKeys);
+        if (videoFeatures != null) {
+            for (int i = 0; i < videoFeatures.size(); ++i) {
+                String vF = videoFeatures.get(i);
+                Map<String, String> vfMap = new HashMap<>();
+                if (vF == null) {
+                    continue;
+                }
+                try {
+                    vfMap = JSONUtils.fromJson(vF, new TypeToken<Map<String, String>>() {
+                    }, vfMap);
+                    Iterator<Map.Entry<String, String>> iteratorIn = vfMap.entrySet().iterator();
+                    while (iteratorIn.hasNext()) {
+                        Map.Entry<String, String> entry = iteratorIn.next();
+                        if (!itemFeatureSet.contains(entry.getKey())) {
+                            // 删除键值对
+                            iteratorIn.remove();
+                        }
+                    }
+                    rankItems.get(i).setFeatureMap(vfMap);
+                } catch (Exception e) {
+                    log.error(String.format("parse video json is wrong in {} with {}",
+                            this.getClass().getSimpleName(), e));
+                }
+            }
+        }
+        log.info("ItemFeature = {}", JSONUtils.toJson(videoFeatures));
+
+        Map<String, String> sceneFeatureMap = this.getSceneFeature(request);
+
+        List<RankItem> result = ScorerUtils.getScorerPipeline(ScorerUtils.VIDEO_SCORE_CONF_FOR_AD)
+                .scoring(sceneFeatureMap, userFeatureMap, rankItems);
+
+        if (CollectionUtils.isEmpty(result)) {
+            return ScoreResponse.newBuilder()
+                    .setResult(Result.newBuilder().setCode(1))
+                    .build();
+        }
+        Map<String, Double> score = new HashMap<>();
+        score.put(ModelType.STR.getKey(), result.get(0).getScoreStr());
+        score.put(ModelType.ROS.getKey(), result.get(0).getScoreRos());
+
+        return ScoreResponse.newBuilder()
+                .setResult(Result.newBuilder().setCode(1))
+                .putAllScore(score)
+                .build();
+//        return ScoreResponse.newBuilder()
+//                .setResult(Result.newBuilder().setCode(1))
+//                .putAllScore(CommonCollectionUtils.toMap(result.get(0).getRankerScore().entrySet(),
+//                        e -> modelNameMap.containsKey(e.getKey())
+//                                ? modelNameMap.get(e.getKey())
+//                                : e.getKey(),
+//                        e -> e.getValue()))
+//                .build();
+    }
+
+    private Map<String, String> getSceneFeature(ScoreRequest request) {
+        Map<String, String> sceneFeatureMap = new HashMap<>();
+        String provinceCn = request.getProvince();
+        provinceCn = provinceCn.replaceAll("省$", "");
+        sceneFeatureMap.put("ctx_region", provinceCn);
+        String city = request.getCity();
+        if ("台北市".equals(city) |
+                "高雄市".equals(city) |
+                "台中市".equals(city) |
+                "桃园市".equals(city) |
+                "新北市".equals(city) |
+                "台南市".equals(city) |
+                "基隆市".equals(city) |
+                "吉林市".equals(city) |
+                "新竹市".equals(city) |
+                "嘉义市".equals(city)
+        ) {
+            ;
+        } else {
+            city = city.replaceAll("市$", "");
+        }
+        sceneFeatureMap.put("ctx_city", city);
+
+        Calendar calendar = Calendar.getInstance();
+        sceneFeatureMap.put("ctx_week", (calendar.get(Calendar.DAY_OF_WEEK) + 6) % 7 + "");
+        sceneFeatureMap.put("ctx_hour", new SimpleDateFormat("HH").format(calendar.getTime()));
+
+        return sceneFeatureMap;
+    }
+}

+ 2 - 0
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/PreViewedService.java

@@ -6,6 +6,7 @@ import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.math.NumberUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.data.redis.core.Cursor;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.data.redis.core.ScanOptions;
@@ -25,6 +26,7 @@ import java.util.concurrent.TimeUnit;
 @Slf4j
 public class PreViewedService {
     @Autowired
+    @Qualifier("redisTemplate")
     private RedisTemplate<String, String> redisTemplate;
 
     public static final String KEY_PRE_VIEWED_FORMAT = "previewed:videos:%s:%s";

+ 2 - 0
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/RecommendService.java

@@ -30,6 +30,7 @@ import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.lang3.RandomUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.stereotype.Service;
 
@@ -47,6 +48,7 @@ import java.util.stream.Collectors;
 public class RecommendService {
 
     @Autowired
+    @Qualifier("redisTemplate")
     private RedisTemplate<String, String> redisTemplate;
 
 

+ 3 - 0
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/WarmUpService.java

@@ -2,6 +2,7 @@ package com.tzld.piaoquan.recommend.server.service;
 
 import com.tzld.piaoquan.recommend.server.service.score.ScorerUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.core.annotation.Order;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.stereotype.Component;
@@ -15,7 +16,9 @@ import javax.annotation.PostConstruct;
 @Order(1)
 public class WarmUpService {
     @Autowired
+    @Qualifier("redisTemplate")
     private RedisTemplate<String, String> redisTemplate;
+    
 
     @PostConstruct
     public void warmup() {

+ 2 - 0
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/flowpool/FlowPoolConfigService.java

@@ -8,6 +8,7 @@ import com.tzld.piaoquan.recommend.server.util.JSONUtils;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.stereotype.Service;
 
@@ -24,6 +25,7 @@ import java.util.concurrent.TimeUnit;
 @Slf4j
 public class FlowPoolConfigService {
     @Autowired
+    @Qualifier("redisTemplate")
     private RedisTemplate<String, String> redisTemplate;
 
     // TODO 这些配置可以用配置中心么?

+ 2 - 0
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/flowpool/FlowPoolService.java

@@ -9,6 +9,7 @@ import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.MapUtils;
 import org.apache.commons.lang3.math.NumberUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.stereotype.Service;
 
@@ -26,6 +27,7 @@ import static com.tzld.piaoquan.recommend.server.service.flowpool.FlowPoolConsta
 @Slf4j
 public class FlowPoolService {
     @Autowired
+    @Qualifier("redisTemplate")
     private RedisTemplate<String, String> redisTemplate;
     @Autowired
     private FlowPoolConfigService flowPoolConfigService;

+ 2 - 0
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/rank/RankService.java

@@ -21,6 +21,7 @@ import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.lang3.RandomUtils;
 import org.apache.commons.lang3.math.NumberUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.stereotype.Service;
@@ -36,6 +37,7 @@ import java.util.stream.Collectors;
 @Slf4j
 public class RankService {
     @Autowired
+    @Qualifier("redisTemplate")
     public RedisTemplate<String, String> redisTemplate;
     @Autowired
     private FeatureRemoteService featureRemoteService;

+ 2 - 0
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/AbstractFlowPoolWithLevelRecallStrategy.java

@@ -13,6 +13,7 @@ import org.apache.commons.lang3.RandomUtils;
 import org.apache.commons.lang3.math.NumberUtils;
 import org.apache.commons.lang3.tuple.Pair;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.data.redis.core.RedisTemplate;
 
 import java.util.ArrayList;
@@ -26,6 +27,7 @@ import java.util.Map;
 @Slf4j
 public abstract class AbstractFlowPoolWithLevelRecallStrategy implements RecallStrategy {
     @Autowired
+    @Qualifier("redisTemplate")
     protected RedisTemplate<String, String> redisTemplate;
 
     @Autowired

+ 2 - 0
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/AbstractFlowPoolWithLevelScoreRecallStrategy.java

@@ -12,6 +12,7 @@ import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.lang3.math.NumberUtils;
 import org.apache.commons.lang3.tuple.Pair;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.data.redis.core.ZSetOperations;
 
@@ -23,6 +24,7 @@ import java.util.*;
 @Slf4j
 public abstract class AbstractFlowPoolWithLevelScoreRecallStrategy implements RecallStrategy {
     @Autowired
+    @Qualifier("redisTemplate")
     protected RedisTemplate<String, String> redisTemplate;
 
     @Autowired

+ 2 - 0
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/AbstractFlowPoolWithScoreRecallStrategy.java

@@ -11,6 +11,7 @@ import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.lang3.math.NumberUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.data.redis.core.ZSetOperations;
 
@@ -22,6 +23,7 @@ import java.util.*;
 @Slf4j
 public abstract class AbstractFlowPoolWithScoreRecallStrategy implements RecallStrategy {
     @Autowired
+    @Qualifier("redisTemplate")
     protected RedisTemplate<String, String> redisTemplate;
 
     @Autowired

+ 2 - 0
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/AbstractRegionRecallStrategy.java

@@ -17,6 +17,7 @@ import org.apache.commons.collections4.MapUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.math.NumberUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.data.redis.core.ZSetOperations;
@@ -30,6 +31,7 @@ import java.util.concurrent.TimeUnit;
 @Slf4j
 public abstract class AbstractRegionRecallStrategy implements RecallStrategy {
     @Autowired
+    @Qualifier("redisTemplate")
     protected RedisTemplate<String, String> redisTemplate;
     @ApolloJsonValue("${region.recall.return.size:{}}")
     protected Map<String, Map<String, Integer>> regionRecallReturnSize;

+ 2 - 0
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/AbstractVideoRecallStrategy.java

@@ -15,6 +15,7 @@ import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.lang.math.NumberUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.data.redis.core.RedisTemplate;
 
 import java.util.ArrayList;
@@ -28,6 +29,7 @@ import java.util.Map;
 @Slf4j
 public abstract class AbstractVideoRecallStrategy implements RecallStrategy {
     @Autowired
+    @Qualifier("redisTemplate")
     protected RedisTemplate<String, String> redisTemplate;
 
     @Autowired

+ 2 - 0
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/SpecialRecallStrategy.java

@@ -8,6 +8,7 @@ import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang.math.NumberUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.data.redis.core.ZSetOperations;
 import org.springframework.stereotype.Service;
@@ -24,6 +25,7 @@ import java.util.Set;
 @Slf4j
 public class SpecialRecallStrategy implements RecallStrategy {
     @Autowired
+    @Qualifier("redisTemplate")
     private RedisTemplate<String, String> redisTemplate;
 
     public static final String LAST_VIDEO_KEY_FORMAT = "recall:last:special:%s:%s:%s";

+ 3 - 1
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/score/ScorerPipeline.java

@@ -165,7 +165,9 @@ public class ScorerPipeline {
             int position = 0;
             for (RankItem item : items) {
                 item.getRankerIndex().put(scorerName, position++);
-                item.getRankerScore().put(scorerName, item.getScore());
+                if(scorerName.equals("finalScore")) {
+                    item.getRankerScore().put(scorerName, item.getScore());
+                }
             }
 
             //

+ 2 - 1
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/score/ScorerUtils.java

@@ -20,6 +20,7 @@ public final class ScorerUtils {
     private static Map<String, ScorerPipeline> scorerPipelineCache = new ConcurrentHashMap<>();
 
     public static String BASE_CONF = "feeds_score_config_baseline.conf";
+    public static String VIDEO_SCORE_CONF_FOR_AD = "video_score_config_for_ad.conf";
 
     public static String FLOWPOOL_CONF = "feeds_score_config_thompson.conf";
 
@@ -28,7 +29,7 @@ public final class ScorerUtils {
         log.info("scorer warm up ");
         ScorerUtils.init(BASE_CONF);
         ScorerUtils.init(FLOWPOOL_CONF);
-
+        ScorerUtils.init(VIDEO_SCORE_CONF_FOR_AD);
     }
 
     private ScorerUtils() {

+ 4 - 1
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/score/model/ModelManager.java

@@ -86,7 +86,10 @@ public class ModelManager {
     public void registerModel(String modelName, String path, Class<? extends Model> modelClass) throws ModelRegisterException, IOException {
         if (modelPathMap.containsKey(modelName)) {
             // fail fast
-            throw new RuntimeException(modelName + " already exists");
+            // throw new RuntimeException(modelName + " already exists");
+            // hard code  广告需要视频模型打分数据,配置要分开
+            return;
+
 //            String oldPath = modelPathMap.get(modelName);
 //            if (path.equals(oldPath)) {
 //                //如果模型的path没有发生改变, 不做任何操作

+ 3 - 3
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/util/CommonCollectionUtils.java

@@ -28,11 +28,11 @@ public class CommonCollectionUtils {
     }
 
 
-    public static <T, K, V> Map<K, V> toMap(List<T> list, Function<T, K> keyFunc, Function<T, V> valueFunc) {
-        if (CollectionUtils.isEmpty(list)) {
+    public static <T, K, V> Map<K, V> toMap(Collection<T> col, Function<T, K> keyFunc, Function<T, V> valueFunc) {
+        if (CollectionUtils.isEmpty(col)) {
             return Collections.emptyMap();
         }
-        return list.stream().collect(Collectors.toMap(keyFunc::apply, valueFunc::apply));
+        return col.stream().collect(Collectors.toMap(keyFunc::apply, valueFunc::apply));
     }
 
     public static <T> boolean contains(Collection<T> col, T ele) {

+ 12 - 1
recommend-server-service/src/main/resources/application-dev.yml

@@ -24,6 +24,17 @@ spring:
         max-wait: -1
         max-idle: 8
         min-idle: 0
+  feature-redis:
+    hostName: r-bp1pi8wyv6lzvgjy5z.redis.rds.aliyuncs.com
+    port: 6379
+    password: Wqsd@2019
+    timeout: 1000
+    lettuce:
+      pool:
+        max-active: 8
+        max-wait: -1
+        max-idle: 8
+        min-idle: 0
 
 xxl:
   job:
@@ -50,4 +61,4 @@ aliyun:
 
 logging:
   file:
-    path: ../logs/${spring.application.name}/
+    path: ./${spring.application.name}/logs/

+ 11 - 1
recommend-server-service/src/main/resources/application-pre.yml

@@ -24,7 +24,17 @@ spring:
         max-wait: -1
         max-idle: 8
         min-idle: 0
-
+  feature-redis:
+    hostName: r-bp1pi8wyv6lzvgjy5z.redis.rds.aliyuncs.com
+    port: 6379
+    password: Wqsd@2019
+    timeout: 1000
+    lettuce:
+      pool:
+        max-active: 8
+        max-wait: -1
+        max-idle: 8
+        min-idle: 0
 xxl:
   job:
     admin:

+ 11 - 1
recommend-server-service/src/main/resources/application-prod.yml

@@ -24,7 +24,17 @@ spring:
         max-wait: -1
         max-idle: 8
         min-idle: 0
-
+  feature-redis:
+    hostName: r-bp1pi8wyv6lzvgjy5z.redis.rds.aliyuncs.com
+    port: 6379
+    password: Wqsd@2019
+    timeout: 1000
+    lettuce:
+      pool:
+        max-active: 8
+        max-wait: -1
+        max-idle: 8
+        min-idle: 0
 xxl:
   job:
     admin:

+ 11 - 0
recommend-server-service/src/main/resources/application-test.yml

@@ -24,6 +24,17 @@ spring:
         max-wait: -1
         max-idle: 8
         min-idle: 0
+  feature-redis:
+    hostName: r-bp1pi8wyv6lzvgjy5z.redis.rds.aliyuncs.com
+    port: 6379
+    password: Wqsd@2019
+    timeout: 1000
+    lettuce:
+      pool:
+        max-active: 8
+        max-wait: -1
+        max-idle: 8
+        min-idle: 0
 
 xxl:
   job:

+ 12 - 0
recommend-server-service/src/main/resources/video_score_config_for_ad.conf

@@ -0,0 +1,12 @@
+scorer-config = {
+  str-score-config = {
+    scorer-name = "com.tzld.piaoquan.recommend.server.service.score.VlogShareLRScorer"
+    scorer-priority = 99
+    model-path = "video_str_model/model_sharev2_20231220_change.txt"
+  }
+  ros-score-config = {
+    scorer-name = "com.tzld.piaoquan.recommend.server.service.score.VlogShareLRScorer4Ros"
+    scorer-priority = 99
+    model-path = "video_str_model/model_ros_v2_20231220_change.txt"
+  }
+}