Prometheus+SpringBoot应用监控全过程详解
wptr33 2024-12-07 17:45 19 浏览
1. Prometheus是什么
Prometheus是一个具有活跃生态系统的开源系统监控和告警工具包。一言以蔽之,它是一套开源监控解决方案。
Prometheus主要特性:
- 多维数据模型,其中包含由指标名称和键/值对标识的时间序列数据
- PromQL,一种灵活的查询语言
- 不依赖分布式存储; 单服务器节点是自治的
- 时间序列收集通过HTTP上的pull模型进行
- 通过中间网关支持推送(push)时间序列
- 通过服务发现或静态配置发现目标
- 支持多种模式的图形和仪表盘
为什么用pull(拉取)而不用push(推送)呢?
因为,pull有以下优势:
- 进行更改时,可以在笔记本电脑上运行监控
- 可以更轻松地判断目标是否下线
- 可以手动转到目标并使用Web浏览器检查其运行状况
目标暴露HTTP端点,Prometheus服务端通过HTTP主动拉取数据。既然是服务端自己主动向目标拉取数据,那么服务端运行在本地(我们自己的电脑上)也是可以的,只要能访问目标端点即可,同时就像心跳检测一样可以判断目标是否下线,还有,服务端自己主动拉取,那么想拉取谁的数据就拉取谁的数据,因而可以随意切换拉取目标。
回想一下Skywalking是怎么做的,SkyWalking有客户端和服务端,需要在目标服务上安装探针(agent),探针采集目标服务的指标数据,上报给服务端OAP服务,这个对目标有一定的侵入性,不过可以接受。Prometheus不需要探针,可以借助push gateway来实现push效果。
对了,有个名词要先说清楚,metrics (译:度量,指标),个人更倾向于把它翻译成指标,后面说指标就是metrics
2. 基本概念
2.1. 数据模型
Prometheus基本上将所有数据存储为时间序列:具有时间戳的值流,它们属于同一个指标和同一组标记的维度。除了存储的时间序列外,Prometheus还可以生成临时派生的时间序列作为查询的结果。
Metric names and labels
Every time series is uniquely identified by its metric name and optional key-value pairs called labels.
每个时间序列都由它的指标名称和称为标签的可选键/值对唯一标识。
样本构成实际的时间序列数据。 每个样本包括:
- 一个64位的浮点值
- 一个毫秒时间戳
给定指标名称和一组标签,时间序列通常使用这种符号来标识:
<metric name>{<label name>=<label value>, ...}
例如,有一个时间序列,指标名称是api_http_requests_total,标签有method="POST"和handler="/messages",那么它可能被表示成这样:
api_http_requests_total{method="POST", handler="/messages"}
2.2. 指标类型
Counter
counter是一个累积量度,代表一个单调递增的计数器,其值只能增加或在重新启动时重置为零。例如,可以使用计数器来表示已服务请求数,已完成任务或错误的数量。
不要使用计数器来显示可以减小的值。例如,请勿对当前正在运行的进程数使用计数器,代替的应该使用量规。
Gauge
量规是一种指标,代表可以任意上下波动的单个数值。
量规通常用于测量值,例如温度或当前内存使用量,还用于可能上升和下降的“计数”,例如并发请求数。
Histogram
直方图对观察结果(通常是请求持续时间或响应大小)进行抽样,并在可配置的桶中对它们进行计数。它还提供了所有观测值的总和。
一个基础指标名称为<basename>的直方图在抓取期间会暴露多个时间序列:
- 观察桶的累积计数器,表示为 <basename>_bucket{le="<upper inclusive bound>"}
- 所有观测值的总和,表示为 <basename>_sum
- 观察到的事件数量,表示为 <basename>_count
Summary
与直方图类似,摘要对观察结果(通常是请求持续时间和响应大小等内容)进行抽样分析。虽然它还提供了观测值的总数和所有观测值的总和,但它可以计算滑动时间窗口内的可配置分位数。
一个基础指标名称为<basename>的摘要在抓取期间暴露多个时间序列:
- 观测事件的φ分位数(0≤φ≤1)流,表示为<basename>{quantile="<φ>"}
- 所有观测值的总和,表示为 <basename>_sum
- 观察到的事件数,表示为 <basename>_count
2.3. 作业和实例
在Prometheus的术语中,可以抓取的端点称为实例,通常对应于单个进程。具有相同目的的实例集合,称为作业。
例如,一个作业有四个实例:
- job: api-serverinstance 1: 1.2.3.4:5670instance 2: 1.2.3.4:5671instance 3: 5.6.7.8:5670instance 4: 5.6.7.8:5671
当Prometheus抓取目标时,它会自动在抓取的时间序列上附加一些标签,以识别被抓取的目标:
- job:目标所属的已配置的作业名称
- instance:被抓取的目标URL的<host>:<port>部分
3. 安装与配置
Prometheus通过抓取指标HTTP端点从目标收集指标。由于Prometheus以相同的方式暴露自己的数据,因此它也可以抓取并监视其自身的健康状况。
默认情况下,不用更改配置,直接运行就可以抓取prometheus自身的健康状况数据
# Start Prometheus.
# By default, Prometheus stores its database in ./data (flag --storage.tsdb.path)
./prometheus --config.file=prometheus.yml
直接访问 localhost:9090
访问 localhost:9090/metrics 可以查看各项指标
举个例子
输入以下表达式,点“Execute”,可以看到以下效果
prometheus_target_interval_length_seconds
这应该返回多个不同的时间序列(以及每个序列的最新值),每个序列的指标名称均为prometheus_target_interval_length_seconds,但具有不同的标签。
这个是以图形化的方式展示指标,通过localhost:9090/metrics查看也是一样的
如果我们只对99%的延迟感兴趣,我们可以使用以下查询:
prometheus_target_interval_length_seconds{quantile="0.99"}
为了计算返回的时间序列数,查询应该这样写:
count(prometheus_target_interval_length_seconds)
接下来,让我们利用Node Exporter来多添加几个目标:
tar -xzvf node_exporter-*.*.tar.gz
cd node_exporter-*.*
# Start 3 example targets in separate terminals:
./node_exporter --web.listen-address 127.0.0.1:8080
./node_exporter --web.listen-address 127.0.0.1:8081
./node_exporter --web.listen-address 127.0.0.1:8082
接下来,配置Prometheus来抓取这三个新目标
首先,定义一个名为'node'的作业,这个作业负责从这三个目标端点抓取数据。假设,想象前两个端点是生产环境的,另一个是非生产环境的,为了以示区别,我们将其打上两个不同的标签。在本示例中,我们将group="production"标签添加到第一个目标组,同时将group="canary"添加到第二个目标。
scrape_configs:
- job_name: 'node'
# Override the global default and scrape targets from this job every 5 seconds.
scrape_interval: 5s
static_configs:
- targets: ['localhost:8080', 'localhost:8081']
labels:
group: 'production'
- targets: ['localhost:8082']
labels:
group: 'canary'
3.1. 配置
为了查看所有的命令行参数,运行如下命令
./prometheus -h
配置文件是YAML格式的,可以使用 --config.file参数指定
配置文件的主要结构如下:
global:
# How frequently to scrape targets by default.
[ scrape_interval: <duration> | default = 1m ]
# How long until a scrape request times out.
[ scrape_timeout: <duration> | default = 10s ]
# How frequently to evaluate rules.
[ evaluation_interval: <duration> | default = 1m ]
# The labels to add to any time series or alerts when communicating with
# external systems (federation, remote storage, Alertmanager).
external_labels:
[ <labelname>: <labelvalue> ... ]
# File to which PromQL queries are logged.
# Reloading the configuration will reopen the file.
[ query_log_file: <string> ]
# Rule files specifies a list of globs. Rules and alerts are read from
# all matching files.
rule_files:
[ - <filepath_glob> ... ]
# A list of scrape configurations.
scrape_configs:
[ - <scrape_config> ... ]
# Alerting specifies settings related to the Alertmanager.
alerting:
alert_relabel_configs:
[ - <relabel_config> ... ]
alertmanagers:
[ - <alertmanager_config> ... ]
# Settings related to the remote write feature.
remote_write:
[ - <remote_write> ... ]
# Settings related to the remote read feature.
remote_read:
[ - <remote_read> ... ]
4. 抓取 Spring Boot 应用
Prometheus希望抓取或轮询单个应用程序实例以获取指标。 Spring Boot在 /actuator/prometheus 提供了一个actuator端点,以适当的格式提供Prometheus抓取。
为了以Prometheus服务器可以抓取的格式公开指标,需要依赖 micrometer-registry-prometheus
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
<version>1.6.4</version>
</dependency>
下面是一个示例 prometheus.yml
scrape_configs:
- job_name: 'spring'
metrics_path: '/actuator/prometheus'
static_configs:
- targets: ['HOST:PORT']
接下来,创建一个项目,名为prometheus-example
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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.cjs.example</groupId>
<artifactId>prometheus-example</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>prometheus-example</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
application.yml
spring:
application:
name: prometheus-example
management:
endpoints:
web:
exposure:
include: "*"
metrics:
tags:
application: ${spring.application.name}
这句别忘了: management.metrics.tags.application=${spring.application.name}
Spring Boot Actuator 默认的端点很多,详见
https://docs.spring.io/spring-boot/docs/2.4.3/reference/html/production-ready-features.html#production-ready-endpoints
启动项目,浏览器访问 /actuator/prometheus 端点
配置Prometheus抓取该应用
scrape_configs:
# The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
- job_name: 'prometheus'
# metrics_path defaults to '/metrics'
# scheme defaults to 'http'.
static_configs:
- targets: ['localhost:9090']
- job_name: 'springboot-prometheus'
metrics_path: '/actuator/prometheus'
static_configs:
- targets: ['192.168.100.93:8080']
重启服务
./prometheus --config.file=prometheus.yml
4.1. Grafana
https://grafana.com/docs/
https://grafana.com/tutorials/
下载&解压
wget https://dl.grafana.com/oss/release/grafana-7.4.3.linux-amd64.tar.gz
tar -zxvf grafana-7.4.3.linux-amd64.tar.gz
启动
./bin/grafana-server web
浏览器访问 http://localhost:3000
默认账号是 admin/admin
首次登陆后我们将密码改成admin1234
先配置一个数据源,一会儿添加仪表盘的时候要选择数据源的
Grafana官方提供了很多模板,我们可以直接使用
首先要找到我们想要的模板
比如,我们这里随便选了一个模板
可以直接将模板JSON文件下载下来导入,也可以直接输入模板ID加载,这里我们直接输入模板ID
立竿见影,马上就看到漂亮的展示界面了
我们再添加一个DashBoard (ID:12856)
原文链接:https://www.cnblogs.com/cjsblog/p/14434883.html
如果觉得本文对你有帮助,可以转发关注支持一下
相关推荐
- redis的八种使用场景
-
前言:redis是我们工作开发中,经常要打交道的,下面对redis的使用场景做总结介绍也是对redis举报的功能做梳理。缓存Redis最常见的用途是作为缓存,用于加速应用程序的响应速度。...
- 基于Redis的3种分布式ID生成策略
-
在分布式系统设计中,全局唯一ID是一个基础而关键的组件。随着业务规模扩大和系统架构向微服务演进,传统的单机自增ID已无法满足需求。高并发、高可用的分布式ID生成方案成为构建可靠分布式系统的必要条件。R...
- 基于OpenWrt系统路由器的模式切换与网页设计
-
摘要:目前商用WiFi路由器已应用到多个领域,商家通过给用户提供一个稳定免费WiFi热点达到吸引客户、提升服务的目标。传统路由器自带的Luci界面提供了工厂模式的Web界面,用户可通过该界面配置路...
- 这篇文章教你看明白 nginx-ingress 控制器
-
主机nginx一般nginx做主机反向代理(网关)有以下配置...
- 如何用redis实现注册中心
-
一句话总结使用Redis实现注册中心:服务注册...
- 爱可可老师24小时热门分享(2020.5.10)
-
No1.看自己以前写的代码是种什么体验?No2.DooM-chip!国外网友SylvainLefebvre自制的无CPU、无操作码、无指令计数器...No3.我认为CS学位可以更好,如...
- Apportable:拯救程序员,IOS一秒变安卓
-
摘要:还在为了跨平台使用cocos2d-x吗,拯救objc程序员的奇葩来了,ApportableSDK:FreeAndroidsupportforcocos2d-iPhone。App...
- JAVA实现超买超卖方案汇总,那个最适合你,一篇文章彻底讲透
-
以下是几种Java实现超买超卖问题的核心解决方案及代码示例,针对高并发场景下的库存扣减问题:方案一:Redis原子操作+Lua脚本(推荐)//使用Redis+Lua保证原子性publicbo...
- 3月26日更新 快速施法自动施法可独立设置
-
2016年3月26日DOTA2有一个79.6MB的更新主要是针对自动施法和快速施法的调整本来内容不多不少朋友都有自动施法和快速施法的困扰英文更新日志一些视觉BUG修复就不翻译了主要翻译自动施...
- Redis 是如何提供服务的
-
在刚刚接触Redis的时候,最想要知道的是一个’setnameJhon’命令到达Redis服务器的时候,它是如何返回’OK’的?里面命令处理的流程如何,具体细节怎么样?你一定有问过自己...
- lua _G、_VERSION使用
-
到这里我们已经把lua基础库中的函数介绍完了,除了函数外基础库中还有两个常量,一个是_G,另一个是_VERSION。_G是基础库本身,指向自己,这个变量很有意思,可以无限引用自己,最后得到的还是自己,...
- China's top diplomat to chair third China-Pacific Island countries foreign ministers' meeting
-
BEIJING,May21(Xinhua)--ChineseForeignMinisterWangYi,alsoamemberofthePoliticalBureau...
- 移动工作交流工具Lua推出Insights数据分析产品
-
Lua是一个适用于各种职业人士的移动交流平台,它在今天推出了一项叫做Insights的全新功能。Insights是一个数据平台,客户可以在上面实时看到员工之间的交流情况,并分析这些情况对公司发展的影响...
- Redis 7新武器:用Redis Stack实现向量搜索的极限压测
-
当传统关系型数据库还在为向量相似度搜索的性能挣扎时,Redis7的RedisStack...
- Nginx/OpenResty详解,Nginx Lua编程,重定向与内部子请求
-
重定向与内部子请求Nginx的rewrite指令不仅可以在Nginx内部的server、location之间进行跳转,还可以进行外部链接的重定向。通过ngx_lua模块的Lua函数除了能实现Nginx...
- 一周热门
-
-
C# 13 和 .NET 9 全知道 :13 使用 ASP.NET Core 构建网站 (1)
-
因果推断Matching方式实现代码 因果推断模型
-
git pull命令使用实例 git pull--rebase
-
git pull 和git fetch 命令分别有什么作用?二者有什么区别?
-
面试官:git pull是哪两个指令的组合?
-
git 执行pull错误如何撤销 git pull fail
-
git fetch 和git pull 的异同 git中fetch和pull的区别
-
git pull 之后本地代码被覆盖 解决方案
-
还可以这样玩?Git基本原理及各种骚操作,涨知识了
-
git命令之pull git.pull
-
- 最近发表
- 标签列表
-
- git pull (33)
- git fetch (35)
- mysql insert (35)
- mysql distinct (37)
- concat_ws (36)
- java continue (36)
- jenkins官网 (37)
- mysql 子查询 (37)
- python元组 (33)
- mybatis 分页 (35)
- vba split (37)
- redis watch (34)
- python list sort (37)
- nvarchar2 (34)
- mysql not null (36)
- hmset (35)
- python telnet (35)
- python readlines() 方法 (36)
- munmap (35)
- docker network create (35)
- redis 集合 (37)
- python sftp (37)
- setpriority (34)
- c语言 switch (34)
- git commit (34)