实验性 Java API#

警告

Java API 支持是一项实验性功能,可能会发生变化。

目前 KubeRay 不支持 Java API。

Java 是用于生产服务的主流编程语言。Ray Serve 提供原生 Java API 用于创建、更新和管理部署。你可以使用 Java 创建 Ray Serve 部署并通过 Python 调用它们,反之亦然。

本节将帮助你

  • 创建、查询和更新 Java 部署

  • 配置 Java 部署资源

  • 使用 Java API 管理 Python 部署

创建部署#

通过将类的完整名称指定为 Serve.deployment() 方法的参数,如下面的代码所示,你可以创建和部署该类的部署。

  public static class Counter {

    private AtomicInteger value;

    public Counter(String value) {
      this.value = new AtomicInteger(Integer.valueOf(value));
    }

    public String call(String delta) {
      return String.valueOf(value.addAndGet(Integer.valueOf(delta)));
    }
  }

  public void create() {
    Application app =
        Serve.deployment()
            .setName("counter")
            .setDeploymentDef(Counter.class.getName())
            .setNumReplicas(1)
            .bind("1");
    Serve.run(app);
  }

访问部署#

部署完成后,你可以通过名称获取其实例。

  public Deployment query() {
    Deployment deployment = Serve.getDeployment("counter");
    return deployment;
  }

更新部署#

你可以更新部署的代码和配置,然后重新部署它。以下示例将 "counter" 部署的初始值更新为 2。

  public void update() {
    Application app =
        Serve.deployment()
            .setName("counter")
            .setDeploymentDef(Counter.class.getName())
            .setNumReplicas(1)
            .bind("2");
    Serve.run(app);
  }

配置部署#

Ray Serve 允许你配置部署以实现

接下来的两节描述了如何配置你的部署。

横向扩展#

通过指定 numReplicas 参数,你可以更改部署副本的数量

  public void scaleOut() {
    Deployment deployment = Serve.getDeployment("counter");

    // Scale up to 2 replicas.
    Serve.run(deployment.options().setNumReplicas(2).bind());

    // Scale down to 1 replica.
    Serve.run(deployment.options().setNumReplicas(1).bind());
  }

资源管理 (CPU, GPU)#

通过 rayActorOptions 参数,你可以为每个部署副本预留资源,例如一个 GPU

  public void manageResource() {
    Map<String, Object> rayActorOptions = new HashMap<>();
    rayActorOptions.put("num_gpus", 1);
    Application app =
        Serve.deployment()
            .setName("counter")
            .setDeploymentDef(Counter.class.getName())
            .setRayActorOptions(rayActorOptions)
            .bind();
    Serve.run(app);
  }

管理 Python 部署#

Python 部署也可以由 Java API 管理和调用。假设你在 /path/to/code/ 目录下有一个 Python 文件 counter.py

from ray import serve

@serve.deployment
class Counter(object):
    def __init__(self, value):
        self.value = int(value)

    def increase(self, delta):
        self.value += int(delta)
        return str(self.value)

你可以通过 Java API 部署它,并通过 RayServeHandle 调用它

import io.ray.api.Ray;
import io.ray.serve.api.Serve;
import io.ray.serve.deployment.Deployment;
import io.ray.serve.generated.DeploymentLanguage;
import java.io.File;

public class ManagePythonDeployment {

  public static void main(String[] args) {

    System.setProperty(
        "ray.job.code-search-path",
        System.getProperty("java.class.path") + File.pathSeparator + "/path/to/code/");

    Serve.start(true, false, null);

    Deployment deployment =
        Serve.deployment()
            .setDeploymentLanguage(DeploymentLanguage.PYTHON)
            .setName("counter")
            .setDeploymentDef("counter.Counter")
            .setNumReplicas(1)
            .setInitArgs(new Object[] {"1"})
            .create();
    deployment.deploy(true);

    System.out.println(Ray.get(deployment.getHandle().method("increase").remote("2")));
  }
}

注意

Ray.initServe.start 之前,你需要指定一个目录来查找 Python 代码。详情请参阅跨语言编程

未来路线图#

未来,Ray Serve 计划提供更多 Java 特性,例如

  • 与 Python 版本匹配的改进型 Java API

  • HTTP 入口支持

  • 将你自己的 Java Spring 项目作为部署