☰
LiteLLM网关部署实战:多模型管理、负载均衡与密钥管控
2026/10/9 12:37:48 网站建设 项目流程

最近在给团队搭企业内部的模型服务平台,对比了市面上几个方案后,最终锁定了 LiteLLM 作为多模型 API 网关。这一周从零开始部署,踩了不少坑,也把负载均衡、密钥管理、故障排查这几个核心模块彻底摸了一遍。LiteLLM 本质上是一个开源的模型代理网关,能把 OpenAI、Anthropic、Azure 以及本地部署的大语言模型统一收敛成一套 OpenAI 兼容 API,同时把负载均衡、限流、预算控制、虚拟密钥这些脏活累活全部接过去。如果你正在做企业大模型私有化部署,或者想把本地部署的 Ollama 服务暴露给多个业务方,这篇文章可以直接照着操作。

1. 先搞清楚:多模型网关到底解决了什么问题

1.1 业务痛点:散装的模型接口

做模型平台的第一件事不是写代码,而是盘点现状。多数企业里都会同时混用多个模型供应商:OpenAI 的 GPT 系列、Azure 上的模型、Anthropic 的 Claude,还有自建的 Ollama、vLLM 推理服务。每个供应商的 API 协议不一样,鉴权方式不一样,限流阈值不一样,模型命名规则更是各搞一套。业务方的后端如果直接对接这些上游,代码里全是一个个 if-else,换一个模型要改业务代码,加一个供应商又要重新联调。

这还不是最痛苦的。等业务接入多了之后,你会发现自己其实是在维护一套自研适配层,既要解析各家返回格式,又要统一错误码,还要做重试和超时。这套自研代码写到第三个月,基本就会变成一个谁都不敢动的定时炸弹。

LiteLLM 的核心价值就是把上面的脏活直接接管。它对外提供的是 OpenAI 兼容接口,业务方不需要感知背后接的是谁,只需要按 OpenAI 的规范发请求,剩下的路由、鉴权、限流、失败转移全部由网关处理。这样一来,业务侧的需求从"对接十个模型供应商"降级为"对接一个 API",平台的模型切换也不再需要业务方发版。

1.2 负载均衡在模型网关里承担的角色

很多方案嘴上说负载均衡,实际只是在 Nginx 里做了个简单的轮询。模型网关层面的负载均衡要复杂得多,因为上游模型服务有真实的成本差异、延迟差异和可用性差异。

具体要处理的几个问题:

  • 同一个模型部署在多个后端时,如何把请求分发到当前最合适的实例。比如一个模型同时接 Azure OpenAI 和本地 vLLM,分发策略不能只看"活没活",还得看当前排队长度和延迟。
  • 某个上游出现故障或超时时,如何在不影响调用方的情况下自动切到备选实例。这在业务高峰期尤其关键,一个供应商限流,不能把整个请求都打挂。
  • 不同模型之间还要能做路由和降级。比如主模型超预算了,静态降级到便宜的模型;或者主模型延迟过高,动态把一部分流量切走。

所以它更像是一个中央调度室,而不是简单的流量分发器。这也是我为什么没有直接拿 Nginx 做转发的原因。LiteLLM 能感知上游状态,能制定路由策略,能自动执行 failover,这些能力在 Nginx 里都很难原生实现。

1.3 本教程的部署目标与适用人群

这篇教程的目标是带你从零搭建一个可用的 LiteLLM 网关,最终形成这样一个运行结构:业务客户端通过 OpenAI SDK 风格的方式请求 LiteLLM 网关,网关按照配置把流量转发到云端模型或者本地的 Ollama/vLLM 服务,并且做密钥鉴权、负载均衡和故障转移。

适合参考这篇教程的人有三类:

  • 平台 / 后端工程师,想给团队搭统一模型入口,摆脱各家 API 协议不一致的维护噩梦。
  • AI 应用开发者,希望把本地部署的大语言模型封装成 OpenAI 兼容服务,供自己的应用或团队内部系统调用。
  • 运维 / 架构师,正在做企业大模型私有化部署,需要一套可控、可审计、可限流的模型网关。

2. 部署前的准备工作与基础配置

2.1 环境准备:Docker 与本地资源评估

LiteLLM 网关本身只是控制面和转发层,它不承载模型推理,所以对硬件要求不算高。我实际在 2 核 4G 的普通云服务器上跑,网关服务的 CPU 和内存占用都很低,真正的性能瓶颈在下游模型服务。如果你要接入本地推理,比如 Ollama,那算力主要花在模型服务那台机器上,网关只管转发。

部署前需要准备:

  • Docker 20.10+ 以及 docker compose v2。Linux 服务器直接用二进制或包管理器安装 Docker,Windows 上则建议先装 Docker Desktop,并且启用 WSL2 后端,运行更顺滑。
  • 如果希望网关配置重启不丢失、支持多实例部署,还需要一个 PostgreSQL 数据库。单机测试不是必须的,但生产环境强烈建议配上。
  • 准备至少一个上游模型的 API Key,否则网关起得来也转发不了。本地模型则无所谓,用 Ollama 加载一个开源模型即可。

2.2 Docker Compose 快速启动

我推荐用 Docker Compose 方式部署,因为配置文件和依赖的 PostgreSQL 可以一起编排,环境一致性好,换机器迁移也方便。下面是一个基础配置文件,实际使用请把密钥替换成自己的。

version: "3.8" services: litellm: image: ghcr.io/berriai/litellm:main-latest container_name: litellm-proxy ports: - "4000:4000" environment: - LITELLM_MASTER_KEY=sk-litellm-main - DATABASE_URL=postgresql://litellm:password@postgres:5432/litellm volumes: - ./config.yaml:/app/config.yaml depends_on: - postgres command: ["--config", "/app/config.yaml"] postgres: image: postgres:16 container_name: litellm-postgres environment: - POSTGRES_USER=litellm - POSTGRES_PASSWORD=password - POSTGRES_DB=litellm volumes: - pgdata:/var/lib/postgresql/data volumes: pgdata:

等容器起来之后,访问http://localhost:4000应该能看到 LiteLLM 的管理界面,http://localhost:4000/health/liveliness会返回存活状态。有一点必须提醒:LITELLM_MASTER_KEY是网关的超级管理员密钥,生产环境一定不要用默认值,建议用类似openssl rand -hex 32的方式生成。

2.3 最小配置 config.yaml

网关的所有路由逻辑都在 config.yaml 里定义。先用一个最小配置跑通链路:一个云端模型和一个本地模型。

model_list: - model_name: "gpt-4o" litellm_params: model: "openai/gpt-4o" api_key: "os.environ/OPENAI_API_KEY" - model_name: "local-llama" litellm_params: model: "ollama/llama3.1:8b" api_base: "http://host.docker.internal:11434" general_settings: master_key: "os.environ/LITELLM_MASTER_KEY" database_url: "os.environ/DATABASE_URL"

这里有几个关键细节。

api_key写成os.environ/OPENAI_API_KEY表示从环境变量读取,不要把真实的 key 明文写进配置文件直接交给 Git。host.docker.internal是容器内访问宿主机地址的惯用方式,如果你在 Windows 上用 Docker Desktop,或者 Linux 上没有额外配置,这个写法通常都能正常工作。如果 Ollama 也以容器方式运行,并且和 LiteLLM 在同一个 Docker 网络里,那api_base可以改成http://ollama:11434直接用服务名互联。

启动后最简单的验证命令:

curl http://localhost:4000/v1/chat/completions \ -H "Authorization: Bearer sk-litellm-main" \ -H "Content-Type: application/json" \ -d '{"model": "gpt-4o", "messages": [{"role": "user", "content": "hello"}]}'

网关默认监听 4000 端口,OpenAI SDK 的 base_url 也指向http://localhost:4000。这一步跑通,基础链路就建立了。

3. 负载均衡与路由策略的配置实操

3.1 同一模型接入多个后端实例

LiteLLM 做负载均衡的思路很直接:在model_list里把多个后端配置成同一个对外模型名,网关会根据路由策略挑选实际处理请求的后端。举例来说,对外统一暴露gpt-4o,但实际请求会分发到 Azure OpenAI 和 OpenAI 两个上游:

model_list: - model_name: "gpt-4o" litellm_params: model: "openai/gpt-4o" api_key: "os.environ/OPENAI_API_KEY" - model_name: "gpt-4o" litellm_params: model: "azure/gpt-4o" api_key: "os.environ/AZURE_API_KEY" api_base: "https://your-resource.openai.azure.com/" api_version: "2024-06-01" router_settings: routing_strategy: "latency-based-routing"

model_name是同一个,代表业务方看到的逻辑模型名;litellm_params则分别指向真实的上游配置。请求进入后,网关会根据routing_strategy决定的策略选择一个合适的后端转发。

几种常见路由策略各有侧重:

策略工作方式适用场景
simple-shuffle随机混洗分发后端能力基本一致,只需要均匀分流
least-busy选择当前在途请求最少的上游上游推理能力差异大,排队严重的场景
usage-based-routing结合预算和配额选择上游需要优先用低成本/低保费的供应商
latency-based-routing选择历史延迟更低的上游对响应延迟敏感的在线业务

我在实际项目里最常用的是latency-based-routing,因为同样的模型在不同供应商那里的负载情况是动态的,长期固定权重并不科学。但如果你接的是本地多个推理服务,建议用least-busy更直观。

3.2 健康检查、冷却与故障降级

负载均衡的基础前提是网关能判断哪个上游是健康的。LiteLLM 会对配置的每个上游定期做健康探测,探测失败的节点会被暂时标记为不健康,不再分配新请求,等恢复后再重新加入池子。

在 router_settings 里有几个参数可以调节这个行为:

router_settings: routing_strategy: "least-busy" cooldown_time: 30 allowed_fails: 3 num_batch_requests: 100

allowed_fails表示连续几次失败后把节点拉入冷却期,cooldown_time是冷却时长,单位是秒。生产环境里我一般把allowed_fails设在 2 到 3,冷却时间 30 到 60 秒,既能及时摘除故障节点,又不会因为一两次抖动就过度敏感。

如果所有上游都挂了,网关还应该能提供一个兜底方案。这就是 fallback 机制。简单说,当主模型失败时,网关可以尝试切换到另一个完全不同的模型。比如主模型是 gpt-4o,故障时可以降级到 local-llama 或更便宜的模型,业务方拿到的还是正常响应,只是质量或速度有差异。fallback 的具体字段在不同版本略有变化,使用时以对应版本的官方文档为准,思路就是给主模型配置一个或多个替补模型。

我在生产中遇到过几次供应商限流导致的抖动,fallback 配好之后,业务几乎无感。

3.3 管理 API 和指标观测

负载均衡配好之后不能不管,还需要观测手段。LiteLLM 提供了管理 API 和 Prometheus 指标端点。

  • /health/endpoints可以查看每个上游的存活状态、最近失败次数、冷却状态。
  • /metrics是 Prometheus 格式的指标,可以接入 Grafana,看每个模型的请求量、失败率、延迟分布。
  • 管理界面上也能直接看到总请求数、模型列表和密钥列表。

没有观测的负载均衡等于盲操作。建议一上来就把 /metrics 接入现有的监控体系,至少盯三个指标:请求总量、5xx 比例、P95 延迟。谁在拖慢整体响应、哪个供应商的故障四起、哪个 key 在疯狂消费预算,都能第一时间看到。

4. 密钥管理的正确姿势

4.1 真实密钥与虚拟密钥分离

模型网关接入的是多个供应商的真实 API Key,但真正下发到业务方向的是一个 LiteLLM 生成的虚拟密钥。两者必须严格分离。

供应商的真实密钥应该只在配置文件或环境变量中出现,用来让网关访问上游。业务方拿到的虚拟 key 是网关自己签发的,可以精确控制这个 key 能访问哪些模型、最多花多少钱、什么时候过期。这样做的好处很明显:不用因为一个业务方的 key 泄露就轮换供应商的真实密钥,而且可以给不同的业务线发不同的 key 单独计费限流。

生成虚拟 key 的接口是/key/generate:

curl -X POST "http://localhost:4000/key/generate" \ -H "Authorization: Bearer sk-litellm-main" \ -H "Content-Type: application/json" \ -d '{ "models": ["gpt-4o", "local-llama"], "max_budget": 20, "expires": "2026-12-31T23:59:59Z" }'

返回结果里包含一个新的api_key,这个 key 就是给业务方用的。max_budget控制总预算,expires控制有效期,models限制可访问的模型范围。返回的 key 只会完整显示一次,需要立即保存,这点要提前和业务方说清楚。

4.2 密钥持久化:为什么必须上数据库

如果你只在本地起 LiteLLM 玩玩,不配置数据库也能运行,但一旦重启,创建的虚拟 key、预算信息、访问日志可能全部丢失。生产环境必须配置 PostgreSQL,把密钥、预算、路由配置的持久化都存进去。

前面 docker-compose 里已经带了 Postgres,config.yaml 里也已经配置了database_url。当虚拟 key 生成后,它会写入数据库;网关重启后,这些 key 依然有效。这也为后续多实例部署打好了基础,多个 LiteLLM 实例共享同一个数据库,任何一台机器都能校验同一个虚拟 key。

数据库到了生产规模还要注意备份和访问控制。至少要做到:数据库不暴露公网,只允许网关容器访问;定期备份数据库,尤其是密钥表和预算表。我见过有团队把数据库整个删了,所有业务方 key 全部失效,只能紧急重新发 key,这个事故一旦发生相当狼狈。

4.3 权限层级与密钥轮换

LiteLLM 的密钥体系不只是"一个 key 走天下",它可以按 user / team 维度管理。比如给算法团队建一个 team,给数据平台建另一个 team,每个 team 的模型白名单、预算上限都不同;再给不同用户发独立 key,方便审计某一个具体用户或业务系统的调用量。

密钥轮换也是规避长期风险的必要操作。轮换流程建议这样走:

  1. 先调用/key/generate生成新 key,发放给业务方。
  2. 业务方完成切换后,用/key/delete把旧 key 删除。
  3. 如果真实供应商的 key 不幸泄露,需要在环境变量里替换,并重启网关使新值生效。

有几点血泪教训值得单独说。一是不要把真实 key 提交到 Git 仓库,尤其是公开仓库,泄露之后很难追溯是谁拿走的;二是不要图省事在日志里直接打印 request headers,这样会把虚拟 key 打印到日志系统里,等于把钥匙挂在了门口;三是虚拟 key 的预算不要设置成"无穷大",哪怕内部系统也建议设个数字,防止某个业务方代码出问题后疯狂调用把月度预算烧光。

5. 上线后的故障排查与调优实录

5.1 高频故障的极速排查

网关部署起来之后,真实世界的问题千奇百怪。我把这段时间遇到的高频故障整理成一张速查表,遇到问题可以按表排查。

现象排查方向常用手段
401 Invalid API Key请求头里的 key 错误或已过期检查 Authorization 头,确认用的是虚拟 key 而非 master key
429 Too Many Requests触发了限流或虚拟 key 预算超限检查/key/info查看 budget 使用情况
404 Model Not Found配置的模型名在 model_list 里不存在检查 config.yaml 中 model_name 是否匹配
500 / 502 上游错误上游模型服务返回异常看/logs或容器 stdout 中的具体错误堆栈
请求超时本地模型推理太慢或上游网络问题调大timeout参数,或检查上游队列长度

碰到问题不要先去翻源码,第一动作永远是打开/logs或容器日志。LiteLLM 的日志里会明明白白写出请求走到哪个上游、上游返回了什么、失败在哪一步。把日志定位到了,问题基本就解决了一半。

5.2 本地模型接入的常见坑

本地模型接入是出问题最多的地方,尤其是 Ollama 和 vLLM 的组合场景。

最常见的问题有两个。第一个是api_base写成了http://localhost:11434。这个写法在宿主机上直接跑 LiteLLM 没问题,但从容器内访问宿主机时,localhost指向的是容器自己,根本连不到宿主机上的 Ollama。解决方案是用http://host.docker.internal:11434,或者把 Ollama 也容器化并纳入同一个 Docker 网络。

第二个问题是模型名匹配不上。Ollama 里拉取的是llama3.1:8b,请求时如果只写llama3.1,或者加了不存在的 tag,上游会直接 404。配置model字段时,建议先本地ollama list看一眼真实的名称,再填到配置里。

如果你用的是 vLLM 启动的推理服务,还要额外注意api_base的路径。vLLM 的 OpenAI 兼容端点一般默认在/v1下,比如http://your-host:8000/v1,拼错路径会出现一连串 404。

5.3 性能调优三件套:超时、重试、缓存

网关稳定之后,下一步就是调性能。我实际优化时主要动三个地方。

第一个是请求超时。模型推理比普通接口慢得多,本地小模型可能要几秒,大模型长文本生成甚至要几十秒。默认超时时间经常不够用,建议针对模型类型单独设置,在线对话模型可以放宽到 60 到 120 秒。

第二个是重试策略。网关在遇到上游瞬时错误时,可以自动重试一次,但不能无限重试,否则会把下游打爆。通常设置 1 到 2 次重试即可,配合健康检查和冷却机制,比盲目重试效果好得多。

第三个是缓存。LiteLLM 支持把相同请求的响应缓存起来,尤其是企业内部常见的问题固定、答案固定,缓存命中后延迟直接从秒级降到毫秒级。缓存可以放在内存里,也可以使用 Redis,生产环境建议用 Redis,多个网关实例可以共享同一份缓存。

5.4 Windows 与 Linux 部署的实际差异

很多本地开发者用 Windows 做测试,生产服务器则是 Linux,这里面的差异值得说几句。

Windows 上首推 Docker Desktop。启用 WSL2 之后,host.docker.internal可以正常使用,GPU 卡如果型号支持,也可以通过 WSL 内的 Docker 直接透传给本地推理服务。但 Windows 容器和 Linux 容器底层不同,镜像兼容性会有差异,建议统一使用 Linux 容器模式。

生产环境的 Linux 服务器部署反而更平滑。没有 Docker Desktop 那层的性能损耗,也不需要什么特殊网络配置,唯一要额外处理的是 GPU 透传。如果你想在 GPU 机器上用容器跑 Ollama 或 vLLM,需要在宿主机安装 NVIDIA Container Toolkit,并且在 compose 文件里声明 GPU 资源。这一步在 Windows 上相对麻烦,Linux 下错误信息更直接,按官方文档操作一般不会卡住。

还有一个容易被忽略的点:文件路径。Windows 下的./config.yaml挂载路径在 Linux 下是完全一样的语法,但如果你用了反斜杠或者 Windows 特有盘符路径,到 Linux 上就全废了。compose 文件里的路径尽量用相对路径,保证跨平台一致。

5.5 日志与监控的落地习惯

最后说一点习惯层面的建议。

网关日志的详细级别要按环境区分。开发环境可以开--detailed_debug,把每个请求的完整链路都打出来;生产环境则要收敛,否则日志量会非常吓人,反而把关键信息淹没。生产环境建议只保留 access log 和 error log,配合 Prometheus 指标做趋势分析。

我还会在网关前面加一层 Nginx 或者云负载均衡器,作用有两个:一是提供统一的 HTTPS 入口,二是做基础的流量清洗和 IP 白名单。LiteLLM 本身已经有鉴权能力,但 Nginx 做最外层的 TLS 终结和简单的限流,能够把网关的压力进一步降低。这个组合我用到现在非常稳,业务方只关心 HTTPS 地址,不用关心网关如何演进。

写在最后

到目前为止,LiteLLM 网关已经在内部稳定运行了一段时间。我个人的体会是,第一次搭建不用追求一步到位,先把单体网关心态摆正:一个模型能跑通,再加上第二个模型,然后才逐步加负载均衡、密钥管理和监控。把最小闭环跑出来之后,后面的每个能力都是按需叠加的,出问题也容易定位。

最后再分享一个小技巧。配置网关的时候,尽量把 config.yaml 看成代码来管理,每次改动都走 Git 提交,不要在生产机器上手动改文件。模型变更、路由策略调整、密钥轮换,这些操作都要有迹可循。你会发现,模型网关稳定运行之后,最大的收益不是省了几个适配层的开发量,而是业务方再也不用关心"到底该接哪家模型"这个问题了。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询