AI 应用的性能优化与监控怎么做?从响应速度到资源管理
应用上线后,怎么知道它跑得好不好?慢了怎么优化?
本篇回答三个问题:
- 性能瓶颈怎么定位?
- 监控体系怎么搭建?
- 常见的优化手段有哪些?
性能瓶颈怎么定位?
慢在哪?先量化
不要凭感觉优化。先用数据定位瓶颈:
# backend/app/services/monitor.pyimporttimeimportloggingfromfunctoolsimportwraps logger=logging.getLogger(__name__)deftimed(logger=None):"""函数耗时统计装饰器。"""defdecorator(func):@wraps(func)asyncdefwrapper(*args,**kwargs):start=time.time()try:result=awaitfunc(*args,**kwargs)returnresultfinally:elapsed=time.time()-startifelapsed>0.5:# 超过 500ms 记录慢请求log=loggerorlogging.getLogger(func.__module__)log.warning(f"Slow call:{func.__name__}took{elapsed:.2f}s")returnwrapperreturndecorator慢查询追踪
数据库查询是最常见的瓶颈。用 SQLAlchemy 的日志定位慢查询:
# backend/app/database.pyimportlogging logging.getLogger("sqlalchemy.engine").setLevel(logging.WARNING)# 只记录超过 1 秒的查询importtimefromsqlalchemyimporteventfromsqlalchemy.engineimportEngine@event.listens_for(Engine,"before_cursor_execute")defbefore_cursor(conn,cursor,statement,parameters,context,executemany):conn.info["query_start"]=time.time()@event.listens_for(Engine,"after_cursor_execute")defafter_cursor(conn,cursor,statement,parameters,context,executemany):total=time.time()-conn.info["query_start"]iftotal>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.pyfromprometheus_clientimportCounter,Histogram,Gauge,generate_latestfromfastapiimportResponseimporttime# 定义指标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")asyncdefmetrics():"""Prometheus 指标接口。"""returnResponse(generate_latest(),media_type="text/plain")LLM 延迟监控采集
在 LLM 调用处加上监控:
fromapp.services.metricsimportLLM_LATENCY,LLM_TOKENSwithLLM_LATENCY.time():response=awaitclient.chat.completions.create(...)LLM_TOKENS.labels(model="deepseek-chat").inc(response.usage.total_tokens)健康检查接口
@app.get("/api/health")asyncdefhealth_check():"""健康检查:返回各依赖服务状态。"""importredis status={"app":"ok","database":"unknown","redis":"unknown"}# 检查数据库try:withmodels.get_db()asconn:conn.execute("SELECT 1")status["database"]="ok"exceptException:status["database"]="error"# 检查 Redistry:r=redis.from_url(settings.REDIS_URL)r.ping()status["redis"]="ok"exceptException:status["redis"]="error"overall="ok"ifall(v=="ok"forvinstatus.values())else"degraded"return{"status":overall,"checks":status}Docker 容器监控
# 查看容器资源使用dockerstats# 查看特定容器日志dockerlogs--tail50--followknow-backend# 容器级别监控(CPU/内存)dockerstats know-backend --no-stream--format"table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}"常见的优化手段有哪些?
1. 数据库查询优化
# ❌ 慢:N+1 查询forkbinknowledge_bases:docs=awaitdb.execute(select(Document).where(Document.knowledge_base_id==kb.id))# ✅ 快:批量查询# 用 JOIN 一次查出result=awaitdb.execute(select(KnowledgeBase,Document).join(Document).where(...))2. LLM 调用缓存
# backend/app/services/cache.pyimporthashlibimportjsonfromapp.configimportsettingsdefllm_cache_key(messages:list)->str:"""生成 LLM 调用的缓存 key。"""content=json.dumps(messages,ensure_ascii=False,sort_keys=True)returnf"llm:{hashlib.md5(content.encode()).hexdigest()}"asyncdefget_cached_llm(messages:list,ttl:int=3600):"""带缓存的 LLM 调用。"""importredis r=redis.from_url(settings.REDIS_URL)key=llm_cache_key(messages)# 查缓存cached=r.get(key)ifcached:returncached.decode()# 调用 LLMresult=awaitcall_llm(messages)# 写入缓存r.setex(key,ttl,result)returnresult3. 静态文件缓存
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 压缩// - 图片压缩// 额外的优化:组件懒加载constKnowledgeBaseDetail=lazy(()=>import("./pages/KnowledgeBaseDetail"));优化 checklist
□ 数据库查询是否有 N+1 问题? □ 慢查询是否加了索引? □ LLM 响应是否做了缓存? □ 静态资源是否设置了缓存头? □ 数据库连接池是否配置了合理大小? □ 是否有健康检查接口? □ 容器资源限制是否设置? □ 关键路径是否加了耗时监控? □ 是否有错误告警?总结
性能优化和监控的关键:
| 方向 | 做什么 | 效果 |
|---|---|---|
| 定位瓶颈 | 慢查询追踪 + 耗时统计 | 知道慢在哪 |
| LLM 缓存 | 缓存相同请求的结果 | 减少 50-80% 的 LLM 调用 |
| 数据库优化 | 索引 + JOIN 替代 N+1 | 查询速度提升 10-100x |
| 健康检查 | 定期检测服务状态 | 及时发现故障 |
| Prometheus | 指标采集 + Grafana 可视化 | 实时了解系统状态 |
本文是《AI 全栈开发实战——做一个真正的产品》系列的第 12 篇。
本文由 Zyentor(智元界) 原创发布
本文发布于 Zyentor(智元界) —— AI 开发者社区
原文链接:https://www.zyentor.com/news/3883