CatLove Cloud 技术团队16 分钟阅读

LiteLLM 代理部署实战:从入门到放弃再到成功

记录我们团队部署 LiteLLM 代理服务的完整过程,包括踩过的坑、解决方案和性能优化经验。真实案例,绝非理论。

#LiteLLM#AI代理#部署#性能优化#实战

LiteLLM 代理部署实战:从入门到放弃再到成功

写在前面

说实话,刚开始研究 LiteLLM 的时候我们也挺懵的。市面上的 AI 代理工具一大堆,为什么选它?这篇文章不是那种"XXX 完全指南"的官方文档复述,而是我们团队实际踩坑、调试、优化的完整记录。

时间线: 2024年9月到11月,大概两个月 团队规模: 3个后端 + 1个运维 最终结果: 生产环境稳定运行,QPS 300+,P99 延迟 < 200ms

为什么选择 LiteLLM?

一开始我们考虑了三个方案:

  1. 直接调用各家 API - 代码太乱,每个模型的接口都不一样
  2. One API - 国人开发,文档不错,但更新有点慢
  3. LiteLLM - Python 生态,文档齐全,社区活跃

最终选 LiteLLM 主要是因为两点:

  • 支持 100+ 模型(OpenAI、Claude、Gemini、国内大模型都有)
  • 统一的 OpenAI 格式,前端代码不用改

但是!选了之后发现坑也不少。

第一个坑:Docker 部署失败

官方文档说得很简单:

docker run -p 4000:4000 ghcr.io/berriai/litellm:latest

结果我们的服务器上死活起不来。报错信息:

Error: Cannot connect to proxy database
ConnectionError: connection to server failed

找了半天原因,发现是 Docker 网络配置问题。我们的服务器在国内,拉镜像本来就慢,而且默认的数据库连接假设你在 localhost,实际上 Docker 容器根本访问不到。

解决方案:用 docker-compose,自己配网络

version: '3.8'
services:
  litellm:
    image: ghcr.io/berriai/litellm:main-latest
    ports:
      - '4000:4000'
    environment:
      - DATABASE_URL=postgresql://user:pass@postgres:5432/litellm
      - LITELLM_MASTER_KEY=sk-your-secret-key-here
    networks:
      - litellm-network
    depends_on:
      - postgres

  postgres:
    image: postgres:15-alpine
    environment:
      - POSTGRES_DB=litellm
      - POSTGRES_USER=user
      - POSTGRES_PASSWORD=pass
    volumes:
      - postgres-data:/var/lib/postgresql/data
    networks:
      - litellm-network

networks:
  litellm-network:
    driver: bridge

volumes:
  postgres-data:

教训:官方文档的 Quick Start 只适合本地测试,生产环境一定要自己配数据库。

配置文件的学问

LiteLLM 的配置文件 config.yaml 看起来简单,实际上细节很多。我们一开始用的配置:

model_list:
  - model_name: gpt-4
    litellm_params:
      model: openai/gpt-4
      api_key: os.environ/OPENAI_API_KEY

结果所有请求都超时。为什么?因为我们在国内,OpenAI 的 API 根本访问不了

后来改成:

model_list:
  # 使用代理访问 OpenAI
  - model_name: gpt-4
    litellm_params:
      model: openai/gpt-4
      api_key: os.environ/OPENAI_API_KEY
      api_base: https://api.openai-proxy.com/v1 # 自建代理
      timeout: 300 # 加大超时时间

  # 备用模型:Claude
  - model_name: gpt-4
    litellm_params:
      model: anthropic/claude-3-opus-20240229
      api_key: os.environ/ANTHROPIC_API_KEY

  # 国内模型:智谱
  - model_name: chatglm
    litellm_params:
      model: chatglm-pro
      api_key: os.environ/ZHIPU_API_KEY
      api_base: https://open.bigmodel.cn/api/paas/v4

router_settings:
  routing_strategy: latency-based-routing # 基于延迟的路由
  num_retries: 2
  timeout: 60
  fallbacks: [{gpt-4: [chatglm]}] # GPT-4 失败时自动切换

关键配置解释

  1. fallbacks - 这个救了我们。OpenAI 不稳定时自动切换到国内模型
  2. routing_strategy - 一开始用的 simple-shuffle,后来发现 latency-based-routing 更靠谱
  3. timeout - 默认 30 秒太短,大模型有时候真的需要更久

性能测试:意外的发现

配置好之后我们做了压测,用的 wrk:

wrk -t12 -c400 -d30s \
  -s post.lua \
  http://localhost:4000/v1/chat/completions

第一次测试结果让我们震惊:

| 指标 | 数值 | |------|------| | QPS | 47 | | P50 延迟 | 1.2s | | P99 延迟 | 8.5s | | 错误率 | 12% |

这也太慢了吧?我们的目标是 QPS 200+,延迟<500ms。

排查过程花了整整一周。最后发现三个问题:

问题1:数据库连接池不够

默认配置的数据库连接数太少,改成:

general_settings:
  database_type: postgres
  database_connection_pool_limit: 100 # 原来是10
  database_connection_timeout: 60

效果:QPS 从 47 → 120

问题2:没开缓存

LiteLLM 支持 Redis 缓存,但默认不开。加上:

cache:
  type: redis
  host: redis
  port: 6379
  ttl: 600 # 10分钟缓存

效果:重复请求直接返回,延迟从 1.2s → 50ms

问题3:Python GIL 锁

这是最蛋疼的。LiteLLM 是 Python 写的,高并发下会被 GIL 锁住。

解决方案:多进程部署

# docker-compose.yml
services:
  litellm:
    deploy:
      replicas: 4 # 4个容器实例
    environment:
      - WORKERS=4 # 每个容器4个worker

配合 Nginx 做负载均衡:

upstream litellm_backend {
    least_conn;  # 最少连接算法
    server litellm_1:4000;
    server litellm_2:4000;
    server litellm_3:4000;
    server litellm_4:4000;
}

server {
    listen 80;
    location / {
        proxy_pass http://litellm_backend;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        # 流式响应support
        proxy_buffering off;
        proxy_cache off;
    }
}

最终效果

| 指标 | 优化前 | 优化后 | |------|--------|--------| | QPS | 47 | 312 | | P50 延迟 | 1.2s | 180ms | | P99 延迟 | 8.5s | 450ms | | 错误率 | 12% | 0.3% |

实际生产环境的意外

上线后第三天,凌晨2点被告警吵醒。所有请求都返回 500。

登上服务器一看,PostgreSQL 磁盘满了

原来 LiteLLM 有个日志功能,默认会把所有的请求/响应都记录到数据库。我们每天几十万请求,三天就把 20GB 磁盘吃满了。

紧急修复:

general_settings:
  disable_spend_logs: true # 关闭花费日志
  disable_master_key_return: true # 不返回key信息

然后清理数据库:

-- 只保留最近7天的日志
DELETE FROM litellm_spendlogs
WHERE created_at < NOW() - INTERVAL '7 days';

-- 设置自动清理
CREATE EXTENSION IF NOT EXISTS pg_cron;
SELECT cron.schedule('cleanup-old-logs', '0 2 * * *',
  'DELETE FROM litellm_spendlogs WHERE created_at < NOW() - INTERVAL ''7 days''');

教训:生产环境一定要监控磁盘,日志策略要合理。

监控和告警

我们用 Prometheus + Grafana 监控,LiteLLM 自带 /metrics 端点:

# prometheus.yml
scrape_configs:
  - job_name: litellm
    static_configs:
      - targets: ['litellm:4000']
    metrics_path: /metrics

关键指标:

  • litellm_requests_total - 总请求数
  • litellm_request_duration_seconds - 请求延迟
  • litellm_llm_api_failed_requests_total - 失败请求

Grafana 的告警规则:

- alert: LiteLLMHighErrorRate
  expr: rate(litellm_llm_api_failed_requests_total[5m]) > 0.05
  for: 5m
  annotations:
    summary: 'LiteLLM error rate > 5%'

- alert: LiteLLMHighLatency
  expr: histogram_quantile(0.99, litellm_request_duration_seconds_bucket) > 2
  for: 10m
  annotations:
    summary: P99 latency > 2s

成本优化:省了60%

最开始我们所有请求都走 GPT-4,一个月下来账单吓人:$8,700

后来做了智能路由:

router_settings:
  routing_strategy: cost-based-routing # 基于成本路由
  model_group_alias:
    gpt-4-cheap: # 定义便宜的gpt-4替代
      - gpt-4
      - claude-3-opus
      - chatglm-pro

业务层面:简单问题用 GPT-3.5,复杂的才用 GPT-4

结果:成本降到 $3,400,省了 60%+

总结

部署 LiteLLM 两个月,我们的体会是:

优点

  • ✅ 真的方便,100+ 模型统一接口
  • ✅ 负载均衡、重试、fallback 都有
  • ✅ 社区活跃,issue 响应快

缺点

  • ❌ Python 性能有上限,需要多实例
  • ❌ 文档有时候跟不上更新
  • ❌ 日志太多,要小心磁盘

适合场景

  • 多模型切换频繁
  • 需要 fallback 机制
  • 团队对 Python 熟悉

不适合

  • 超高并发(万级QPS)
  • 对延迟极其敏感(<50ms)
  • 团队全是前端,没人会运维

下一步

我们打算做的优化:

  1. 接入更多国产模型(Kimi、DeepSeek)
  2. 基于内容的智能路由(检测query复杂度自动选模型)
  3. 试试新出的 streaming load balancing

有问题欢迎在评论区讨论,或者直接找我们:contact@catlove.cc


本文所有配置和代码都在我们的生产环境验证过,不是纸上谈兵。

C
CatLove Cloud 技术团队
CatLove Cloud 技术团队