适配器开发过程

  1. 首先在如下目录开发自定义适配器,具体如何开发见后续教程

image.png

  1. 编写好adapter后对 fate-serving-extension 模块进行打包,在target下拿到 fate-serving-extension-2.1.0.jar

image.png

  1. 打开 fate-servingserver 模块部署目录下 extension 目录,通过xftp工具替换jar包

    1. cd /data/projects/fate-serving/server/extension

    image.png

  2. 重新编写配置文件,更改使用的适配器

    1. cd /data/project/fate-serving/server/conf
    2. vim serving-server.properties

    image.png

  3. 重启server

    1. cd /data/project/fate-serving/server
    2. ./service.sh restart

    单个预测适配器如何开发

    实现单个预测适配器,需要继承AbstractSingleFeatureDataAdaptor

    1. public class CustomAdapter extends AbstractSingleFeatureDataAdaptor {
    2. @Override
    3. public void init() {
    4. // init() 方法中可以直接使用environment对象
    5. // environment.getProperty("port");
    6. }
    7. @Override
    8. public ReturnResult getData(Context context, Map<String, Object> featureIds) {
    9. // ...
    10. }
    11. }
  • init用于获取配置文件中的参数,可用于获取自定义接口地址
  • getData用于返回host端获取的特征值,特征值要根据featureIds(如:{“id”:123,”tel”:13000000000})中guest端传来数据进行获取,最终要返回一个ReturnResult类型的实例,这个实例要通过setData与setRetcode设置相关信息。

案例:
guest端传来的featureIds包括:id

host端数据源如图所示,第一行为标签,其余为数据,数据源位于server模块根目录下名为host_data.csv
image.png
对应的adaper代码为

  1. public class MyFileAdapter extends AbstractSingleFeatureDataAdaptor {
  2. private static final Logger logger = LoggerFactory.getLogger(MyFileAdapter.class);
  3. @Override
  4. public void init() {
  5. }
  6. @Override
  7. public ReturnResult getData(Context context, Map<String, Object> featureIds) {
  8. ReturnResult returnResult = new ReturnResult();
  9. Map<String, Object> data = new HashMap<>();
  10. try {
  11. logger.info("testHost data path = {}", Paths.get(System.getProperty(Dict.PROPERTY_USER_DIR), "host_data.csv"));
  12. logger.info(featureIds.toString());
  13. List<String> lines = Files.readAllLines(Paths.get(System.getProperty(Dict.PROPERTY_USER_DIR), "host_data.csv"));
  14. String[] label = StringUtils.split(lines.get(0), ",");
  15. int id = (Integer)featureIds.get("id");
  16. logger.info(String.valueOf(id));
  17. int flag = 0;
  18. for (int i = 1; i < lines.size(); i++) {
  19. String[] item = StringUtils.split(lines.get(i), ",");
  20. if (Integer.parseInt(item[0]) == id) {
  21. for (int j = 1; j < item.length; j++) {
  22. data.put(label[j], Double.parseDouble(item[j]));
  23. }
  24. flag = 1;
  25. break;
  26. }
  27. }
  28. if(flag == 0){
  29. logger.info("未找到数据!");
  30. throw new Exception();
  31. }
  32. else{
  33. logger.info(data.toString());
  34. returnResult.setData(data);
  35. returnResult.setRetcode(StatusCode.SUCCESS);
  36. }
  37. } catch (Exception ex) {
  38. logger.error(ex.getMessage());
  39. returnResult.setRetcode(StatusCode.HOST_FEATURE_ERROR);
  40. }
  41. return returnResult;
  42. }
  43. }

其中,处理之后的data形式为:{“x1”:0.123,”x2”:-1.65}

多个预测适配器如何开发