AI 全栈开发实战(12):性能优化与监控——从慢查询定位到 Prometheus 监控

📅 2026/6/19 17:38:07
AI 全栈开发实战(12):性能优化与监控——从慢查询定位到 Prometheus 监控
AI 应用的性能优化与监控怎么做从响应速度到资源管理应用上线后怎么知道它跑得好不好慢了怎么优化本篇回答三个问题性能瓶颈怎么定位监控体系怎么搭建常见的优化手段有哪些性能瓶颈怎么定位慢在哪先量化不要凭感觉优化。先用数据定位瓶颈# backend/app/services/monitor.pyimporttimeimportloggingfromfunctoolsimportwraps loggerlogging.getLogger(__name__)deftimed(loggerNone):函数耗时统计装饰器。defdecorator(func):wraps(func)asyncdefwrapper(*args,**kwargs):starttime.time()try:resultawaitfunc(*args,**kwargs)returnresultfinally:elapsedtime.time()-startifelapsed0.5:# 超过 500ms 记录慢请求logloggerorlogging.getLogger(func.__module__)log.warning(fSlow call:{func.__name__}took{elapsed:.2f}s)returnwrapperreturndecorator慢查询追踪数据库查询是最常见的瓶颈。用 SQLAlchemy 的日志定位慢查询# backend/app/database.pyimportlogging logging.getLogger(sqlalchemy.engine).setLevel(logging.WARNING)# 只记录超过 1 秒的查询importtimefromsqlalchemyimporteventfromsqlalchemy.engineimportEngineevent.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):totaltime.time()-conn.info[query_start]iftotal1:logging.getLogger(slow_query).warning(fSlow 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_LATENCYHistogram(llm_request_duration_seconds,LLM API call latency,buckets(0.1,0.5,1.0,2.0,5.0,10.0))LLM_TOKENSCounter(llm_tokens_total,Total tokens consumed,[model])API_REQUESTSCounter(api_requests_total,Total API requests,[method,endpoint,status])API_LATENCYHistogram(api_request_duration_seconds,API request latency)app.get(/metrics)asyncdefmetrics():Prometheus 指标接口。returnResponse(generate_latest(),media_typetext/plain)LLM 延迟监控采集在 LLM 调用处加上监控fromapp.services.metricsimportLLM_LATENCY,LLM_TOKENSwithLLM_LATENCY.time():responseawaitclient.chat.completions.create(...)LLM_TOKENS.labels(modeldeepseek-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]okexceptException:status[database]error# 检查 Redistry:rredis.from_url(settings.REDIS_URL)r.ping()status[redis]okexceptException:status[redis]erroroverallokifall(vokforvinstatus.values())elsedegradedreturn{status:overall,checks:status}Docker 容器监控# 查看容器资源使用dockerstats# 查看特定容器日志dockerlogs--tail50--followknow-backend# 容器级别监控CPU/内存dockerstats know-backend --no-stream--formattable {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}常见的优化手段有哪些1. 数据库查询优化# ❌ 慢N1 查询forkbinknowledge_bases:docsawaitdb.execute(select(Document).where(Document.knowledge_base_idkb.id))# ✅ 快批量查询# 用 JOIN 一次查出resultawaitdb.execute(select(KnowledgeBase,Document).join(Document).where(...))2. LLM 调用缓存# backend/app/services/cache.pyimporthashlibimportjsonfromapp.configimportsettingsdefllm_cache_key(messages:list)-str:生成 LLM 调用的缓存 key。contentjson.dumps(messages,ensure_asciiFalse,sort_keysTrue)returnfllm:{hashlib.md5(content.encode()).hexdigest()}asyncdefget_cached_llm(messages:list,ttl:int3600):带缓存的 LLM 调用。importredis rredis.from_url(settings.REDIS_URL)keyllm_cache_key(messages)# 查缓存cachedr.get(key)ifcached:returncached.decode()# 调用 LLMresultawaitcall_llm(messages)# 写入缓存r.setex(key,ttl,result)returnresult3. 静态文件缓存Nginx 配置中已经做了location /static/ { expires 7d; add_header Cache-Control public, immutable; }4. 数据库连接池# SQLAlchemy 连接池配置enginecreate_async_engine(settings.DATABASE_URL,pool_size10,# 连接池大小max_overflow20,# 最大溢出连接数pool_pre_pingTrue,# 使用前检查连接是否有效pool_recycle3600,# 1 小时后回收连接)5. 前端资源优化// Vite 配置已包含// - 代码分割Code Splitting// - Tree Shaking// - CSS 压缩// - 图片压缩// 额外的优化组件懒加载constKnowledgeBaseDetaillazy(()import(./pages/KnowledgeBaseDetail));优化 checklist□ 数据库查询是否有 N1 问题 □ 慢查询是否加了索引 □ LLM 响应是否做了缓存 □ 静态资源是否设置了缓存头 □ 数据库连接池是否配置了合理大小 □ 是否有健康检查接口 □ 容器资源限制是否设置 □ 关键路径是否加了耗时监控 □ 是否有错误告警总结性能优化和监控的关键方向做什么效果定位瓶颈慢查询追踪 耗时统计知道慢在哪LLM 缓存缓存相同请求的结果减少 50-80% 的 LLM 调用数据库优化索引 JOIN 替代 N1查询速度提升 10-100x健康检查定期检测服务状态及时发现故障Prometheus指标采集 Grafana 可视化实时了解系统状态本文是《AI 全栈开发实战——做一个真正的产品》系列的第 12 篇。本文由 Zyentor智元界 原创发布本文发布于 Zyentor智元界 —— AI 开发者社区原文链接https://www.zyentor.com/news/3883