Springboot集成prometheus快速入门demo

一、介绍

prometheus

Prometheus 是由前 Google 工程师从 2012 年开始在 Soundcloud 以开源软件的形式进行研发的系统监控和告警工具包,自此以后,许多公司和组织都采用了 Prometheus 作为监控告警工具。Prometheus 的开发者和用户社区非常活跃,它现在是一个独立的开源项目,可以独立于任何公司进行维护。为了证明这一点,Prometheus 于 2016 年 5 月加入 CNCF 基金会,成为继 Kubernetes 之后的第二个 CNCF 托管项目

grafana

Grafana 是一个监控仪表系统,它是由 Grafana Labs 公司开源的的一个系统监测工具,它可以大大帮助我们简化监控的复杂度,我们只需要提供需要监控的数据,它就可以帮助生成各种可视化仪表,同时它还有报警功能,可以在系统出现问题时发出通知。

二、环境搭建

这里采用docker-compose搭建测试环境,具体配置如下

docker-compose-prometheus.yml

 
 
# 镜像版本请自行选择 https://hub.docker.com/search?q=&type=image
version: "3"


# 网桥 -> 方便相互通讯
networks:
  prometheus:
    ipam:
      driver: default
      config:
        - subnet: "172.22.0.0/24"


services:
  # 开源的系统监控和报警系统
  prometheus:
    image: registry.cn-hangzhou.aliyuncs.com/zhengqing/prometheus:v2.34.0             # 原镜像`prom/prometheus:v2.34.0`
    container_name: prometheus
    restart: unless-stopped
    volumes:
      - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
    command: "--config.file=/etc/prometheus/prometheus.yml --storage.tsdb.path=/prometheus"
    ports:
      - "9090:9090"
    depends_on:
      - node-exporter
    networks:
      prometheus:
        ipv4_address: 172.22.0.11


  # 采集服务器层面的运行指标
  node-exporter:
    image: registry.cn-hangzhou.aliyuncs.com/zhengqing/node-exporter:v1.3.1           # 原镜像`prom/node-exporter:v1.3.1`
    container_name: prometheus-node-exporter
    restart: unless-stopped
    ports:
      - "9100:9100"
    networks:
      prometheus:
        ipv4_address: 172.22.0.22


  # 用于UI展示
  # https://grafana.com/docs/grafana/latest/installation/docker
  grafana:
    image: registry.cn-hangzhou.aliyuncs.com/zhengqing/grafana:8.0.0               # 原镜像`grafana/grafana:8.0.0`
    container_name: prometheus-grafana
    restart: unless-stopped
    ports:
      - "3000:3000"
    volumes:
      - "./prometheus/grafana/grafana.ini:/etc/grafana/grafana.ini" # 邮箱配置
#      - "./prometheus/grafana/grafana-storage:/var/lib/grafana"
#      - "./prometheus/grafana/public:/usr/share/grafana/public" # 这里面可处理汉化包 可参考 https://github.com/WangHL0927/grafana-chinese
#      - "./prometheus/grafana/conf:/usr/share/grafana/conf"
#      - "./prometheus/grafana/log:/var/log/grafana"
#      - "/etc/localtime:/etc/localtime"
    environment:
      GF_EXPLORE_ENABLED: "true"
      GF_SECURITY_ADMIN_PASSWORD: "admin"
      GF_INSTALL_PLUGINS: "grafana-clock-panel,grafana-simple-json-datasource,alexanderzobnin-zabbix-app"
      # 持久化到mysql数据库
      GF_DATABASE_URL: "mysql://root:root@172.22.0.34:3306/grafana" # TODO 修改
    depends_on:
      - prometheus
      - mysql
    networks:
      prometheus:
        ipv4_address: 172.22.0.33


  # mysql数据库 => 用于grafana持久化数据
  mysql:
    image: registry.cn-hangzhou.aliyuncs.com/zhengqing/mysql:5.7
    container_name: prometheus-mysql
    restart: unless-stopped
    volumes:
      - "./prometheus/mysql5.7/my.cnf:/etc/mysql/my.cnf"
      - "./prometheus/mysql5.7/data:/var/lib/mysql"
      - "./prometheus/mysql5.7/log/mysql/error.log:/var/log/mysql/error.log"
    environment:
      TZ: Asia/Shanghai
      LANG: en_US.UTF-8
      MYSQL_ROOT_PASSWORD: root         # 设置root用户密码
      MYSQL_DATABASE: grafana           # 初始化数据库grafana
    ports:
      - "3306:3306"
    networks:
      prometheus:
        ipv4_address: 172.22.0.34

启动测试环境

docker-compose-prometheus.yml 需修改grafana中配置的mysql连接信息 prometheus.yml 自行配置

 
 
# 运行
docker-compose -f docker-compose-prometheus.yml -p prometheus up -d
# 查看grafana日志
docker logs -fn10 prometheus-grafana
  1. grafana访问地址:http://ip地址:3000 默认登录账号密码:admin/admin

  2. prometheus访问地址: http://ip地址:9090

  3. exporter访问地址: http://ip地址:9100/metrics

5a8a4b0eea1e7156e3ede862d41bb68a.png

三、代码工程

下面老做一个小实验,实现自定义监控指标

pom.xml

 
 
<?xml version="1.0" encoding="UTF-8"?>
<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">
    <parent>
        <artifactId>springboot-demo</artifactId>
        <groupId>com.et</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>


    <artifactId>prometheus</artifactId>


    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>
    <dependencies>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>io.micrometer</groupId>
            <artifactId>micrometer-core</artifactId>
        </dependency>
        <dependency>
            <groupId>io.micrometer</groupId>
            <artifactId>micrometer-registry-prometheus</artifactId>
        </dependency>


    </dependencies>
</project>

application.properties

 
 
server.port=8088
spring.application.name=springboot2-prometheus
management.endpoints.web.exposure.include=*
management.metrics.tags.application=${spring.application.name}

PrometheusCustomMonitor.java

 
 
package com.et.prometheus.monitor;


import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.DistributionSummary;
import io.micrometer.core.instrument.MeterRegistry;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;


import javax.annotation.PostConstruct;
import java.util.concurrent.atomic.AtomicInteger;


@Component
public class PrometheusCustomMonitor {


    private Counter requestErrorCount;
    private Counter orderCount;
    private DistributionSummary amountSum;
    private AtomicInteger failCaseNum;


    private final MeterRegistry registry;


    @Autowired
    public PrometheusCustomMonitor(MeterRegistry registry) {
        this.registry = registry;
    }


    @PostConstruct
    private void init() {
        requestErrorCount = registry.counter("requests_error_total", "status", "error");
        orderCount = registry.counter("order_request_count", "order", "test-svc");
        amountSum = registry.summary("order_amount_sum", "orderAmount", "test-svc");
        failCaseNum = registry.gauge("fail_case_num", new AtomicInteger(0));
    }


    public Counter getRequestErrorCount() {
        return requestErrorCount;
    }


    public Counter getOrderCount() {
        return orderCount;
    }


    public DistributionSummary getAmountSum() {
        return amountSum;
    }


    public AtomicInteger getFailCaseNum() {
        return failCaseNum;
    }
}

GlobalExceptionHandler.java

 
 
package com.et.prometheus.exception;


import com.et.prometheus.monitor.PrometheusCustomMonitor;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;


import javax.annotation.Resource;


@ControllerAdvice
public class GlobalExceptionHandler {
    @Resource
    private PrometheusCustomMonitor monitor;


    @ResponseBody
    @ExceptionHandler(value = Exception.class)
    public String handle(Exception e) {
        monitor.getRequestErrorCount().increment();
        return "error, message: " + e.getMessage();
    }
}

TestController.java

 
 
package com.et.prometheus.controller;


import com.et.prometheus.monitor.PrometheusCustomMonitor;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;


import javax.annotation.Resource;
import java.util.Random;


@RestController
public class TestController {
    @Resource
    private PrometheusCustomMonitor monitor;


    @RequestMapping("/order")
    public String order(@RequestParam(defaultValue = "0") String flag) throws Exception {
        // 统计下单次数
        monitor.getOrderCount().increment();
        if ("1".equals(flag)) {
            throw new Exception("出错啦");
        }
        Random random = new Random();
        int amount = random.nextInt(100);
        // 统计金额
        monitor.getAmountSum().record(amount);


        monitor.getFailCaseNum().set(amount);
        return "下单成功, 金额: " + amount;
    }
}

启动类:

 
 
package com.et.prometheus;


import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;


@SpringBootApplication
public class DemoApplication {


   public static void main(String[] args) {
      SpringApplication.run(DemoApplication.class, args);
   }
}

code repository

  • https://github.com/Harries/springboot-demo

四、测试

启动springboot服务,,访问http://localhost:8089/orderhttp://localhost:8089/order?flag=1模拟下单成功和失败的情况,然后我们访问http://localhost:8088/actuator/prometheus,可以看到我们自定义指标已经被 /prometheus 端点暴露出来

 
 
# TYPE order_request_count_total counter
order_request_count_total{application="springboot2-prometheus",order="test-svc",} 34.0
# HELP jvm_threads_daemon_threads The current number of live daemon threads
# TYPE jvm_threads_daemon_threads gauge
jvm_threads_daemon_threads{application="springboot2-prometheus",} 18.0
# HELP jvm_classes_loaded_classes The number of classes that are currently loaded in the Java virtual machine
# TYPE jvm_classes_loaded_classes gauge
jvm_classes_loaded_classes{application="springboot2-prometheus",} 7250.0
# HELP order_amount_sum_max  
# TYPE order_amount_sum_max gauge
order_amount_sum_max{application="springboot2-prometheus",orderAmount="test-svc",} 97.0
# HELP order_amount_sum  
# TYPE order_amount_sum summary
order_amount_sum_count{application="springboot2-prometheus",orderAmount="test-svc",} 34.0
order_amount_sum_sum{application="springboot2-prometheus",orderAmount="test-svc",} 1482.0

在grafana上配置自定义的监控参数

访问 http://localhost:3000/login ,初始账号/密码为:admin/admin

1、配置数据源

点击左侧齿轮ConfigurationAdd Data Source,会看到如下界面:57402f241302a257e656fa06236f9430.png这里我们选择Prometheus 当做数据源,这里我们就配置一下Prometheus 的访问地址,点击 Save & Test711163eeca6583fc89a1ee03e05dc519.png

2、创建监控 Dashboard

点击导航栏上的 + 按钮,并点击Dashboard,将会看到类似如下的界面7139dbda6ef4eab2903ee981d4a587e9.png点击+ Add new panel9b038898728d18f2cd357e0b7869c749.png

最终效果如下

a10a75f62a6f2ba2dc349a4f71603e27.png

五、引用

  • https://segmentfault.com/a/1190000040239129

  • http://www.liuhaihua.cn/archives/710215.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/407004.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【深度学习笔记】3_5 图像分类数据集fashion-mnist

注&#xff1a;本文为《动手学深度学习》开源内容&#xff0c;仅为个人学习记录&#xff0c;无抄袭搬运意图 3.5 图像分类数据集&#xff08;Fashion-MNIST&#xff09; 在介绍softmax回归的实现前我们先引入一个多类图像分类数据集。它将在后面的章节中被多次使用&#xff0c…

抖音视频评论数据提取软件|抖音数据抓取工具

一、开发背景&#xff1a; 在业务需求中&#xff0c;我们经常需要下载抖音视频。然而&#xff0c;在网上找到的视频通常只能通过逐个复制链接的方式进行抓取和下载&#xff0c;这种操作非常耗时。我们希望能够通过关键词自动批量抓取并选择性地下载抖音视频。因此&#xff0c;为…

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的犬种识别系统(附完整代码资源+UI界面+PyTorch代码)

摘要&#xff1a;本文介绍了一种基于深度学习的犬种识别系统系统的代码&#xff0c;采用最先进的YOLOv8算法并对比YOLOv7、YOLOv6、YOLOv5等算法的结果&#xff0c;能够准确识别图像、视频、实时视频流以及批量文件中的犬种。文章详细解释了YOLOv8算法的原理&#xff0c;并提供…

RabbitMQ-消息队列:发布确认高级

18、发布确认高级 在生产环境中由于一些不明原因&#xff0c;导致 RabbitMQ 重启&#xff0c;在 RabbitMQ 重启期间生产者消息投递失败&#xff0c; 导致消息丢失&#xff0c;需要手动处理和恢复。于是&#xff0c;我们开始思考&#xff0c;如何才能进行 RabbitMQ 的消息可靠投…

零基础手把手教你创建微信小程序(二)·创建第一个微信小程序以及了解小程序代码的构成

零基础手把手教你创建微信小程序&#xff08;一&#xff09;微信小程序开发账号的注册以及开发者工具的安装和使用-CSDN博客 目录 ​编辑 1. 创建微信小程序 1.1 基本信息 1.2 在模拟器上查看项目效果 1.3 在真机上预览项目效果 1.4 主界面的5个组成部分 1.4.1 菜单…

Android studio 下的APK打包失败问题解决办法

嗨&#xff0c;各位小伙伴们&#xff0c;我是你们的好朋友咕噜铁蛋&#xff01;作为移动应用开发者&#xff0c;在使用Android Studio进行APK打包时&#xff0c;有时候可能会遇到各种问题导致打包失败&#xff0c;这给我们的开发工作带来了一定的挑战。今天&#xff0c;我将和大…

Excel 面试题及答案(2)

一、VLOOKUP+IF案例: A1 :根据左侧数据源,按姓名匹配《职级》,仅限用函数,不能做任何辅助A2 :根据左侧数据源,按姓名匹配《部门》,仅限用函数,不能做任何辅助A3 :根据右侧考核规则,匹配《绩效比例》,用函数完成(可适当做辅助的单元格区域) =VLOOKUP(F8,IF({1,0},…

qt波位图

1&#xff0c;QPainter 绘制&#xff0c;先绘制这一堆蓝色的东西, 2&#xff0c;在用定时器&#xff1a;QTimer&#xff0c;配合绘制棕色的圆。用到取余&#xff0c;取整 #pragma once#include <QWidget> #include <QPaintEvent>#include <QTimer>QT_BEGIN_…

小程序配置服务器域名:一步步教你如何设置

小程序配置服务器域名&#xff1a;一步步教你如何设置 在当今数字化时代&#xff0c;小程序已经成为了连接用户与服务的重要桥梁。然而&#xff0c;为了让小程序能够正常地与服务器进行通信&#xff0c;我们需要对小程序进行服务器域名的配置。本文将为大家详细介绍小程序配置…

【黑马程序员】STL容器之string

string string 基本概念 string本质 string是c风格的字符串&#xff0c;而string本质上是一个类 string和char* 区别 char* 是一个指针string是一个类&#xff0c;类内部封装了char*,管理这个字符串&#xff0c;是一个char*型的容器 特点 string 内部封装了很多成员方法…

C# (WebApi)整合 Swagger

SpringBoot-整合Swagger_jboot整合swagger-CSDN博客 C# webapi 也可以整合Swagger webapi运行其实有个自带的HELP页面 但是如果觉得UI不好看&#xff0c;且没办法显示方法注释等不方便的操作&#xff0c;我们也可以整合Swagger 一、使用NuGet控制台安装Swagger 在菜单中选择…

从软硬件以及常见框架思考高并发设计

目录 文章简介 扩展方式 横向扩展 纵向扩展 站在软件的层面上看 站在硬件的层面上看 站在经典的单机服务框架上看 性能提升的思考方向 可用性提升的思考方向 扩展性提升的思考方向 文章简介 先从整体&#xff0c;体系认识&#xff0c;理解高并发的策略&#xff0c;方…

LeetCode 448.找到所有数组中消失的数字

目录 1.题目 2.代码及思路 3.进阶 3.1题目 3.2代码及思路 1.题目 给你一个含 n 个整数的数组 nums &#xff0c;其中 nums[i] 在区间 [1, n] 内。请你找出所有在 [1, n] 范围内但没有出现在 nums 中的数字&#xff0c;并以数组的形式返回结果。 示例 1&#xff1a; 输入&am…

shiro 整合 springboot 实战

序言 前面我们学习了如下内容&#xff1a; 5 分钟入门 shiro 安全框架实战笔记 shiro 整合 spring 实战及源码详解 这一节我们来看下如何将 shiro 与 springboot 进行整合。 spring 整合 maven 依赖 <?xml version"1.0" encoding"UTF-8"?> …

神经网络系列---常用梯度下降算法

文章目录 常用梯度下降算法随机梯度下降&#xff08;Stochastic Gradient Descent&#xff0c;SGD&#xff09;&#xff1a;随机梯度下降数学公式&#xff1a;代码演示 批量梯度下降&#xff08;Batch Gradient Descent&#xff09;批量梯度下降数学公式&#xff1a;代码演示 小…

- 工程实践 - 《QPS百万级的有状态服务实践》05 - 持久化存储

本文属于专栏《构建工业级QPS百万级服务》 继续上篇《QPS百万级的有状态服务实践》04 - 服务一致性。目前我们的系统如图1。现在我们虽然已经尽量把相同用户的请求转发到相同的机器&#xff0c;并且在客户端做了适配。但是因为成本&#xff0c;更极端的情况下&#xff0c;服务依…

【多线程】synchronized 关键字 - 监视器锁 monitor lock

synchronized 1 synchronized 的特性1) 互斥2) 可重入 2 synchronized 使用示例1) 修饰代码块: 明确指定锁哪个对象.2) 直接修饰普通方法: 锁的 SynchronizedDemo 对象3) 修饰静态方法: 锁的 SynchronizedDemo 类的对象 3 Java 标准库中的线程安全类 1 synchronized 的特性 1)…

信号通信与消息队列实现的通信:2024/2/23

作业1&#xff1a;将信号和消息队列的课堂代码敲一遍 1.1 信号 1.1.1 信号默认、捕获、忽略处理(普通信号) 代码&#xff1a; #include <myhead.h> void handler(int signo) {if(signoSIGINT){printf("用户键入 ctrlc\n");} } int main(int argc, const ch…

招聘APP开发实践:技术选型、架构设计与开发流程

时下&#xff0c;招聘APP成为了企业和求职者之间连接的重要纽带。本文将深入探讨招聘APP的开发实践&#xff0c;重点关注技术选型、架构设计以及开发流程等关键方面&#xff0c;带领读者走进这一充满挑战与机遇的领域。 一、技术选型 在开始招聘APP的开发之前&#xff0c;首…

单片机51 输入和输出

一、IO口基本概念介绍 单片机的IO口&#xff08;Input/Output口&#xff09;是连接单片机与外部电路或设备的接口。单片机的IO口可以分为输入口和输出口两种&#xff0c;用于控制和监测外部设备的状态。 1. 输入口&#xff1a;单片机的输入口用于接收外部电路或设备的信号。输…
最新文章