使用场景
PushGateway 是 Prometheus 生态中的一个重要一员,它允许任何客户端向其 Push 符合规范的自定义监控指标,再结合 Prometheus 统一收集监控。Prometheus Pushgateway 用于接收短期任务的指标数据,这些任务通过服务发现的监控系统无法直接监控。Pushgateway 允许临时性的工作(例如批处理作业)将指标推送到一个中央位置,而无需直接暴露其指标。这些数据可以被 Prometheus 服务器拉取和进行持久化存储。
注意:
Pushgateway 并不能将 Prometheus 转换为基于推送的监控系统,仅用作特殊场景中的指标暂存组件。同时 Pushgateway 不对暂存的指标做持久化保证,重启 Pushgateway 会导致暂存的指标丢失。实际场景请参见 Prometheus 官方文档 示例判断是否应该使用 Pushgateway。
一键安装
1. 登录 腾讯云可观测平台。
2. 在左侧菜单栏中单击 Prometheus 监控。
3. 在实例列表中,选择对应的 Prometheus 实例。
4. 进入实例详情页,单击数据采集 > 集成中心。
5. 在集成中心搜索 Pushgateway,找到后单击它即会弹出一个安装窗口。
6. 在弹出窗口的安装页面,根据提示填写相关信息,并单击保存。


配置说明
参数 | 说明 |
名称 | 集成名称,命名规范如下: 名称具有唯一性。 名称需要符合下面的正则:'^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$'。 |
采集超时 | Pushgateway 采集超时,时间格式,不能大于采集间隔。 |
采集间隔 | Pushgateway 采集间隔,时间格式。 |
CPU/核 | Pushgateway CPU 核数限制,不能大于64。 |
内存/Gi | Pushgateway 内存限制,配置时需带上单位Gi,不能大于512Gi。 |
7. 在已集成列表中获取 Pushgateway 地址信息。


数据推送
基本概念
分组: 以 job 和上报时指定的 label 确定的一组指标。
分组路径:分组指标上报请求在 pushgateway 中的对应请求路径,格式为:
/metrics/job/<JOB_NAME>{/<LABEL_NAME>/<LABEL_VALUE>}
。开发准备
go get github.com/prometheus/client_golang/prometheus
pip install prometheus-client
<dependency><groupId>io.prometheus</groupId><artifactId>prometheus-metrics-core</artifactId><version>1.3.3</version> <!-- 推荐使用最新版本参考:https://mvnrepository.com/artifact/io.prometheus/prometheus-metrics-core --></dependency><dependency><groupId>io.prometheus</groupId><artifactId>prometheus-metrics-instrumentation-jvm</artifactId><version>1.3.3</version></dependency><dependency><groupId>io.prometheus</groupId><artifactId>prometheus-metrics-exporter-pushgateway</artifactId><version>1.3.3</version></dependency>
PUT 请求
PUT 请求用来向 pushgateway 上报一个完整的分组,pushgateway 会使用 PUT 请求体中的指标更新整个分组(请求体中不存在的指标会被删除)。
请求体为空的 PUT 请求会使 pushgateway 删除整个分组。
package mainimport ("log""github.com/prometheus/client_golang/prometheus""github.com/prometheus/client_golang/prometheus/push"// 配合后续代码debug使用// "github.com/prometheus/common/expfmt")// 定义并注册指标var (serverRequestTotal = prometheus.NewCounterVec(prometheus.CounterOpts{Name: "http_server_request_total",Help: "total count of http server requests",}, []string{"path"})metricsRegistry = prometheus.NewRegistry())func init() {metricsRegistry.MustRegister(serverRequestTotal)}func main() {url := "YOUR-PUSHGATEWAY-ADDRESS"serverRequestTotal.WithLabelValues("api/v1/list").Inc()if err := push.New(url, "tcloud_test_job").Collector(metricsRegistry).// 自定义分组labelGrouping("provider", "tcloud").Grouping("product", "tmp").// 发送text/plain格式请求,便于debug// Format(expfmt.NewFormat(expfmt.TypeTextPlain)).// 发送PUT请求Push(); err != nil {log.Fatalf("Could not push completion time to Pushgateway: %v", err)}}
from prometheus_client import CollectorRegistry, Counter, push_to_gateway, pushadd_to_gateway, delete_from_gatewayregistry = CollectorRegistry()counter = Counter('http_server_request_total', 'total count of http server request', ['path'], registry=registry)address = "YOUR-PUSHGATEWAY-ADDRESS"job = "tcloud_test_job"grouping_key = {"product": "tmp", "provider": "tcloud"}if __name__ == "__main__":counter.labels(path='api/v1/list').inc()push_to_gateway(address, job=job, grouping_key=grouping_key, registry=registry)
package org.example;import java.io.IOException;import io.prometheus.metrics.core.metrics.Counter;import io.prometheus.metrics.exporter.pushgateway.PushGateway;import io.prometheus.metrics.instrumentation.jvm.JvmMetrics;import io.prometheus.metrics.model.registry.PrometheusRegistry;public class Main {private static PrometheusRegistry registry = new PrometheusRegistry();private static String address = "YOUR-PUSHGATEWAY-ADDRESS";private static String job = "tcloud_test_job";private static PushGateway pushGateway = PushGateway.builder().address(address).groupingKey("product", "tmp").groupingKey("provider", "tcloud").job(job).registry(registry).build();private static Counter counter = Counter.builder().name("http_request_total").labelNames("path").help("total count of http server request").register(registry);public static void main(String[] args) throws IOException {JvmMetrics.builder().register(registry);counter.labelValues("api/v1/list").inc();pushGateway.push();}}
cat <<EOF | curl -X PUT --data-binary @- http://*.*.*.*:8080/metrics/job/some_job/some_group_key1/value1/some_group_key2/value2# TYPE some_metric countersome_metric{label="val1"} 42# TYPE another_metric gauge# HELP another_metric Just an example.another_metric 2398.283EOF
POST 请求
POST 请求用来向 pushgateway 上报分组中需要修改的部分指标,pushgateway 仅会更新 POST 请求体中存在的指标,其他指标不变。
请求体为空的 POST 请求仅会更新 pushgateway 中记录的上报时间。
// 整体逻辑同PUT请求示例err := push.New(url, "tcloud_test_job").Collector(metricsRegistry).// 自定义分组labelGrouping("provider", "tcloud").Grouping("product", "tmp").// 发送POST请求Add()
if __name__ == "__main__":counter.labels(path='api/v1/list').inc()pushadd_to_gateway(address, job=job, grouping_key=grouping_key, registry=registry)
public static void main(String[] args) throws IOException {counter.labelValues("api/v1/list").inc();pushGateway.pushAdd();}
cat <<EOF | curl -X POST --data-binary @- http://*.*.*.*:8080/metrics/job/some_job/some_group_key1/value1/some_group_key2/value2# TYPE some_metric countersome_metric{label="val1"} 42# TYPE another_metric gauge# HELP another_metric Just an example.another_metric 2398.283EOF
DELETE 请求
DELETE 请求用来删除 pushgateway 中的整个分组。
// 整体逻辑同PUT请求示例err := push.New(url, "tcloud_test_job").// 自定义分组labelGrouping("provider", "tcloud").Grouping("product", "tmp").// 发送DELETE请求Delete()
if __name__ == "__main__":delete_from_gateway(address, job=job, grouping_key=grouping_key)
public static void main(String[] args) throws IOException {pushGateway.delete();}
curl -X DELETE http://*.*.*.*:8080/metrics/job/some_job/some_group_key1/value1/some_group_key2/value2
管理 API
PUT /api/v1/admin/wipe
注意:
wipe API 会清空 pushgateway 中的全部上报指标。
接入建议
因为 pushgateway 自身实现和设计逻辑,仅建议短期任务或特殊场景(存在网络隔离,仅支持主动推送指标等)使用 pushgateway 接入。可以根据实际需要参考以下建议:
每个上报端使用单独分组
多个上报端同时上报指标到同一个 pushgateway 时,建议附带单独的分组 label,例如
instance="instanceXX", instance="ip:port"
等,防止在 pushgateway 中指标相互覆盖。(持续上报场景)上报结束后删除 pushgateway 中对应指标
在持续使用 pushgateway 上报的场景中,上报端离线前应主动删除上报的分组,防止最后一次上报的数据一直保留在 pushgateway 中被反复采集。