开发工作流程#
本页描述了开发 Ray Serve 应用的推荐工作流程。如果您已准备好投入生产环境,请跳至生产指南部分。
使用 serve.run
进行本地开发#
您可以在 Python 脚本中使用 serve.run
在本地运行和测试您的应用,使用句柄以编程方式发送请求,而不是通过 HTTP。
优势
自包含的 Python 便于编写本地集成测试。
无需部署到云提供商或管理基础设施。
缺点
不测试 HTTP 端点。
如果您的本地机器没有 GPU,则无法使用 GPU。
让我们看一个简单的例子。
# Filename: local_dev.py
from starlette.requests import Request
from ray import serve
from ray.serve.handle import DeploymentHandle, DeploymentResponse
@serve.deployment
class Doubler:
def double(self, s: str):
return s + " " + s
@serve.deployment
class HelloDeployment:
def __init__(self, doubler: DeploymentHandle):
self.doubler = doubler
async def say_hello_twice(self, name: str):
return await self.doubler.double.remote(f"Hello, {name}!")
async def __call__(self, request: Request):
return await self.say_hello_twice(request.query_params["name"])
app = HelloDeployment.bind(Doubler.bind())
我们可以添加以下代码以在本地部署和测试 Serve。
handle: DeploymentHandle = serve.run(app)
response: DeploymentResponse = handle.say_hello_twice.remote(name="Ray")
assert response.result() == "Hello, Ray! Hello, Ray!"
使用 HTTP 请求进行本地开发#
您可以使用 serve run
CLI 命令在本地运行和测试您的应用,使用 HTTP 发送请求(类似于如果您熟悉 Uvicorn,您可能会使用的 uvicorn
命令)。
回顾上面的例子
# Filename: local_dev.py
from starlette.requests import Request
from ray import serve
from ray.serve.handle import DeploymentHandle, DeploymentResponse
@serve.deployment
class Doubler:
def double(self, s: str):
return s + " " + s
@serve.deployment
class HelloDeployment:
def __init__(self, doubler: DeploymentHandle):
self.doubler = doubler
async def say_hello_twice(self, name: str):
return await self.doubler.double.remote(f"Hello, {name}!")
async def __call__(self, request: Request):
return await self.say_hello_twice(request.query_params["name"])
app = HelloDeployment.bind(Doubler.bind())
现在在您的终端中运行以下命令
serve run local_dev:app
# 2022-08-11 11:31:47,692 INFO scripts.py:294 -- Deploying from import path: "local_dev:app".
# 2022-08-11 11:31:50,372 INFO worker.py:1481 -- Started a local Ray instance. View the dashboard at http://127.0.0.1:8265.
# (ServeController pid=9865) INFO 2022-08-11 11:31:54,039 controller 9865 proxy_state.py:129 - Starting HTTP proxy with name 'SERVE_CONTROLLER_ACTOR:SERVE_PROXY_ACTOR-dff7dc5b97b4a11facaed746f02448224aa0c1fb651988ba7197e949' on node 'dff7dc5b97b4a11facaed746f02448224aa0c1fb651988ba7197e949' listening on '127.0.0.1:8000'
# (ServeController pid=9865) INFO 2022-08-11 11:31:55,373 controller 9865 deployment_state.py:1232 - Adding 1 replicas to deployment 'Doubler'.
# (ServeController pid=9865) INFO 2022-08-11 11:31:55,389 controller 9865 deployment_state.py:1232 - Adding 1 replicas to deployment 'HelloDeployment'.
# (HTTPProxyActor pid=9872) INFO: Started server process [9872]
# 2022-08-11 11:31:57,383 SUCC scripts.py:315 -- Deployed successfully.
serve run
命令会阻塞终端,可以使用 Ctrl-C 取消。通常,不应在多个终端同时运行 serve run
,除非每个 serve run
针对的是一个独立的正在运行的 Ray 集群。
现在 Serve 正在运行,我们可以向应用发送 HTTP 请求。为简单起见,我们将仅使用 curl
命令从另一个终端发送请求。
curl -X PUT "http://localhost:8000/?name=Ray"
# Hello, Ray! Hello, Ray!
测试完成后,您可以通过中断 serve run
命令来关闭 Ray Serve(例如,使用 Ctrl-C)
^C2022-08-11 11:47:19,829 INFO scripts.py:323 -- Got KeyboardInterrupt, shutting down...
(ServeController pid=9865) INFO 2022-08-11 11:47:19,926 controller 9865 deployment_state.py:1257 - Removing 1 replicas from deployment 'Doubler'.
(ServeController pid=9865) INFO 2022-08-11 11:47:19,929 controller 9865 deployment_state.py:1257 - Removing 1 replicas from deployment 'HelloDeployment'.
请注意,重新运行 serve run
会重新部署所有部署。为了防止重新部署代码未更改的部署,您可以使用 serve deploy
;详情请参阅生产指南。
本地测试模式#
注意
这是一项实验性功能。
Ray Serve 支持本地测试模式,允许您在单个进程中本地运行部署。此模式对于单元测试和调试应用逻辑非常有用,无需完整 Ray 集群的开销。要启用此模式,请在 serve.run
函数中使用 _local_testing_mode
标志
serve.run(app, _local_testing_mode=True)
此模式在后台线程中运行每个部署,并支持与在完整 Ray 集群上运行相同的大多数功能。请注意,某些功能(例如将 DeploymentResponses
转换为 ObjectRefs
)在本地测试模式下不受支持。如果您遇到限制,请考虑在 GitHub 上提交功能请求。
在远程集群上测试#
要在远程集群上测试,请再次使用 serve run
,但这次传入 --address
参数来指定要连接的 Ray 集群的地址。对于远程集群,此地址的形式为 ray://<head-node-ip-address>:10001
;有关更多信息,请参阅Ray 客户端。
从本地机器过渡到远程集群时,您需要确保集群具有与本地机器相似的环境——例如文件、环境变量和 Python 包。
让我们看一个只打包代码的简单示例。在您的本地机器上运行以下命令,将命令中的 <head-node-ip-address>
替换为您的远程集群头节点 IP 地址
serve run --address=ray://<head-node-ip-address>:10001 --working-dir="./project/src" local_dev:app
这将使用 Ray 客户端连接到远程集群,上传 working_dir
目录,并运行您的 Serve 应用。在此,由 working_dir
指定的本地目录必须包含 local_dev.py
,以便可以将其上传到集群并由 Ray Serve 导入。
一旦启动并运行,我们可以向应用发送请求
curl -X PUT http://<head-node-ip-address>:8000/?name=Ray
# Hello, Ray! Hello, Ray!
对于更复杂的依赖项,包括工作目录之外的文件、环境变量和 Python 包,您可以使用运行时环境。此示例使用 –runtime-env-json 参数
serve run --address=ray://<head-node-ip-address>:10001 --runtime-env-json='{"env_vars": {"MY_ENV_VAR": "my-value"}, "working_dir": "./project/src", "pip": ["requests", "chess"]}' local_dev:app
您也可以在 YAML 文件中指定 runtime_env
;详情请参阅serve run。
接下来是什么?#
在Ray dashboard 中查看您的 Serve 应用详情。一旦准备好部署到生产环境,请参阅生产指南。