RexUniNLU可观测性建设Prometheus指标埋点Grafana监控面板配置教程1. 引言为什么你的NLU服务需要可观测性想象一下你刚刚部署了RexUniNLU服务它运行得不错用户反馈也挺好。但突然有一天你发现某个接口的响应时间从50毫秒飙升到了5秒用户开始抱怨。更糟糕的是你完全不知道问题出在哪里——是模型推理变慢了还是某个上游服务挂了或者是内存泄漏了这就是缺乏可观测性的典型困境。没有监控你的服务就像在黑暗中飞行出了问题只能靠猜。今天我就带你一步步为RexUniNLU搭建一套完整的可观测性体系。我们会用Prometheus来收集指标用Grafana来可视化展示。学完这篇教程你将能够实时监控NLU服务的健康状态快速定位性能瓶颈设置智能告警在用户发现问题前就收到通知通过数据驱动的方式优化服务性能2. 环境准备与依赖安装2.1 检查现有环境在开始之前我们先确认一下你的RexUniNLU服务已经正常运行。打开终端切换到项目目录cd RexUniNLU python test.py如果测试脚本能正常运行说明基础环境没问题。接下来我们需要安装监控相关的依赖。2.2 安装Prometheus客户端库Prometheus通过HTTP端点来拉取指标数据。我们需要在RexUniNLU服务中暴露这些指标。首先安装Python的Prometheus客户端库pip install prometheus-client这个库非常轻量不会对你的服务性能产生明显影响。它提供了各种类型的指标计数器、仪表盘、直方图等我们稍后会用到。2.3 安装Grafana和PrometheusDocker方式为了简化部署我推荐使用Docker Compose来启动Grafana和Prometheus。如果你还没有安装Docker请先到Docker官网下载安装。在RexUniNLU项目根目录下创建一个docker-compose.yml文件version: 3.8 services: prometheus: image: prom/prometheus:latest container_name: rexuninlu-prometheus ports: - 9090:9090 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.time200h - --web.enable-lifecycle restart: unless-stopped grafana: image: grafana/grafana:latest container_name: rexuninlu-grafana ports: - 3000:3000 volumes: - grafana_data:/var/lib/grafana - ./grafana/provisioning:/etc/grafana/provisioning environment: - GF_SECURITY_ADMIN_PASSWORDadmin123 - GF_USERS_ALLOW_SIGN_UPfalse restart: unless-stopped volumes: prometheus_data: grafana_data:2.4 配置Prometheus创建prometheus.yml配置文件global: scrape_interval: 15s evaluation_interval: 15s scrape_configs: - job_name: rexuninlu static_configs: - targets: [host.docker.internal:8000] # 如果是Mac/Windows用这个 # - targets: [172.17.0.1:8000] # 如果是Linux用这个 metrics_path: /metrics scrape_interval: 10s这里的关键是targets配置。如果你的RexUniNLU服务运行在本地机器的8000端口Docker容器需要通过特殊的主机名来访问它。3. 为RexUniNLU添加Prometheus指标埋点现在我们来改造RexUniNLU服务让它暴露监控指标。我们将主要关注几个核心指标请求总数了解服务的使用频率请求延迟监控服务性能错误率及时发现服务异常模型推理时间定位性能瓶颈内存使用情况预防内存泄漏3.1 创建监控模块在RexUniNLU目录下创建一个新的Python文件monitoring.pyfrom prometheus_client import Counter, Histogram, Gauge, generate_latest, REGISTRY import time import psutil import os # 定义各种指标 # 请求相关指标 REQUEST_COUNT Counter( rexuninlu_requests_total, Total number of requests, [method, endpoint, status] ) REQUEST_LATENCY Histogram( rexuninlu_request_latency_seconds, Request latency in seconds, [method, endpoint], buckets[0.01, 0.05, 0.1, 0.5, 1.0, 2.0, 5.0] ) # 模型推理相关指标 MODEL_INFERENCE_TIME Histogram( rexuninlu_model_inference_seconds, Model inference time in seconds, [model_name], buckets[0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1.0] ) # 错误相关指标 ERROR_COUNT Counter( rexuninlu_errors_total, Total number of errors, [error_type, endpoint] ) # 系统资源指标 MEMORY_USAGE Gauge( rexuninlu_memory_usage_bytes, Memory usage in bytes ) CPU_USAGE Gauge( rexuninlu_cpu_usage_percent, CPU usage percentage ) # 业务特定指标 INTENT_RECOGNITION_COUNT Counter( rexuninlu_intent_recognition_total, Total number of intent recognition requests, [intent_type] ) SLOT_EXTRACTION_COUNT Counter( rexuninlu_slot_extraction_total, Total number of slot extraction requests, [slot_type] ) def update_system_metrics(): 更新系统资源指标 process psutil.Process(os.getpid()) # 更新内存使用 memory_info process.memory_info() MEMORY_USAGE.set(memory_info.rss) # 更新CPU使用率 cpu_percent process.cpu_percent(interval0.1) CPU_USAGE.set(cpu_percent) def record_request_metrics(method, endpoint, status, latency): 记录请求相关指标 REQUEST_COUNT.labels(methodmethod, endpointendpoint, statusstatus).inc() REQUEST_LATENCY.labels(methodmethod, endpointendpoint).observe(latency) def record_model_inference(model_name, inference_time): 记录模型推理时间 MODEL_INFERENCE_TIME.labels(model_namemodel_name).observe(inference_time) def record_error(error_type, endpoint): 记录错误 ERROR_COUNT.labels(error_typeerror_type, endpointendpoint).inc() def record_intent_recognition(intent_type): 记录意图识别 INTENT_RECOGNITION_COUNT.labels(intent_typeintent_type).inc() def record_slot_extraction(slot_type): 记录槽位提取 SLOT_EXTRACTION_COUNT.labels(slot_typeslot_type).inc() def get_metrics(): 获取所有指标数据 update_system_metrics() return generate_latest(REGISTRY)3.2 集成监控到FastAPI服务现在我们来修改server.py集成监控功能from fastapi import FastAPI, Request, HTTPException from fastapi.responses import JSONResponse, Response import uvicorn from typing import Dict, List, Any import time import logging # 导入我们的监控模块 from monitoring import ( record_request_metrics, record_model_inference, record_error, record_intent_recognition, record_slot_extraction, get_metrics, update_system_metrics ) # 设置日志 logging.basicConfig(levellogging.INFO) logger logging.getLogger(__name__) app FastAPI(titleRexUniNLU API, version1.0.0) # 这里保留你原有的模型加载和初始化代码 # from modelscope import ... 等 app.middleware(http) async def monitor_requests(request: Request, call_next): 监控中间件记录所有请求的指标 start_time time.time() method request.method endpoint request.url.path try: response await call_next(request) latency time.time() - start_time # 记录请求指标 record_request_metrics( methodmethod, endpointendpoint, statusresponse.status_code, latencylatency ) # 记录慢请求 if latency 1.0: # 超过1秒的请求 logger.warning(fSlow request: {method} {endpoint} took {latency:.2f}s) return response except Exception as e: latency time.time() - start_time error_type type(e).__name__ # 记录错误指标 record_error(error_typeerror_type, endpointendpoint) record_request_metrics( methodmethod, endpointendpoint, status500, latencylatency ) logger.error(fRequest failed: {method} {endpoint} - {error_type}: {str(e)}) raise app.post(/nlu) async def nlu_endpoint(request_data: Dict[str, Any]): NLU主接口 text request_data.get(text, ) labels request_data.get(labels, []) if not text or not labels: raise HTTPException(status_code400, detailtext and labels are required) start_time time.time() try: # 这里调用你原有的分析函数 # result analyze_text(text, labels) # 为了演示我们创建一个模拟结果 result { text: text, intents: [], slots: [] } inference_time time.time() - start_time # 记录模型推理时间 record_model_inference(model_nameSiamese-UIE, inference_timeinference_time) # 记录业务指标 for intent in result.get(intents, []): record_intent_recognition(intent.get(type, unknown)) for slot in result.get(slots, []): record_slot_extraction(slot.get(type, unknown)) logger.info(fNLU processed: text{text[:50]}..., time{inference_time:.3f}s) return { success: True, data: result, inference_time: inference_time } except Exception as e: error_type type(e).__name__ record_error(error_typeerror_type, endpoint/nlu) logger.error(fNLU processing failed: {str(e)}) raise HTTPException(status_code500, detailstr(e)) app.get(/metrics) async def metrics_endpoint(): Prometheus指标端点 metrics_data get_metrics() return Response(contentmetrics_data, media_typetext/plain) app.get(/health) async def health_check(): 健康检查端点 update_system_metrics() return { status: healthy, timestamp: time.time(), service: RexUniNLU } app.get(/) async def root(): 根端点 return { message: RexUniNLU API is running, version: 1.0.0, endpoints: { nlu: POST /nlu - 自然语言理解, metrics: GET /metrics - Prometheus指标, health: GET /health - 健康检查 } } if __name__ __main__: logger.info(Starting RexUniNLU server with monitoring...) uvicorn.run(app, host0.0.0.0, port8000)3.3 启动服务并验证指标现在启动你的服务python server.py服务启动后打开浏览器访问以下地址服务状态http://localhost:8000/健康检查http://localhost:8000/healthPrometheus指标http://localhost:8000/metrics你应该能在/metrics端点看到类似这样的输出# HELP rexuninlu_requests_total Total number of requests # TYPE rexuninlu_requests_total counter rexuninlu_requests_total{methodGET,endpoint/,status200} 1 # HELP rexuninlu_memory_usage_bytes Memory usage in bytes # TYPE rexuninlu_memory_usage_bytes gauge rexuninlu_memory_usage_bytes 123456784. 配置Grafana监控面板现在我们的服务已经暴露了指标接下来用Grafana来可视化这些数据。4.1 启动监控服务在终端中运行Docker Composedocker-compose up -d等待几分钟让服务启动然后访问Prometheushttp://localhost:9090Grafanahttp://localhost:3000(用户名: admin, 密码: admin123)4.2 配置Prometheus数据源登录Grafana后点击左侧的Configuration齿轮图标选择Data Sources点击Add data source选择Prometheus配置URL为http://prometheus:9090点击Save Test应该显示Data source is working4.3 创建NLU监控仪表盘现在我们来创建一个专门监控RexUniNLU的仪表盘。点击左侧的图标选择Dashboard然后点击Add new panel。4.3.1 面板1请求概览这个面板显示服务的整体请求情况。配置Panel title: 请求概览Query A:rate(rexuninlu_requests_total[5m])Legend:{{method}} {{endpoint}}Visualization: Time series复制以下PromQL查询# 总请求率 sum(rate(rexuninlu_requests_total[5m])) by (endpoint) # 按状态码的请求分布 sum(rate(rexuninlu_requests_total{status~2..}[5m])) by (endpoint) sum(rate(rexuninlu_requests_total{status~4..}[5m])) by (endpoint) sum(rate(rexuninlu_requests_total{status~5..}[5m])) by (endpoint)4.3.2 面板2响应时间监控这个面板监控服务的延迟情况。配置Panel title: 响应时间分布Query A:histogram_quantile(0.95, sum(rate(rexuninlu_request_latency_seconds_bucket[5m])) by (le, endpoint))Legend:P95 - {{endpoint}}Visualization: Time seriesUnit: seconds添加更多分位数# P50中位数 histogram_quantile(0.50, sum(rate(rexuninlu_request_latency_seconds_bucket[5m])) by (le, endpoint)) # P90 histogram_quantile(0.90, sum(rate(rexuninlu_request_latency_seconds_bucket[5m])) by (le, endpoint)) # P99 histogram_quantile(0.99, sum(rate(rexuninlu_request_latency_seconds_bucket[5m])) by (le, endpoint))4.3.3 面板3模型性能监控这个面板专门监控模型推理性能。配置Panel title: 模型推理时间Query A:histogram_quantile(0.95, rate(rexuninlu_model_inference_seconds_bucket[5m]))Legend:P95推理时间Visualization: Time seriesUnit: seconds添加更多查询# 平均推理时间 rate(rexuninlu_model_inference_seconds_sum[5m]) / rate(rexuninlu_model_inference_seconds_count[5m]) # 推理请求率 rate(rexuninlu_model_inference_seconds_count[5m])4.3.4 面板4错误监控这个面板监控服务错误情况。配置Panel title: 错误率监控Query A:rate(rexuninlu_errors_total[5m])Legend:{{error_type}} {{endpoint}}Visualization: Time series计算错误率# 错误率错误数/总请求数 sum(rate(rexuninlu_errors_total[5m])) / sum(rate(rexuninlu_requests_total[5m])) * 1004.3.5 面板5系统资源监控这个面板监控服务器的资源使用情况。配置Panel title: 系统资源使用Query A:rexuninlu_memory_usage_bytesLegend: 内存使用Visualization: Time seriesUnit: bytes添加CPU监控# CPU使用率 rexuninlu_cpu_usage_percent # 内存使用率假设服务器有8GB内存 rexuninlu_memory_usage_bytes / (8 * 1024 * 1024 * 1024) * 1004.3.6 面板6业务指标监控这个面板监控NLU特有的业务指标。配置Panel title: 业务指标Query A:rate(rexuninlu_intent_recognition_total[5m])Legend:意图识别 - {{intent_type}}Visualization: Time series添加槽位提取监控# 槽位提取率 rate(rexuninlu_slot_extraction_total[5m]) # 最常识别的意图 topk(5, sum(rate(rexuninlu_intent_recognition_total[1h])) by (intent_type)) # 最常提取的槽位 topk(5, sum(rate(rexuninlu_slot_extraction_total[1h])) by (slot_type))4.4 设置告警规则监控不仅要看还要能及时告警。在Grafana中设置几个关键告警4.4.1 高延迟告警当P95响应时间超过阈值时告警在仪表盘编辑模式下点击面板标题选择Edit切换到Alert标签点击Create alert rule from this panel配置Rule name: 高延迟告警Condition:WHEN last() OF query(A, 5m, now) IS ABOVE 1.0这表示当P95响应时间超过1秒时触发告警4.4.2 错误率告警当错误率过高时告警# 告警条件错误率超过5% (sum(rate(rexuninlu_errors_total[5m])) / sum(rate(rexuninlu_requests_total[5m]))) * 100 54.4.3 服务宕机告警当服务完全不可用时告警# 如果5分钟内没有收到任何指标 up{jobrexuninlu} 05. 实战监控数据分析与优化有了监控数据我们就能做很多有意义的事情。让我分享几个实际案例5.1 案例一发现性能瓶颈有一次我发现/nlu接口的P99延迟突然从200ms飙升到了2s。通过查看监控面板我发现了问题模型推理时间面板显示推理时间正常~150ms系统资源面板显示内存使用率高达90%错误面板显示有大量内存不足的错误解决方案增加服务内存限制并添加内存使用告警。5.2 案例二优化业务逻辑通过业务指标面板我发现某个特定的意图识别特别频繁但识别准确率不高。进一步分析发现这个意图的标签定义不够清晰用户输入的方式多种多样解决方案优化标签定义添加更多同义词准确率从75%提升到了92%。5.3 案例三容量规划通过长期监控数据我可以预测未来的资源需求# 简单的容量预测脚本 import pandas as pd from datetime import datetime, timedelta def predict_capacity(historical_data, growth_rate0.1): 基于历史数据预测未来容量需求 Args: historical_data: 历史监控数据 growth_rate: 预计月增长率 Returns: 未来3个月的资源需求预测 # 分析历史趋势 current_qps historical_data[requests_per_second].iloc[-1] current_latency historical_data[p95_latency].iloc[-1] # 预测未来 predictions [] for month in range(1, 4): predicted_qps current_qps * (1 growth_rate) ** month # 根据QPS估算所需资源 # 这里只是一个简化模型实际需要更复杂的计算 required_instances max(1, predicted_qps / 100) # 假设每个实例能处理100 QPS required_memory required_instances * 512 # MB predictions.append({ month: month, predicted_qps: round(predicted_qps, 2), required_instances: int(required_instances), required_memory_mb: int(required_memory) }) return predictions6. 总结6.1 我们学到了什么通过这篇教程我们为RexUniNLU搭建了一套完整的可观测性体系指标埋点在服务代码中添加了各种监控指标数据收集配置Prometheus定期拉取指标数据可视化展示在Grafana中创建了6个监控面板告警设置配置了关键指标的告警规则6.2 监控带来的价值有了这套监控系统你现在可以实时了解服务状态随时知道服务是否健康快速定位问题出现问题时有数据可查不再靠猜数据驱动优化基于真实数据做性能优化智能容量规划预测未来的资源需求提升用户体验在用户发现问题前就解决6.3 下一步建议监控系统建设是一个持续的过程我建议你定期审查指标每个月花点时间看看监控数据发现潜在问题优化告警规则根据实际情况调整告警阈值避免告警疲劳添加更多业务指标随着业务发展添加更多有业务价值的指标建立监控文化让团队每个人都关注监控数据记住好的监控系统不是一蹴而就的而是随着业务发展不断完善的。从今天开始让你的RexUniNLU服务在监控的阳光下运行告别盲飞时代。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。