1. PromQL基础入门理解核心概念PromQL是Prometheus内置的查询语言专门用于处理时间序列数据。想象一下时间序列就像是一连串按时间排序的数据点每个点都记录了某个指标在特定时刻的值。比如服务器CPU使用率每分钟的记录就是一个典型的时间序列。Prometheus中的数据模型包含几个关键要素指标名称Metric Name如http_requests_total表示HTTP请求总量标签Labels提供额外的维度信息如{methodGET, status200}样本值Sample Value具体的数值如1024时间戳Timestamp记录数据点的时间举个例子这是一个完整的时间序列数据http_requests_total{methodPOST, handler/api/users} 42 1620000000表示在时间戳1620000000时/api/users接口的POST请求累计达到了42次。PromQL支持四种基本数据类型即时向量Instant Vector某一时刻的所有时间序列范围向量Range Vector一段时间范围内的多个时间序列标量Scalar简单的数字值字符串String文本值实际使用较少2. 查询基础从简单到复杂2.1 基本查询语法最简单的PromQL查询就是直接输入指标名称node_cpu_seconds_total这会返回所有CPU时间的序列。但通常我们需要更精确的过滤这时可以使用标签匹配http_requests_total{status200, methodGET}PromQL支持四种标签匹配操作符精确匹配!不等于~正则匹配!~正则不匹配例如查询所有状态码为4xx的请求http_requests_total{status~4..}2.2 范围查询范围查询让我们可以获取一段时间内的数据语法是在指标后加上时间范围http_requests_total[5m]这表示获取最近5分钟的所有样本。时间单位可以是s秒m分钟h小时d天w周y年2.3 使用函数处理数据PromQL提供了丰富的内置函数来处理数据。最常用的是rate()和irate()用于计算Counter类型指标的增长速率rate(http_requests_total[5m])rate()计算5分钟内的平均增长率而irate()则更敏感反映最近两个数据点的瞬时增长率。另一个实用函数是increase()计算指定时间范围内的绝对增长量increase(http_requests_total[1h])3. 聚合操作从数据中提取洞察3.1 基本聚合操作PromQL支持多种聚合操作可以将多个时间序列合并计算sum(http_requests_total) by (status)常用聚合操作符包括sum()求和avg()平均值min()/max()最小/最大值count()计数quantile()分位数3.2 分组与过滤使用by和without可以控制聚合的分组方式avg(node_memory_usage_bytes) by (instance)这会按实例计算平均内存使用量。而without则是排除某些标签sum(rate(http_requests_total[5m])) without (instance)3.3 高级聚合技巧topk和bottomk可以找出最高或最低的k个值topk(3, http_requests_total)histogram_quantile用于计算直方图的分位数histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m]))4. 构建告警规则从查询到行动4.1 告警规则基础Prometheus的告警规则本质上是特殊的PromQL查询当条件满足时触发告警。基本结构如下groups: - name: example rules: - alert: HighRequestLatency expr: histogram_quantile(0.99, rate(http_request_duration_seconds_bucket[5m])) 1 for: 10m labels: severity: critical annotations: summary: High request latency on {{ $labels.instance }}4.2 实用告警示例CPU使用率过高告警100 - (avg(irate(node_cpu_seconds_total{modeidle}[5m])) by (instance) * 100) 80内存不足告警(node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes) / node_memory_MemTotal_bytes 0.9磁盘空间告警(node_filesystem_avail_bytes{mountpoint/} * 100) / node_filesystem_size_bytes{mountpoint/} 104.3 告警最佳实践设置合理的持续时间使用for字段避免瞬时波动触发告警分级告警区分warning和critical级别提供有意义的注释在annotations中包含解决问题的线索避免告警疲劳确保每个告警都需要人工干预5. 实战技巧与性能优化5.1 查询性能优化合理选择时间范围范围越大查询越慢使用irate替代rate当数据变化剧烈时避免不必要的计算先过滤再聚合利用记录规则预计算常用查询5.2 高级查询模式比较不同时间段rate(http_requests_total[5m]) - rate(http_requests_total[5m] offset 1h)预测性告警predict_linear(node_filesystem_free_bytes[1h], 4*3600) 0多条件组合up 0 unless on(instance) node_systemd_units{stateactive}5.3 常见问题排查无数据返回检查指标名称拼写、时间范围和数据保留期数据间断可能是抓取间隔设置不当或目标不可达数值异常检查Counter重置或单位转换问题查询超时优化查询复杂度或增加超时时间6. 与外部系统集成6.1 使用HTTP APIPrometheus提供了丰富的HTTP API可以通过编程方式执行查询curl http://localhost:9090/api/v1/query?queryuptime2023-07-01T12:00:00Z6.2 Grafana集成在Grafana中使用PromQL创建仪表盘添加Prometheus数据源在面板中使用PromQL查询利用变量实现动态过滤6.3 告警管理器集成配置Alertmanager处理Prometheus告警route: receiver: slack-notifications receivers: - name: slack-notifications slack_configs: - channel: #alerts send_resolved: true7. 实际案例解析7.1 监控Web应用请求成功率sum(rate(http_requests_total{status~2..}[5m])) by (service) / sum(rate(http_requests_total[5m])) by (service)错误率告警rate(http_requests_total{status~5..}[5m]) / rate(http_requests_total[5m]) 0.017.2 资源利用率监控CPU使用率100 - (avg by (instance) (irate(node_cpu_seconds_total{modeidle}[5m])) * 100)内存压力(node_memory_MemTotal_bytes - node_memory_MemFree_bytes - node_memory_Buffers_bytes - node_memory_Cached_bytes) / node_memory_MemTotal_bytes8. 最佳实践与经验分享命名规范指标和标签采用一致的命名方案避免过度聚合保持查询足够细粒度以便排查问题使用注释复杂的查询添加注释说明定期审查告警删除不再相关的告警规则监控监控系统确保Prometheus自身健康在实际使用中我发现最常犯的错误是忘记Counter类型需要先计算rate再比较。比如错误的写法http_requests_total 1000 # 错误正确的应该是rate(http_requests_total[5m]) 1000另一个实用技巧是使用label_replace动态添加标签label_replace(up, hostname, $1, instance, (.*):.*)掌握PromQL需要实践建议从简单查询开始逐步构建复杂表达式。遇到问题时Prometheus的Web UI提供了很好的调试环境可以实时查看查询结果。