AI 应用的性能优化与监控怎么做?从响应速度到资源管理
应用上线后,怎么知道它跑得好不好?慢了怎么优化?
本篇回答三个问题:
1. 性能瓶颈怎么定位?
2. 监控体系怎么搭建?
3. 常见的优化手段有哪些?
性能瓶颈怎么定位?
慢在哪?先量化
不要凭感觉优化。先用数据定位瓶颈:
# backend/app/services/monitor.py
import time
import logging
from functools import wraps
logger = logging.getLogger(__name__)
def timed(logger=None):
"""函数耗时统计装饰器。"""
def decorator(func):
@wraps(func)
async def wrapper(*args, **kwargs):
start = time.time()
try:
result = await func(*args, **kwargs)
return result
finally:
elapsed = time.time() - start
if elapsed > 0.5: # 超过 500ms 记录慢请求
log = logger or logging.getLogger(func.__module__)
log.warning(f"Slow call: {func.__name__} took {elapsed:.2f}s")
return wrapper
return decorator
慢查询追踪
数据库查询是最常见的瓶颈。用 SQLAlchemy 的日志定位慢查询:
# backend/app/database.py
import logging
logging.getLogger("sqlalchemy.engine").setLevel(logging.WARNING)
# 只记录超过 1 秒的查询
import time
from sqlalchemy import event
from sqlalchemy.engine import Engine
@event.listens_for(Engine, "before_cursor_execute")
def before_cursor(conn, cursor, statement, parameters, context, executemany):
conn.info["query_start"] = time.time()
@event.listens_for(Engine, "after_cursor_execute")
def after_cursor(conn, cursor, statement, parameters, context, executemany):
total = time.time() - conn.info["query_start"]
if total > 1:
logging.getLogger("slow_query").warning(f"Slow query ({total:.2f}s): {statement[:200]}")
监控体系怎么搭建?
关键指标
API 层面:
├─ 请求延迟:P50, P95, P99
├─ 请求量:QPS(每秒查询数)
└─ 错误率:5xx 比例
AI 层面:
├─ LLM 调用延迟
├─ Token 消耗量
└─ 向量检索延迟
系统层面:
├─ CPU/内存/GPU 使用率
├─ 磁盘 IO
└─ 网络带宽
用 Prometheus + Grafana 搭建监控
# backend/app/services/metrics.py
from prometheus_client import Counter, Histogram, Gauge, generate_latest
from fastapi import Response
import time
# 定义指标
LLM_LATENCY = Histogram("llm_request_duration_seconds", "LLM API call latency", buckets=(0.1, 0.5, 1.0, 2.0, 5.0, 10.0))
LLM_TOKENS = Counter("llm_tokens_total", "Total tokens consumed", ["model"])
API_REQUESTS = Counter("api_requests_total", "Total API requests", ["method", "endpoint", "status"])
API_LATENCY = Histogram("api_request_duration_seconds", "API request latency")
@app.get("/metrics")
async def metrics():
"""Prometheus 指标接口。"""
return Response(generate_latest(), media_type="text/plain")
LLM 延迟监控采集
在 LLM 调用处加上监控:
from app.services.metrics import LLM_LATENCY, LLM_TOKENS
with LLM_LATENCY.time():
response = await client.chat.completions.create(...)
LLM_TOKENS.labels(model="deepseek-chat").inc(response.usage.total_tokens)
健康检查接口
@app.get("/api/health")
async def health_check():
"""健康检查:返回各依赖服务状态。"""
import redis
status = {"app": "ok", "database": "unknown", "redis": "unknown"}
# 检查数据库
try:
with models.get_db() as conn:
conn.execute("SELECT 1")
status["database"] = "ok"
except Exception:
status["database"] = "error"
# 检查 Redis
try:
r = redis.from_url(settings.REDIS_URL)
r.ping()
status["redis"] = "ok"
except Exception:
status["redis"] = "error"
overall = "ok" if all(v == "ok" for v in status.values()) else "degraded"
return {"status": overall, "checks": status}
Docker 容器监控
# 查看容器资源使用
docker stats
# 查看特定容器日志
docker logs --tail 50 --follow know-backend
# 容器级别监控(CPU/内存)
docker stats know-backend --no-stream --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}"
常见的优化手段有哪些?
1. 数据库查询优化
# ❌ 慢:N+1 查询
for kb in knowledge_bases:
docs = await db.execute(select(Document).where(Document.knowledge_base_id == kb.id))
# ✅ 快:批量查询
# 用 JOIN 一次查出
result = await db.execute(
select(KnowledgeBase, Document).join(Document).where(...)
)
2. LLM 调用缓存
# backend/app/services/cache.py
import hashlib
import json
from app.config import settings
def llm_cache_key(messages: list) -> str:
"""生成 LLM 调用的缓存 key。"""
content = json.dumps(messages, ensure_ascii=False, sort_keys=True)
return f"llm:{hashlib.md5(content.encode()).hexdigest()}"
async def get_cached_llm(messages: list, ttl: int = 3600):
"""带缓存的 LLM 调用。"""
import redis
r = redis.from_url(settings.REDIS_URL)
key = llm_cache_key(messages)
# 查缓存
cached = r.get(key)
if cached:
return cached.decode()
# 调用 LLM
result = await call_llm(messages)
# 写入缓存
r.setex(key, ttl, result)
return result
3. 静态文件缓存
Nginx 配置中已经做了:
location /static/ {
expires 7d;
add_header Cache-Control "public, immutable";
}
4. 数据库连接池
# SQLAlchemy 连接池配置
engine = create_async_engine(
settings.DATABASE_URL,
pool_size=10, # 连接池大小
max_overflow=20, # 最大溢出连接数
pool_pre_ping=True, # 使用前检查连接是否有效
pool_recycle=3600, # 1 小时后回收连接
)
5. 前端资源优化
// Vite 配置已包含:
// - 代码分割(Code Splitting)
// - Tree Shaking
// - CSS 压缩
// - 图片压缩
// 额外的优化:组件懒加载
const KnowledgeBaseDetail = lazy(() => import("./pages/KnowledgeBaseDetail"));
优化 checklist
□ 数据库查询是否有 N+1 问题?
□ 慢查询是否加了索引?
□ LLM 响应是否做了缓存?
□ 静态资源是否设置了缓存头?
□ 数据库连接池是否配置了合理大小?
□ 是否有健康检查接口?
□ 容器资源限制是否设置?
□ 关键路径是否加了耗时监控?
□ 是否有错误告警?
总结
性能优化和监控的关键:
| 方向 | 做什么 | 效果 |
|---|---|---|
| 定位瓶颈 | 慢查询追踪 + 耗时统计 | 知道慢在哪 |
| LLM 缓存 | 缓存相同请求的结果 | 减少 50-80% 的 LLM 调用 |
| 数据库优化 | 索引 + JOIN 替代 N+1 | 查询速度提升 10-100x |
| 健康检查 | 定期检测服务状态 | 及时发现故障 |
| Prometheus | 指标采集 + Grafana 可视化 | 实时了解系统状态 |
本文是 《AI 全栈开发实战——做一个真正的产品》 系列的第 12 篇。
本文由 Zyentor(智元界) 原创发布