TPP方案代码SDK

更新时间:
复制为 MD 格式

本文介绍TPP方案代码SDK的使用方法。

概况

  • 方案执行的入口XXXSolution.java

  • 方案执行的上下文XXXContext.java

  • 方案执行的结果XXXResult.java

  • 方案生命周期配置LifeCycleConfig.java

  • 常用的Java类 lombok, commons-lang

那么需要别的jar包怎么办?tpp方案插件会提供一些其它jar包,比如:jedis、eas、httpClient、fastjson、abfs、be等)。

安装sdk

<!--
        sdk
        -->
        <dependency>
            <groupId>com.alibaba.airec.faassdk</groupId>
            <artifactId>cloud-sdk</artifactId>
            <version>0.1-SNAPSHOT</version>
        </dependency>

使用样例

/**
 * author: oe
 * date:   2021/9/6
 * comment:最简单的solution
 */
package com.alibaba.tpp.solution.hello;
import com.alibaba.glaucus.protocol.solution.GeneralSolution;
import com.alibaba.glaucus.protocol.solution.LifeCycleConfig;
import com.alibaba.glaucus.protocol.solution.SolutionContext;
import com.alibaba.glaucus.protocol.solution.SolutionResult;
import com.taobao.recommendplatform.protocol.solution.RecommendResultSupport;
import java.util.*;
public class HelloSolution implements GeneralSolution {
    @Override
    public void init(LifeCycleConfig lifeCycleConfig) {
    }
    @Override
    public SolutionResult execute(SolutionContext solutionContext) throws Exception {
        Map<String,String> abConfigMap = new LinkedHashMap<>();
        solutionContext.abConfigKeySet().forEach(key->{
            String value = solutionContext.getAbConfig(key);
            abConfigMap.put(key,value);
        });
        SolutionResult result = new RecommendResultSupport();
        Map<String,Object> map = new TreeMap<>();
        map.put("requestParams",solutionContext.getRequestParamsMapCopy());
        map.put("abConfigs",abConfigMap);
        List<Map<String,Object>> solutionResult= new ArrayList<>();
        solutionResult.add(map);
        result.setSolutionResult(solutionResult);
        result.setAttribute("HelloSolution", "hello hello hello");
        return result;
    }
    @Override
    public void destroy(LifeCycleConfig lifeCycleConfig) {
    }
}

核心类列表

class

说明

GeneralSolution.java

方案类。用户的方案都继承自此类。

3个抽象方法:

  • init

方案初始化,方案加载的时候执行,整个生命周期执行一次

  • destroy

方案销毁,方案卸载的时候执行,整个生命周期执行一次

  • execute

每来一个请求执行一次,整个生命周期执行多次

RecommendSolution.java

推荐方案类,继承自GeneralSolution。用户的推荐方案继承此类。

3个抽象方法:

  • init

  • destroy

  • recommend (execute方法调用recommend)

    • Context

入参,推荐上下文,每次请求不一样。

    • RecommendResult

出参,推荐结果,每次请求不一样。

LifeCycleConfig.java

方案初始化的入参,记录了一些全生命周期的信息。

@Overridepublic void init(LifeCycleConfig lifeCycleConfig) { lifeCycleConfig.getSolutionId();//方案id lifeCycleConfig.getAppId();//场景id}

SolutionContext.java

方案execute入参,方案上下文,每次请求不一样。

此类中可获取ab实验参数、请求参数、保存每一次执行的中间结果。

  • solutionContext.getAbConfig(key); //ab实验参数

  • solutionContext.getRequestParamsMapCopy();//请求参数

注意:如果配置项特别大, 重复比较耗时, 建议进行缓存, 定期更新

Context.java

推荐方案入参数,继承自SolutionContext。

用户可以继承此类,构造自己的上下文,只保留需要的数据。例如demo中的RecommendContext.java:

/**
 * 构建RecommendContext
 * 如果配置项特别大,重复比较耗时,建议进行缓存,定期更新
 *
 * @param solutionContext
 * @return
 */
public final static RecommendContext build(SolutionContext solutionContext) {
    RecommendContext context = new RecommendContext();
    //log
    context.setLogContext(new LogContext(new SolutionLogger() {...})) ;
    //userId
    String userId = (String) solutionContext.getRequestParams("userId");
    context.setUserId(userId == null ? "" : userId);
    //request params
    context.setRequestParams(solutionContext.getRequestParamsMapCopy());
    parseRequestParams(context.getRequestParams(), context);
    //ab config
    solutionContext.abConfigKeySet().forEach(key -> {
        context.getAbConfigs().put(key, solutionContext.getAbConfig(key));
    });
    parseAbConfigs(context.getAbConfigs(), context);
    return context;
}

SolutionResult.java

方案出参,最终返回给TPP服务调用方。

result.setSolutionResult(list);//核心结果result.setAttribute("HelloSolution", "hello hello hello");//辅助字段

调用后返回的完整 JSON 响应结构中,result 数组对应 setSolutionResult 设置的核心结果,HelloSolution 对应 setAttribute 设置的辅助字段:

{ "result": [ {...} ], "HelloSolution": "hello hello hello", "solutionCluster": "TPP-123456ABCEFG", "pvid": "b4a2ced6-e824-4b4a-89f5-a3b33fcb6c8a", "debuginfo": "", "solutionid": 22, "solutionHost": "172.20.0.103", "scm": "1007.10001.-1.0", "version": 1, "tpp_trace": "ac14006716352163860146287d00fc", "time_used": 1 }

RecommendResult.java

推荐方案出参,继承自SolutionResult。实现了父类的2个方法:

  • List<Object> getSolutionResult();

此处变成获取推荐结果

  • void setSolutionResult(List<? extends Object> var1);

此处变成设置推荐结果

RecommendResultSupport.java

推荐方案出参,继承自RecommendResult,实现了所有父类方法,可以直接使用。最佳实践也是使用此类。

Map<String, Object> models

models存储result、attribute、scmid(埋点日志)、trafficLimit(限流)

  • result 推荐结果,存储在models,key="result"

  • scmid 埋点日志,存储在models,key="scmid"

  • attribute 辅助字段,存储在models,key 不可以和上面的冲突

boolean empty

此次返回是否空结果(非异常导致、就是没有推荐结果or抄底了)

TPP 方案调用返回的 JSON 响应示例如下,其中关键字段含义已通过注释标注:

{
  "result": [...],                                    // result:推荐结果
  "solutionCluster": "TPP-123456ABCEFG",              // instanceId
  "pvid": "6c629df4-cc72-469d-86a5-9985ee866f28",
  "emptyTraceLog": "empty-trace-log\ncom.alibaba.tpp.solution.demo.match.I2iBeMatch:",
  "debuginfo": "",
  "dataTraceLog": "data-trace-log\ncom.alibaba.tpp.solution.demo.match.I2iRedisMatch:",
  "solutionid": 23,                                   // 方案id
  "solutionHost": "172.20.0.103",
  "scm": "1007.10001.-1.0",                           // 埋点信息
  "version": 1,
  "tpp_trace": "ac14006716352176020517740d00fc",
  "time_used": 641                                     // 运行时间(ms)
}