news 2026/6/19 17:37:59

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
AI 全栈开发实战(12):性能优化与监控——从慢查询定位到 Prometheus 监控

AI 应用的性能优化与监控怎么做?从响应速度到资源管理

应用上线后,怎么知道它跑得好不好?慢了怎么优化?

本篇回答三个问题:

  1. 性能瓶颈怎么定位?
  2. 监控体系怎么搭建?
  3. 常见的优化手段有哪些?

性能瓶颈怎么定位?

慢在哪?先量化

不要凭感觉优化。先用数据定位瓶颈:

# 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)returnresult

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 压缩// - 图片压缩// 额外的优化:组件懒加载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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/19 17:37:12

告别臃肿!这款轻量级工具让你的华硕笔记本重获新生

告别臃肿!这款轻量级工具让你的华硕笔记本重获新生 【免费下载链接】g-helper Lightweight Armoury Crate alternative for Asus laptops with nearly the same functionality. Works with ROG Zephyrus, Flow, TUF, Strix, Scar, ProArt, Vivobook, Zenbook, Exper…

作者头像 李华
网站建设 2026/6/19 17:27:31

从信息收集到权限获取:实战复现Windows Server RPC缓冲区溢出漏洞MS08-067

1. 信息收集:锁定目标的第一步 搞安全测试的朋友都知道,信息收集就像侦探破案前的现场勘查。我去年在给某企业做内网渗透时,就深刻体会到这一步的重要性。当时花了整整三天时间做信息收集,最后只用半小时就拿下了目标服务器。下面…

作者头像 李华
网站建设 2026/6/19 17:25:53

D435i:从单目误解到双目真相,揭秘其SLAM与VIO应用之道

1. D435i的硬件构成:从单目误解到双目真相 第一次拿到D435i时,我也被它的外观迷惑了——正面只有一个明显的RGB摄像头,这不就是个单目摄像头吗?但当我开始用它跑VINS-Fusion时,发现事情没那么简单。仔细研究后才发现&a…

作者头像 李华
网站建设 2026/6/19 17:13:15

正则化工程实践:从过拟合诊断到产线调优全链路

1. 项目概述:为什么 regularization 不是“加个参数就完事”的玄学你训练了一个深度神经网络,训练集准确率99.8%,验证集却只有72.3%——模型在训练数据上跳着华尔兹,在测试数据上却连站都站不稳。你调大了学习率,它更飘…

作者头像 李华
网站建设 2026/6/19 17:02:20

机器学习工程化实战:从Notebook到高可用模型服务的全链路落地

1. 项目概述:这不是一次“部署上线”,而是一场从实验室到产线的系统性迁移 “From Notebook to Production: Running ML in the Real World (Part 4)”——这个标题里藏着一个被无数数据科学家反复咀嚼、又悄悄回避的真相: Jupyter Notebook…

作者头像 李华
网站建设 2026/6/19 16:56:17

Gemini 3.1 Pro百万上下文实战:原生长上下文范式解析

1. 项目概述:这不是“更大窗口”,而是重新定义上下文处理的底层逻辑 “Gemini 3.1 Pro 1M context API教程:百万上下文实战”——这个标题里藏着一个被多数人误读的关键点:它不是简单地把输入框拉长了10倍,而是彻底重构…

作者头像 李华