> 原始 Markdown 孪生体（构建期从源 Markdown 生成）。渲染页：https://docs.gatellm.io/zh-CN/quickstart/multi-upstream-load-balancing · 文档索引：https://docs.gatellm.io/zh-CN/llms.txt


# 多上游负载均衡

当同一个模型有多个上游/节点可用时，负载均衡器（LoadBalancer）在它们之间分发请求，提供故障转移、权重分配和粘性会话。本章带你建两个完整案例：OpenAI 高可用（双 OpenAI + 备用）和多供应商故障转移（OpenAI + Azure）。

## 你将完成什么

- 一个 OpenAI 高可用负载均衡器 `gpt-4o-ha`（3 个节点：美区 + 欧区 + 备用）
- 或一个多供应商负载均衡器 `gpt-4o-multi`（OpenAI 主 + Azure 备）
- 密钥组的 `load_balancers` 维度放行 LB
- 客户端用 LB name 调用

## 前置

- 网关已运行（`http://localhost:7890`），能登录控制台
- 已设 `ENCRYPTION_KEY`——下面要保存的上游 API key 与访问密钥都落库前加密，没设会在保存时报 `encryption_key not set in config`。见 [Docker 单机跑通 → 前置](/zh-CN/quickstart/docker-single-node.md#prereq)
- 多把上游 API key——同一供应商的**多个不同账号**（如多把 OpenAI key），或不同供应商（OpenAI + Azure OpenAI 等）。OpenAI 不提供区域子域，所谓多区域其实是多账号，见[案例 A](#case-a-openai-ha)的警示

## 核心概念 {#core-concepts}

> （原文此处为负载均衡概念图，详见上方来源链接对应的渲染页。）

- **LoadBalancer 本身就是一个"模型名"**：客户端用 LB 的 `name`（如 `gpt-4o-ha`）调用，跟调用普通模型一样
- **entries**：LB 下的节点列表，每个指向一个上游+模型的组合
- **weight**：权重越高分配越多请求；`weight=0` 为备用节点，仅在正常节点全部不可用时启用

## 案例 A：OpenAI 高可用 {#case-a-openai-ha}

**场景**：两个 OpenAI 上游（美区+欧区），加一个备用上游，实现故障自动转移。

### 1. 建 3 个上游

控制台 → **上游服务** → 新建，分别建：

> ⚠️ OpenAI **不提供区域子域**——`api-eu.openai.com`、`api-backup.openai.com` 这类地址**不存在**，照抄会 DNS 失败。下面三个上游用**同一 OpenAI 端点、不同账号（组织）的 API key** 实现多账号高可用与故障转移；名称里的 `us`/`eu` 仅作区分，不对应真实地理区域。跨供应商容灾见[案例 B](#case-b-multi-vendor-failover)。

| 名称 | 协议 | 基础 URL |
|------|------|---------|
| `openai-us` | `openai` | `https://api.openai.com/v1` |
| `openai-eu` | `openai` | `https://api.openai.com/v1` |
| `openai-backup` | `openai` | `https://api.openai.com/v1` |

每个上游填各自账号的 API key。三个上游端点相同、凭据独立，网关在它们之间按权重分发、故障转移。

### 2. 各上游下建模型 gpt-4o

在每个上游下展开 → 模型子表 → 新建模型 `gpt-4o`，上游模型 ID 都填 `gpt-4o`。

### 3. 建负载均衡器

控制台 → **负载均衡器** → **新建**，填：

| 字段 | 值 | 说明 |
|------|-----|------|
| 名称 | `gpt-4o-ha` | 客户端调用时用的模型名 |
| 出错换节点 | ✓ | `retry_on_different_node`，故障自动转移 |
| 粘性会话 | ✗（取消勾选） | 演示加权分发需先关掉，见下方说明 |

**条目**区点 **+ 添加条目**，逐行填（上游、模型为下拉选，权重 0–255）：

| 上游 | 模型 | 权重 |
|------|------|------|
| `openai-us` | `gpt-4o` | `5` |
| `openai-eu` | `gpt-4o` | `3` |
| `openai-backup` | `gpt-4o` | `0`（备用） |

> ℹ️ 这里关掉粘性会话是为了演示**按 5:3 权重分发**：粘性会话默认开启（同一客户端粘同一节点），开启时权重比例不会逐请求体现。要演示加权分发就关掉它。粘性会话细节见[开启粘性会话](/zh-CN/howto/enable-sticky-session.md)。

保存。

<details>
<summary>等价 JSON（经 Console API 配置时用）</summary>

```json
{
  "name": "gpt-4o-ha",
  "entries": [
    {"upstream": "openai-us", "model": "gpt-4o", "weight": 5},
    {"upstream": "openai-eu", "model": "gpt-4o", "weight": 3},
    {"upstream": "openai-backup", "model": "gpt-4o", "weight": 0}
  ],
  "retry_on_different_node": true,
  "extra_config": { "sticky_session_enabled": false }
}
```

</details>

### 4. 配密钥组放行 LB

控制台 → **访问密钥** → **密钥组** → 找到目标密钥组（如 `default`）→ 编辑 → 「负载均衡器」子页签 → 勾选 `gpt-4o-ha`（或 `*`）。等价 JSON：

```json
{
  "name": "default",
  "models": ["*"],
  "load_balancers": ["gpt-4o-ha"]
}
```

> 「所有模型」**不**附带负载均衡器权限，反之亦然——两个维度要分别勾选。

### 5. 客户端用 LB name 调用

```bash
curl http://localhost:7890/v1/chat/completions \
  -H "Authorization: Bearer <你的访问密钥>" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-4o-ha",
    "messages": [{"role":"user","content":"hi"}]
  }'
```

网关按 5:3 权重在 `openai-us` / `openai-eu` 间分发请求。某节点故障时自动重试到其他节点（`retry_on_different_node=true`，受 `MAX_UPSTREAM_RETRIES` 控制）。所有正常节点不可用时启用备用节点 `openai-backup`（weight=0）。

## 案例 B：多供应商故障转移 {#case-b-multi-vendor-failover}

**场景**：主用 OpenAI，备用 Azure OpenAI，实现供应商级容灾。

### 1. 建上游

| 名称 | 协议 | 基础 URL |
|------|------|---------|
| `openai` | `openai` | `https://api.openai.com/v1` |
| `azure-openai` | `openai` | `https://{resource}.openai.azure.com/openai/v1` |

### 2. 各上游下建模型

- `openai` 下建模型 `gpt-4o`，上游模型 ID `gpt-4o`
- `azure-openai` 下建模型 `gpt-4o-deploy`，上游模型 ID 用 Azure 部署名

### 3. 建负载均衡器

控制台 → **负载均衡器** → **新建**，名称填 `gpt-4o-multi`、勾选「出错换节点」，条目区逐行添加。等价 JSON：

```json
{
  "name": "gpt-4o-multi",
  "entries": [
    {"upstream": "openai", "model": "gpt-4o", "weight": 10},
    {"upstream": "azure-openai", "model": "gpt-4o-deploy", "weight": 5}
  ],
  "retry_on_different_node": true
}
```

### 4. 密钥组放行 + 客户端调用

同案例 A 第 4-5 步，把 LB name 换成 `gpt-4o-multi`。

## 故障转移行为

当 `retry_on_different_node = true`（默认）时：

1. 请求发到当前选中节点
2. 节点返回可重试错误（5xx、连接超时、读取超时）
3. 网关自动选下一个节点重试
4. 重试次数受 `MAX_UPSTREAM_RETRIES` 控制

当所有节点都不可用时，网关在重试预算耗尽后返回 503，响应携带最后一次错误。

> **流式响应限制**：流式重试仅在发送第一个 SSE 数据块之前尝试。一旦客户端开始接收数据，不支持中途换节点。

## 常见问题

**Q：LB 的 name 和普通模型的 name 冲突了怎么办？**
LB 和普通模型共享全局唯一名称空间。不能有同名的 LB 和模型。

**Q：客户端报 403？**
密钥组的 `load_balancers` 列表没包含 LB name。检查「负载均衡器」子页签是否勾选。

**Q：客户端报 503 持续不停？**
所有节点都不可用。检查每个上游的 `base_url` 和 API key。若上游确实全挂，网关在重试预算耗尽后返回 503。

**Q：怎么开粘性会话（同一客户端持续路由到同一节点）？**
见 [开启粘性会话](/zh-CN/howto/enable-sticky-session.md)。

**Q：怎么监控各节点健康状态？**
控制台 → 负载均衡器 → 点该 LB → Entries 面板，看每个节点的状态（healthy/unavailable）与有效权重（等于配置权重）。

**下一步**：[创建负载均衡器](/zh-CN/howto/setup-load-balancer.md) 看完整字段表与操作步骤；[负载均衡字段](/zh-CN/reference/load-balancing-fields.md) 看完整字段表与重试配置；[访问密钥与密钥组字段](/zh-CN/reference/access-keys-groups-fields.md) 看密钥组的负载均衡器维度。
