为 LLM 回答和其他流量配置流式传输
本文档介绍了如何在 API Gateway 中配置流式传输。
API Gateway 支持流式传输。通过流式传输,网关可以处理长时间运行的连接,并以块的形式传输数据,以实现请求和响应流式传输。
流式传输的常见用途是为大语言模型 (LLM) 提供服务。模型会一次发送一个令牌的回答,因此客户端可以在模型仍在生成文本时显示该文本。如需查看一个完整的示例,了解如何从 vLLM 在 Cloud Run 上部署的 Gemma 模型流式传输响应,请参阅从 LLM 流式传输响应。
支持的流式传输协议
启用后,API Gateway 支持以下流式传输方法:
- 增量响应传送:HTTP/2 DATA 帧或 HTTP/1.1 分块传输编码,具体取决于客户端协商的结果。
- 服务器发送的事件 (SSE):从服务器到客户端的单向流式传输。
- WebSockets:通过单个 TCP 连接实现全双工通信通道。
- gRPC 双向流式传输:使用 gRPC 进行全双工流式传输。
前提条件
在使用流式传输之前,请确保您的后端服务支持所需的协议(例如 HTTP/2 或 WebSockets),并且您的 API 配置已正确设置。
配置后端协议
如需支持流式传输流量,您必须根据流式传输类型为后端配置协议:
- gRPC:您必须将后端配置为使用 HTTP/2 (
h2)。 - WebSockets:您必须使用
http/1.1。WebSocket 需要 HTTP/1.1Connection: Upgrade握手。 - 服务器发送的事件 (SSE) 和增量响应交付:后端可以使用 HTTP/1.1 或 HTTP/2 (
h2)。建议使用 HTTP/2 (h2) 以提高性能。
在 OpenAPI 规范中,按如下方式配置后端协议:
示例 (OpenAPI 3.x)
在 x-google-api-management.backends 对象中,设置已命名后端定义中的 protocol 字段。您还必须在根级或操作级使用 x-google-backend 引用此后端。
x-google-api-management:
backends:
gemma:
address: https://my-gemma-service.run.app
protocol: h2 # Use 'http/1.1' for WebSockets
x-google-backend: gemma
示例 (OpenAPI 2.0)
设置 x-google-backend 扩展程序中的 protocol 字段。
x-google-backend:
address: https://my-gemma-service.run.app
protocol: h2 # Use 'http/1.1' for WebSockets
设置直播截止时间
deadline 字段用于控制请求(一元或流式)的运行时长。
下表显示了超时时间如何应用于每种类型的请求:
| 方法 | 空闲超时时间 (消息之间的最大间隔) |
请求超时时间 (最长总请求时长) |
|---|---|---|
| 非流式传输 | 不适用:空闲超时仅适用于流 | 默认值为 15 秒;设置 deadline 可更改此值,对于支持流式传输的网关,最长可设置为 3,600 秒 |
| 通过 HTTP 进行流式传输 (SSE、分块传输) |
不适用:实际上是无限的;只有请求超时才会结束流 | 默认值为 15 秒;设置 deadline 可更改此值,对于支持流式传输的网关,最长可设置为 3,600 秒 |
| 通过 gRPC 或 WebSocket 进行流式传输 | 默认值为 300 秒;设置 deadline 可更改此值,对于支持流式传输的网关,此值最多可设置为 3,600 秒。在 WebSocket 上,系统会忽略小于 300 秒的 deadline,并应用 300 秒的最小值 |
对于支持流式传输的网关,始终为 3,600 秒,不可配置 |
示例 (OpenAPI 3.x)
在具名后端定义中设置 deadline 字段。
x-google-api-management:
backends:
gemma:
address: https://my-gemma-service.run.app
protocol: h2
deadline: 3600.0
x-google-backend: gemma
示例 (OpenAPI 2.0)
设置 x-google-backend 扩展程序中的 deadline 字段。
x-google-backend:
address: https://my-gemma-service.run.app
protocol: h2
deadline: 3600.0
如需了解适用于流式传输连接的其他限制,请参阅限制。
在网关上启用流式传输
流式传输是在创建网关时指定的。请注意以下行为:
- 没有明确的停用标志:没有可用于明确停用直播的标志。如果您省略
--enable-streaming标志,API Gateway 会在创建时根据 API 配置和平台默认设置解析模式:配置了模型路由器的 API 配置始终会生成流式网关。读取网关的只输出effectiveStreamingMode字段,查看创建网关时使用的模式。 - 不可变性:流式传输模式在创建时即已确定,之后无法修改。
如需在网关上指定流式传输,请将 --enable-streaming 标志与 gcloud api-gateway gateways create 命令结合使用:
gcloud api-gateway gateways create GATEWAY_ID \
--api=API_ID \
--api-config=CONFIG_ID \
--location=GCP_REGION \
--enable-streaming如需详细了解网关部署选项,请参阅将 API 部署到网关。
网关流式传输属性
Gateway 资源上的以下字段用于控制流式传输行为:
| 字段 | 属性 | 值 |
|---|---|---|
streamingMode |
字符串(不可变,可选) |
|
effectiveStreamingMode |
字符串 (OUTPUT_ONLY) |
|
使用 REST API 创建网关时,您可以在请求正文中指定流式传输:
{
"apiConfig": "projects/...",
"streamingMode": "STREAMING_MODE_ENABLED"
}
验证流式传输是否已启用
如需确认网关上是否已启用流式传输,请使用 gcloud CLI 描述网关:
gcloud api-gateway gateways describe GATEWAY_ID \
--location=GCP_REGION在输出中查找 effectiveStreamingMode 字段。如果启用了流式传输,则输出包括:
effectiveStreamingMode: EFFECTIVE_STREAMING_MODE_ENABLED
从 LLM 流式传输回答
此示例将流式网关置于 vLLM 在 Cloud Run 上部署的 Gemma 模型之前,并通过该网关以流式方式完成聊天。vLLM 部署了一个与 OpenAI 兼容的 API,该 API 以服务器发送事件 (SSE) 的形式流式传输响应。
在开始之前,请完成配置开发环境,包括配置用于创建 API 配置的服务账号。网关使用该服务账号来调用 Cloud Run 服务。
部署模型
按照使用 vLLM 容器部署 Gemma 4 模型中的说明部署 Gemma 模型。记下服务名称、服务网址、区域以及您部署的模型的名称,例如 google/gemma-4-E4B-it。
向网关授予对服务的访问权限
该指南使用 --no-allow-unauthenticated 部署服务。网关使用其服务账号的 ID 令牌调用服务,您可以在创建 API 配置时将该令牌作为 --backend-auth-service-account 传递。向该服务账号授予 Cloud Run Invoker 角色 (roles/run.invoker):
gcloud run services add-iam-policy-binding SERVICE_NAME \
--region=REGION \
--member=serviceAccount:SERVICE_ACCOUNT_EMAIL \
--role=roles/run.invoker替换以下内容:
SERVICE_NAME:Cloud Run 服务的名称REGION:部署服务的区域SERVICE_ACCOUNT_EMAIL:网关的服务账号的电子邮件地址
创建 API 配置
将以下 OpenAPI 规范另存为 gemma-api.yaml,并将 https://my-gemma-service.run.app 替换为您的服务网址:
openapi: 3.0.3
info:
title: Gemma API
version: 1.0.0
x-google-api-management:
backends:
gemma:
address: https://my-gemma-service.run.app
protocol: h2
deadline: 570.0
x-google-backend: gemma
components:
securitySchemes:
google_id_token:
type: oauth2
flows:
implicit:
authorizationUrl: ""
scopes: {}
x-google-auth:
issuer: https://accounts.google.com
jwksUri: https://www.googleapis.com/oauth2/v3/certs
audiences:
- gemma-api
security:
- google_id_token: []
paths:
/v1/chat/completions:
post:
operationId: createChatCompletion
responses:
'200':
description: A chat completion, streamed as SSE when the request sets "stream" to true.
570 秒的 deadline 比 Gemma 指南中为该服务设置的 --timeout 600 短 30 秒。因此,网关的 deadline(而非服务超时)会结束运行时间过长的流。顶级 x-google-backend 默认为 pathTranslation: APPEND_PATH_TO_ADDRESS。网关会将请求路径附加到后端地址,因此对 /v1/chat/completions 的请求会到达 vLLM 聊天补全端点。
security 要求会使网关拒绝任何未携带具有受众群体 gemma-api 的 Google 签名 ID 令牌的请求。您可以选择其他受众群体字符串,只要调用方在生成令牌时请求的是同一字符串即可。如需了解详情,请参阅使用 Google ID 令牌对用户进行身份验证。
创建 API 配置:
gcloud api-gateway api-configs create CONFIG_ID \
--api=API_ID \
--openapi-spec=gemma-api.yaml \
--backend-auth-service-account=SERVICE_ACCOUNT_EMAIL替换以下内容:
CONFIG_ID:API 配置的 IDAPI_ID:API 的 ID。如果该 API 不存在,该命令会创建它。
创建网关
根据 API 配置创建流式网关:
gcloud api-gateway gateways create GATEWAY_ID \
--api=API_ID \
--api-config=CONFIG_ID \
--location=GCP_REGION \
--enable-streaming替换以下内容:
GATEWAY_ID:网关的 IDGCP_REGION:网关的区域,可以与REGION不同。如需了解允许的值,请参阅将 API 部署到网关。
当网关准备就绪后,获取其主机名:
gcloud api-gateway gateways describe GATEWAY_ID \
--location=GCP_REGION \
--format="value(defaultHostname)"获取调用者的 ID 令牌
用户账号无法选择其 ID 令牌的目标对象,因此该示例会为您模拟的服务账号生成令牌。对于调用方,请使用现有服务账号或创建一个服务账号。如需了解详情,请参阅创建服务账号。向您自己授予该服务账号的 Service Account Token Creator 角色 (roles/iam.serviceAccountTokenCreator),gcloud CLI 需要该角色才能模拟该服务账号:
gcloud iam service-accounts add-iam-policy-binding CALLER_SERVICE_ACCOUNT_EMAIL \
--member=user:USER_EMAIL \
--role=roles/iam.serviceAccountTokenCreator替换以下内容:
CALLER_SERVICE_ACCOUNT_EMAIL:调用网关的服务账号的电子邮件地址USER_EMAIL:您的电子邮件地址
发送流式传输请求
发送设置了 "stream": true 的对话补全请求,并在 Authorization 标头中包含调用方服务账号的 ID 令牌。-N 标志会关闭 curl 中的输出缓冲,因此每个事件都会在到达时打印:
curl -N https://DEFAULT_HOSTNAME/v1/chat/completions \
-H "Authorization: Bearer $(gcloud auth print-identity-token \
--impersonate-service-account=CALLER_SERVICE_ACCOUNT_EMAIL \
--audiences=gemma-api)" \
-H "Content-Type: application/json" \
-d '{
"model": "MODEL_NAME",
"messages": [{"role": "user", "content": "Why is the sky blue?"}],
"stream": true
}'替换以下内容:
DEFAULT_HOSTNAME:网关的主机名CALLER_SERVICE_ACCOUNT_EMAIL:上一步中的服务账号MODEL_NAME:您部署的模型,例如google/gemma-4-E4B-it
响应是一个 SSE 流。第一个事件携带 assistant 角色,每个后续事件携带答案的下一部分,而 data: [DONE] 之前的最后一个事件设置 finish_reason。输出类似于以下内容:
data: {"id":"chatcmpl-7bcd57ad-1c3c-4779-91be-2973b875e517","object":"chat.completion.chunk","created":1790099706,"model":"google/gemma-4-E4B-it","choices":[{"index":0,"delta":{"role":"assistant","content":""},"logprobs":null,"finish_reason":null}],"prompt_token_ids":null}
data: {"id":"chatcmpl-7bcd57ad-1c3c-4779-91be-2973b875e517","object":"chat.completion.chunk","created":1790099706,"model":"google/gemma-4-E4B-it","choices":[{"index":0,"delta":{"content":"The"},"logprobs":null,"finish_reason":null,"token_ids":null}]}
...
data: {"id":"chatcmpl-7bcd57ad-1c3c-4779-91be-2973b875e517","object":"chat.completion.chunk","created":1790099706,"model":"google/gemma-4-E4B-it","choices":[{"index":0,"delta":{"content":""},"logprobs":null,"finish_reason":"stop","stop_reason":106,"token_ids":null}]}
data: [DONE]
清理
为避免因本示例中使用的资源导致您的 Google Cloud 账号产生费用,请删除网关和 API 配置:
gcloud api-gateway gateways delete GATEWAY_ID \
--location=GCP_REGIONgcloud api-gateway api-configs delete CONFIG_ID \
--api=API_ID如果您为此示例创建了 API,请将其删除:
gcloud api-gateway apis delete API_ID
删除 Cloud Run 服务:
gcloud run services delete SERVICE_NAME \
--region=REGION价格
在流式传输功能的公开预览期间,客户无需为启用流式传输功能的网关上的网络出站流量付费。不过,无论发布阶段如何,Service Control 结算仍适用于 API 级别。
限制
在公开预览版期间,API Gateway 中的流式传输存在以下限制:
不可变性:您无法更新现有网关来启用或停用流式传输。您必须创建新网关。请注意,启用流式传输的网关会收到不同的主机名格式,因此您需要更新客户端或 DNS 记录。如果您希望我们更新网关记录以使用新格式,请与支持团队联系。API Gateway 使用以下主机名模式:
- 非流式:
{gateway_id}-{base36_project_number}.{shard_hash}.gateway.dev,例如test-gateway-4jcaz8x.uc.gateway.dev - 流式传输:
{gateway_id}-{project_number}.{region}.gateway.dev,例如test-gateway-9876654321.us-central1.gateway.dev - 流式(旧版):
{service}-{tenant_project_number}.{region}.run.app,例如test-gateway-834512064953.us-central1.run.app。在区域性*.gateway.dev主机名可用之前创建的网关会永久保留此主机名,不会迁移到新模式。
支持流式传输的新网关接收 Streaming 模式。前两个示例是同一项目中的同一网关:在流式模式下,项目编号以十进制而非 base36 显示,因此第一个标签的空间比非流式网关上的空间小。第一个标签是组合的
{gateway_id}-{project_number}字符串,必须符合 63 个字符的 DNS 标签限制。49 个字符的网关 ID 限制可确保项目编号不超过 13 位数;如果项目编号更长,则需要更短的网关 ID。- 非流式:
Terraform:不支持使用 Terraform 启用流式传输(计划在未来版本中实现)。
负载均衡和自定义网域:
effectiveStreamingMode为EFFECTIVE_STREAMING_MODE_ENABLED的网关与 API Gateway 的 HTTP(S) 负载均衡或无服务器 NEG 不兼容。您无法将此类网关放置在无服务器 NEG 或外部应用负载均衡器后面。因此,在公开预览版期间,这些网关不支持自定义网域(依赖于负载均衡)。截止时间行为:在网关上启用流式传输不会改变
deadline字段在 SSE 或分块传输路径上的行为。截止时间仍然是完整响应的实际时间界限,因此一旦截止时间到期,无论流正在发送多少数据,都会被切断。默认值为 15 秒,最大值为 3,600 秒。在 WebSocket 上,deadline会限制消息之间的间隔,连接会在 3,600 秒后终止。请参阅设置流截止时间。Model Context Protocol (MCP):使用
--enable-streaming创建网关不会生成 MCP 端点流。无论网关的流处理模式如何,MCP 响应始终是单个application/json正文。如需了解详情,请参阅 MCP 限制。