cxpxatu521 2024-03-18 15:12 采纳率: 80%
浏览 31
已结题

java通过pushgateway同步本地接口调用次数到prometheus Counter覆盖统计出错

遇到的问题

为了将本地Java接口的调用次数同步普罗米修斯, 我的做法是将接口调用次数推送到pushgateway, 在普罗米修斯中注册了pushgateway, 现在可以成功同步本地接口的调用次数, 但是每次调用代码同步的接口调用次数会把上次的覆盖, 比如第一次接口调用了10次, 第二次接口调用了9次, 普罗米修斯中统计到的接口调用次数就变成了9次, 而不是19次, 请各位指导下

推动接口调用次数的java代码

package org.example;

import io.prometheus.client.CollectorRegistry;
import io.prometheus.client.Counter;
import io.prometheus.client.exporter.PushGateway;

import java.io.IOException;

/**
 * 将 本地接口调用次数推动到pushgateway, 并同步到普罗米修斯
 */
public class PushDemo {
    private static final String NAME = "rpc_requests_total";
    private static final String HELP = "接口请求总数";
    private static final String[] LABELS = {"method", "result"};
    private static final Counter counter = Counter.build()
            .name(NAME)
            .help(HELP)
            .labelNames(LABELS)
            .register();

    public static void main( String[] args) {
        for (int i = 0; i < 50; ++i) {
            addSuccessCount();
        }
    }

    public static void addSuccessCount() {
        counter.labels("method1", "success").inc();

        // 设置PushGateway的地址
        PushGateway pushGateway = new PushGateway("ip:port");

        // 将指标推送到PushGateway
        try {
            pushGateway.pushAdd(CollectorRegistry.defaultRegistry, "pushgateway_test");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>org.example</groupId>
  <artifactId>PrometheusPushDataDemo</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>PrometheusPushDataDemo</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>io.prometheus</groupId>
      <artifactId>simpleclient_pushgateway</artifactId>
      <version>0.12.0</version>
    </dependency>
  </dependencies>
</project>

prometheus注册pushgateway

  - job_name: "pushgateway_test"
    scrape_interval: 500ms
    static_configs:
      - targets: ['ip:port']

docker启动pushgateway

sudo docker run -d \
  --name=pushgateway_test \
  -p 19091:9091 \
  -e TZ=Asia/Shanghai \
  prom/pushgateway
  • 写回答

10条回答 默认 最新

  • 关注

    回答参考Claude 3
    使用Prometheus的StatefulSet需要将程序部署到Kubernetes集群中。以下是大致步骤:

    1. 将应用程序打包为Docker镜像

    首先需要将应用程序打包为Docker镜像,以便于在Kubernetes集群中部署。可以使用Dockerfile来构建镜像。

    1. 编写Kubernetes资源清单文件

    需要为StatefulSet编写资源清单文件,描述StatefulSet的各种细节。这个文件通常是YAML格式的。

    apiVersion: apps/v1
    kind: StatefulSet
    metadata:
      name: my-stateful-app
    spec:
      serviceName: "my-service"
      replicas: 3
      selector:
        matchLabels:
          app: my-app
      template:
        metadata:
          labels:
            app: my-app
        spec:
          containers:
          - name: my-app
            image: my-app:latest
            ports:
            - containerPort: 8080
            volumeMounts:
            - name: data
              mountPath: /data
      volumeClaimTemplates:
      - metadata:
          name: data
        spec:
          accessModes: ["ReadWriteOnce"]
          resources:
            requests:
              storage: 1Gi
    

    在这个示例中,定义了一个StatefulSet,包含3个副本。每个Pod挂载了一个持久卷,用于存储状态数据。

    1. 在应用程序中使用持久卷存储指标值
      需要在应用程序中,将指标值保存到挂载的持久卷中。可以使用文件系统或者其他持久存储方案。每次应用程序启动时,需要从持久存储中读取之前的指标值。

    以下是一个示例代码,演示如何使用文件存储指标值:

    import io.prometheus.client.CollectorRegistry;
    import io.prometheus.client.Counter;
    import io.prometheus.client.exporter.PushGateway;
    
    import java.io.IOException;
    import java.nio.file.Files;
    import java.nio.file.Paths;
    
    public class PushDemo {
        private static final String NAME = "rpc_requests_total";
        private static final String HELP = "接口请求总数";
        private static final String[] LABELS = {"method", "result"};
        private static final Counter counter = Counter.build()
                .name(NAME)
                .help(HELP)
                .labelNames(LABELS)
                .register();
    
        private static final String DATA_DIR = "/data";
        private static final String COUNTER_FILE = DATA_DIR + "/counter.txt";
    
        public static void main(String[] args) {
            // 从文件中读取上一次的计数值
            long previousCount = readCountFromFile();
    
            // 设置新的初始值
            counter.labels("method1", "success").inc(previousCount);
    
            for (int i = 0; i < 50; ++i) {
                addSuccessCount();
            }
        }
    
        public static void addSuccessCount() {
            counter.labels("method1", "success").inc();
    
            // 设置PushGateway的地址
            PushGateway pushGateway = new PushGateway("pushgateway:9091");
    
            // 将指标推送到PushGateway
            try {
                pushGateway.pushAdd(CollectorRegistry.defaultRegistry, "pushgateway_test");
            } catch (IOException e) {
                e.printStackTrace();
            }
    
            // 将当前计数值写入文件
            writeCountToFile(counter.labels("method1", "success").get());
        }
    
        private static long readCountFromFile() {
            try {
                return Files.exists(Paths.get(COUNTER_FILE)) ?
                        Long.parseLong(new String(Files.readAllBytes(Paths.get(COUNTER_FILE)))) : 0;
            } catch (IOException e) {
                e.printStackTrace();
                return 0;
            }
        }
    
        private static void writeCountToFile(double count) {
            try {
                Files.write(Paths.get(COUNTER_FILE), String.valueOf(count).getBytes());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    

    在这个示例中,假设应用程序会将指标值存储在/data/counter.txt文件中。在启动时,应用程序会读取该文件中的值,并将其设置为Counter的初始值。在每次推送后,应用程序会将当前的计数值写入该文件。

    由于StatefulSet为每个Pod分配了一个持久标识符,因此即使Pod被重新调度,挂载的持久卷也不会改变,计数器值也不会丢失。

    1. 部署StatefulSet到Kubernetes集群

    最后一步是使用kubectl命令将StatefulSet部署到Kubernetes集群中:

    kubectl apply -f /path/to/statefulset.yaml
    

    这样应用程序就部署为StatefulSet的形式运行在Kubernetes集群中了,计数器值也可以在Pod重新调度时持久保存。
    需要确保Prometheus可以正确发现并抓取StatefulSet中Pod的指标数据。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(9条)

报告相同问题?

问题事件

  • 系统已结题 3月26日
  • 已采纳回答 3月18日
  • 赞助了问题酬金100元 3月18日
  • 创建了问题 3月18日

悬赏问题

  • ¥15 is not in the mmseg::model registry。报错,模型注册表找不到自定义模块。
  • ¥15 安装quartus II18.1时弹出此error,怎么解决?
  • ¥15 keil官网下载psn序列号在哪
  • ¥15 想用adb命令做一个通话软件,播放录音
  • ¥30 Pytorch深度学习服务器跑不通问题解决?
  • ¥15 部分客户订单定位有误的问题
  • ¥15 如何在maya程序中利用python编写领子和褶裥的模型的方法
  • ¥15 Bug traq 数据包 大概什么价
  • ¥15 在anaconda上pytorch和paddle paddle下载报错
  • ¥25 自动填写QQ腾讯文档收集表