跳到主要内容

路由与故障转移

本指南将介绍如何创建多目标模型,用一个面向调用方的模型别名承载多个目标模型。

多目标模型不会直接调用服务提供方。它使用 routing 配置块指向目标模型别名,并由 AISIX 为每次请求选择其中一个目标。

准备工作

请先准备以下内容:

  • 一个 Admin 和代理监听器都可用的自托管网关。
  • 网关 config.yaml 中的 Admin Key。
  • 两个可以承载流量的目标模型。如果还没有创建,请先配置服务提供方凭证模型别名
  • 一个用于验证的调用方 API Key。可以按照调用方 API Key 创建,也可以在本指南中创建。

选择路由策略

请根据面向调用方的别名需要承担的行为选择策略:

  • 使用 failover 保留一个主目标,并配置备用目标。
  • 使用 round_robin 在多个相似目标之间轮转请求。
  • 使用 weighted 将更多流量发送到部分目标。

AISIX 会在可重试的上游失败上执行重试和故障转移,例如 5xx 响应、请求超时和传输错误。大多数上游 4xx 响应会被视为调用方侧问题,不会触发故障转移;但启用 retry_on_429 时,429 例外。

创建多目标模型

设置本指南中使用的 Admin Key 和模型别名:

export AISIX_ADMIN_KEY="admin-local-only-change-me"
export PRIMARY_MODEL="gpt-4o-primary"
export SECONDARY_MODEL="gpt-4o-secondary"
export ROUTING_MODEL="chat-prod"

创建一个故障转移模型:它会先从主目标开始,在失败时回退到备用目标。

curl -sS -X POST "http://127.0.0.1:3001/admin/v1/models" \
-H "Authorization: Bearer ${AISIX_ADMIN_KEY}" \
-H "Content-Type: application/json" \
-d '{
"display_name": "'"${ROUTING_MODEL}"'",
"routing": {
"strategy": "failover",
"targets": [
{"model": "'"${PRIMARY_MODEL}"'"},
{"model": "'"${SECONDARY_MODEL}"'"}
],
"retries": 1,
"max_fallbacks": 1,
"retry_on_429": true
}
}'

你应该会看到类似下面的响应:

{
"id": "134c4b01-09e6-41b7-97c7-f4e9a608f4c2",
"value": {
"display_name": "chat-prod",
"routing": {
"strategy": "failover",
"targets": [
{
"model": "gpt-4o-primary"
},
{
"model": "gpt-4o-secondary"
}
],
"retries": 1,
"max_fallbacks": 1,
"retry_on_429": true
}
},
"revision": 1
}

如果后续需要更新、查看或删除该多目标模型,请复制高亮的 id

使用该配置时,AISIX 会从 gpt-4o-primary 开始。如果该目标发生可重试失败,AISIX 可以先重试一次,然后再故障转移到 gpt-4o-secondary

允许调用方访问

调用方 API Key 必须被允许使用多目标别名。如果已经有调用方 API Key 资源,请更新它的允许列表,使其包含 chat-prod

为了验证自托管配置,创建一个只能调用 chat-prod 的调用方 API Key:

export AISIX_API_KEY="sk-routing-demo"

AISIX_API_KEY_HASH=$(printf '%s' "${AISIX_API_KEY}" | shasum -a 256 | awk '{print $1}')

curl -sS -X POST "http://127.0.0.1:3001/admin/v1/apikeys" \
-H "Authorization: Bearer ${AISIX_ADMIN_KEY}" \
-H "Content-Type: application/json" \
-d '{
"key_hash": "'"${AISIX_API_KEY_HASH}"'",
"allowed_models": ["'"${ROUTING_MODEL}"'"]
}'

你应该会看到类似下面的响应:

{
"id": "9b7f01fd-5f26-4657-82ef-605cc2f0ce21",
"value": {
"key_hash": "dd08e1fdcc327a5f15dedfba33172b5412b887d9d12ffc1076f77683b1ddbe3e",
"allowed_models": [
"chat-prod"
]
},
"revision": 1
}

如果后续需要更新、轮换或删除该调用方 API Key,请复制高亮的 id

验证路由

向多目标别名发送请求:

curl -sSi -X POST "http://127.0.0.1:3000/v1/chat/completions" \
-H "Authorization: Bearer ${AISIX_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"model": "'"${ROUTING_MODEL}"'",
"messages": [
{"role": "user", "content": "Hello from AISIX routing."}
]
}'

成功请求会返回类似下面的响应:

HTTP/1.1 200 OK
content-type: application/json
x-aisix-call-id: ***
x-aisix-served-by: gpt-4o-primary
server: AISIX/0.1.0

{
"id": "chatcmpl-***",
"object": "chat.completion",
"created": **********,
"model": "chat-prod",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "Hello! How can I assist you today with AISIX routing?"
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 13,
"completion_tokens": 13,
"total_tokens": 26
}
}

响应体会保留面向调用方的模型别名。x-aisix-served-by 响应头会显示具体由哪个目标模型处理了请求。

当需要确认某次路由请求由哪个目标处理时,可以使用该响应头。缓存命中、单目标模型响应、错误响应或部分端点族可能不会包含该响应头。

流式请求可以解析多目标别名,但流已经开始后不会再执行故障转移。

调整重试与运行时行为

本示例会对主目标执行一次重试,并向备用目标执行一次故障转移。

只有当流量计划需要不同行为时,才调整路由字段:

  • 如果只想选择目标而不跨目标故障转移,请设置 max_fallbacks: 0
  • 当上游限流响应也应参与重试和故障转移时,启用 retry_on_429
  • 当尝试某个目标比直接返回 503 all_candidates_unavailable 更合适时,配置 routing.on_all_filtered: "original_order"

对于流式请求,如果在第一个上游数据块返回前超时,可以故障转移到下一个目标;一旦流式字节已经开始返回,超时会结束当前流,而不会在响应中途故障转移。

使用 GET /admin/v1/models/status 查看目标模型的运行时状态。

完整的模型请求字段和响应结构,请参见 Admin API 参考

下一步

你已经配置了多目标模型,并允许调用方 API Key 使用它。继续阅读多目标模型故障转移,端到端测试故障转移。