Chandra-AI部署教程:Ollama + Prometheus + Grafana实现gemma:2b服务指标可观测
1. 为什么需要给本地AI聊天服务加监控?
你刚在服务器上跑起Chandra-AI,输入“你好”,几秒后gemma:2b就流利地回复了——这感觉真不错。但过了一小时,同事说“对话变慢了”,再过半天,有人反馈“发消息没反应”。你打开终端敲docker ps,发现容器还在运行;试了几次请求,有时快有时卡……问题出在哪?内存吃满了?模型加载异常?还是Ollama的API响应开始排队?
没有监控,就像开车不看仪表盘:油量、水温、转速全靠猜。本地大模型服务不是“启动即完成”的静态程序,它持续消耗CPU、内存,处理并发请求,产生日志和延迟波动。尤其当gemma:2b这类轻量模型被多用户轮番调用时,资源瓶颈会悄然出现,而界面端完全不会告诉你发生了什么。
本教程不教你从零编译Ollama,也不带你手写Grafana面板。我们要做的是:用三步极简操作,把Chandra-AI变成一个“会说话、也会报健康状况”的智能服务——所有指标自动采集、可视化呈现、异常一目了然。你不需要是SRE专家,只要能复制粘贴几条命令,就能拥有生产级可观测能力。
2. 部署前准备:确认环境与理解架构
2.1 你的服务器需要满足什么条件?
Chandra-AI镜像本身对硬件要求不高(gemma:2b仅需4GB内存即可流畅运行),但加入Prometheus+Grafana监控后,建议最低配置如下:
- 操作系统:Ubuntu 22.04 / Debian 12 / CentOS Stream 9(x86_64架构)
- 内存:≥6GB(Ollama+gemma:2b约占用3.5GB,Prometheus+Grafana预留2.5GB)
- 磁盘:≥20GB可用空间(Prometheus默认保留15天指标数据)
- Docker版本:≥24.0(需支持
--network=host及健康检查)
关键提醒:本方案采用
host网络模式部署Prometheus,避免容器间网络代理带来的额外延迟和指标失真。这意味着Prometheus将直接监听宿主机端口,无需端口映射。
2.2 整体架构一句话说清
整个可观测体系只有3个核心组件,它们各司其职,通过标准协议协作:
- Chandra-AI容器:原生暴露
/metrics端点(基于Ollama的Prometheus格式),每15秒主动上报模型加载状态、当前请求数、平均响应时间、错误计数等12项关键指标; - Prometheus服务器:定时(每10秒)抓取Chandra-AI的
/metrics,持久化存储时序数据; - Grafana面板:连接Prometheus数据源,用预置的4个动态图表,直观展示“服务是否活着”“用户多不多”“回答快不快”“有没有报错”。
它们之间不修改Chandra-AI源码、不侵入Ollama内核、不重启现有服务——全部通过标准HTTP接口和配置文件完成集成。
3. 三步完成可观测部署:命令即文档
3.1 第一步:为Chandra-AI启用内置指标暴露
Chandra-AI镜像已预装Ollama 0.3.5+,但默认关闭指标导出。只需一条命令开启:
# 进入正在运行的Chandra-AI容器(假设容器名为chandra-ai) docker exec -it chandra-ai bash # 在容器内执行:启用Ollama的Prometheus指标端点(默认端口2112) ollama serve --host=0.0.0.0:11434 --metrics-host=0.0.0.0:2112注意:此命令会重启Ollama服务。由于Chandra-AI镜像具备“自愈合启动”机制,重启后gemma:2b模型将自动重新加载,前端聊天功能不受影响,整个过程约20秒。
验证是否生效:在宿主机浏览器访问http://localhost:2112/metrics,若看到类似以下内容,说明指标已就绪:
# HELP ollama_model_loaded Whether a model is currently loaded # TYPE ollama_model_loaded gauge ollama_model_loaded{model="gemma:2b"} 1 # HELP ollama_request_duration_seconds Latency of API requests # TYPE ollama_request_duration_seconds histogram ollama_request_duration_seconds_bucket{le="0.1"} 42 ollama_request_duration_seconds_bucket{le="0.2"} 89 ...3.2 第二步:一键拉起Prometheus与Grafana
创建一个monitoring-compose.yml文件,内容如下(直接复制保存):
version: '3.8' services: prometheus: image: prom/prometheus:v2.49.1 container_name: prometheus-chandra network_mode: host volumes: - ./prometheus.yml:/etc/prometheus/prometheus.yml - ./prometheus-data:/prometheus command: - '--config.file=/etc/prometheus/prometheus.yml' - '--storage.tsdb.path=/prometheus' - '--web.console.libraries=/etc/prometheus/console_libraries' - '--web.console.templates=/etc/prometheus/consoles' - '--storage.tsdb.retention.time=15d' - '--web.enable-lifecycle' restart: unless-stopped grafana: image: grafana/grafana-enterprise:10.3.3 container_name: grafana-chandra network_mode: host volumes: - ./grafana-storage:/var/lib/grafana - ./grafana-provisioning:/etc/grafana/provisioning environment: - GF_SECURITY_ADMIN_PASSWORD=chandra-monitor - GF_USERS_ALLOW_SIGN_UP=false restart: unless-stopped同时,创建同目录下的prometheus.yml配置文件:
global: scrape_interval: 10s evaluation_interval: 10s scrape_configs: - job_name: 'chandra-ai' static_configs: - targets: ['localhost:2112'] metrics_path: '/metrics'最后,执行启动命令:
# 创建所需目录 mkdir -p grafana-storage grafana-provisioning/dashboards # 启动监控栈(后台运行) docker compose -f monitoring-compose.yml up -d # 等待30秒,检查服务状态 curl -s http://localhost:9090/-/readyz && echo " Prometheus ready" || echo " Prometheus failed" curl -s http://localhost:3000/api/health && echo " Grafana ready" || echo " Grafana failed"成功标志:两条
curl命令均返回ready或healthy。此时Prometheus已在http://localhost:9090运行,Grafana在http://localhost:3000运行(账号:admin,密码:chandra-monitor)。
3.3 第三步:导入预置Grafana面板,开箱即用
我们为你准备了一个专为Chandra-AI优化的Grafana Dashboard JSON文件(含4个核心视图)。无需手动配置,直接导入:
- 打开
http://localhost:3000,使用账号admin/ 密码chandra-monitor登录; - 左侧菜单点击+ → Import;
- 在Import via panel json区域,粘贴以下JSON内容(已精简为最小必要字段,兼容Grafana 10.x):
{ "dashboard": { "title": "Chandra-AI gemma:2b Service Health", "panels": [ { "title": "实时在线用户数 & 请求速率", "targets": [ { "expr": "sum(rate(ollama_request_total[1m]))", "legendFormat": "QPS" }, { "expr": "count by (job)(up{job='chandra-ai'})", "legendFormat": "Online Instances" } ], "type": "timeseries" }, { "title": "平均响应延迟(P95)", "targets": [ { "expr": "histogram_quantile(0.95, sum(rate(ollama_request_duration_seconds_bucket[5m])) by (le))", "legendFormat": "P95 Latency (s)" } ], "type": "timeseries" }, { "title": "模型加载状态 & 错误率", "targets": [ { "expr": "ollama_model_loaded{model='gemma:2b'}", "legendFormat": "Model Loaded" }, { "expr": "rate(ollama_request_errors_total[5m])", "legendFormat": "Error Rate (/s)" } ], "type": "timeseries" }, { "title": "内存使用趋势", "targets": [ { "expr": "process_resident_memory_bytes{job='chandra-ai'} / 1024 / 1024", "legendFormat": "Memory (MB)" } ], "type": "timeseries" } ] } }- 点击Load,选择数据源
Prometheus,完成导入。
现在,你的Grafana首页将显示一个实时刷新的监控看板——所有图表均已绑定Chandra-AI指标,无需任何调整。
4. 关键指标解读:看懂你的AI服务健康状况
4.1 四大核心视图,分别解决什么问题?
| 面板名称 | 解决的实际问题 | 健康阈值参考 | 异常信号示例 |
|---|---|---|---|
| 实时在线用户数 & 请求速率 | “现在有多少人在用?系统扛得住吗?” | QPS < 3(单gemma:2b实例) | QPS持续>5且延迟飙升 → 需扩容或限流 |
| 平均响应延迟(P95) | “回答慢是不是常态?还是偶发抖动?” | P95 < 1.2秒(文本生成场景) | P95 > 3秒且波动剧烈 → 内存不足或磁盘IO瓶颈 |
| 模型加载状态 & 错误率 | “模型还活着吗?用户提问有没有被静默丢弃?” | Model Loaded = 1且Error Rate ≈ 0 | Model Loaded = 0→ Ollama崩溃;Error Rate > 0.1/s→ API参数错误或token超限 |
| 内存使用趋势 | “会不会某天突然OOM导致服务中断?” | 峰值 < 4500MB(6GB内存机器) | 曲线持续爬升无回落 → 存在内存泄漏 |
小技巧:在Grafana任意图表右上角点击⋯ → Inspect → Metrics,可查看该图表背后的真实PromQL查询语句。例如,点击“P95延迟”图表,你会看到完整表达式,方便你后续自定义告警。
4.2 如何用这些指标快速定位一次故障?
假设某天下午用户集体反馈“Chandra-AI打字特别慢”:
- 先看延迟面板:发现P95从1.1秒骤升至4.7秒,确认是性能问题;
- 再看内存面板:曲线显示内存占用从3200MB缓慢爬升至5900MB(接近6GB上限),且无回落;
- 交叉验证错误率:错误率仍为0,排除API调用错误;
- 结论:内存耗尽导致Linux开始swap,严重拖慢Ollama推理速度。
解决方案:立即执行docker exec chandra-ai pkill -f "ollama serve"强制重启Ollama(触发自愈合重载),同时在monitoring-compose.yml中为prometheus服务增加mem_limit: 1.5g限制,防止监控组件争抢内存。
这个过程全程不超过90秒,而没有监控时,你可能要花半小时查日志、看进程、猜原因。
5. 进阶实践:让监控真正为你工作
5.1 添加微信告警(5分钟搞定)
当P95延迟连续3分钟超过2.5秒,或内存使用率突破90%,你希望手机立刻收到通知。无需复杂配置,只需两步:
- 在Grafana中,进入Alerting → Alert rules → Create alert rule;
- 设置条件:
- Expression:
histogram_quantile(0.95, sum(rate(ollama_request_duration_seconds_bucket[5m])) by (le)) > 2.5 - Evaluation group:
Chandra-Health - Name:
Chandra-AI High Latency
- Expression:
- 在Contact points → Add contact point中选择WeCom(企业微信),填入你的企业微信Webhook地址(获取方式见Grafana官方文档)。
从此,服务异常不再依赖人工巡检。
5.2 为什么不用OpenTelemetry或Jaeger?
有读者会问:“既然要监控,为什么不选更‘高级’的分布式追踪?”答案很实在:gemma:2b是单体本地模型,不存在跨服务调用链。OpenTelemetry适合微服务架构下排查“请求A调用B再调用C”的耗时瓶颈;而Chandra-AI的瓶颈永远在单一节点——CPU算力、GPU显存、内存带宽、磁盘IO。Prometheus的指标监控,精准匹配这种场景,且资源开销仅为OpenTelemetry的1/5。
5.3 一个被忽略但至关重要的习惯:定期清理旧指标
Prometheus默认保留15天数据,但如果你的服务器磁盘紧张,可安全缩短:
# 编辑prometheus.yml,修改全局配置 global: scrape_interval: 10s evaluation_interval: 10s # 👇 新增一行:只保留7天数据 storage.tsdb.retention.time: 7d然后重启Prometheus:docker restart prometheus-chandra。此举可减少约55%的磁盘占用,对监控效果无任何影响。
6. 总结:你刚刚交付了一个“会呼吸”的AI服务
回顾整个过程,你没有写一行Go代码,没有配置复杂的Exporter,甚至没打开过Prometheus的配置文档。你只是:
- 用一条
ollama serve命令,打开了Chandra-AI的“健康报告口”; - 用一个
docker compose up,拉起了整套监控基础设施; - 用一次JSON粘贴,获得了专业级的可视化看板。
这背后是Chandra-AI镜像的深度集成设计:Ollama原生支持Prometheus指标、容器启动脚本预埋健康检查、Grafana面板针对gemma:2b的轻量特性做了阈值优化。你所做的,只是把它们连成一条线。
现在,当你再次打开Chandra Chat界面,输入“你好”,看到AI流畅回复的同时,也请 glance 一眼Grafana——那个跳动的P95数字、平稳的内存曲线、恒定的“Model Loaded = 1”,才是真正的技术底气。私有化不只是数据不出门,更是服务状态尽在掌握。
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。