文章目录
项目事前思考
需要了解清楚:需要从哪些角度去分析实现?
使用了缓存,就需要把缓存命中率数据进行收集;
使用了数据库连接池,就把连接池的参数给暴露出来;
Prometheus 普罗米修斯
概述
定义:
Prometheus作为一个开源的监控和告警工具,具有强大的数据采集、存储和查询能力;
介绍:
它通过采集和存储指标(metrics),提供了强大的数据查询语言,可以帮助我们分析和理解应用程序的行为。
Prometheus 的核心组件是 Prometheus Server,它负责采集监控指标并提供查询接口。
Prometheus 监控服务基于 Spring Actuator 机制采集 JVM 等数据,结合配套提供的 Grafana Dashboard 可以方便地监控 Spring Boot 应用的状态。
特点:
易于管理:Prometheus 核心部分只有一个单独的二进制文件;Prometheus 基于 Pu 模型的架构方式;
监控服务的内部运行状态:基于 Prometheus 丰富的 Client 库,用户可以轻松的在应用程序中添加对 Prometheus 的支持;
强大的数据模型:所有采集的监控数据均以指标(metric)的形式保存在内置的时间序列数据库当中(TSDB)。
强大的查询语言PromQL:通过 PromQL 可以实现对监控数据的查询、聚合。同时 PromQL 也被应用于数据可视化(如 Grafana)以及告警当中;
高效:可以处理数以百万的监控指标;
可扩展性:当单例Prometheus Server 处理的任务量过大时,通过使用功能分区(sharding)+联邦集群(federation)可以对其进行扩展;
易于集成:使用 Prometheus 可以快速搭建监控服务,并且可以非常方便地在应用程序中进行集成;
可视化:Prometheus Server 中自带的 Prometheus Ul,可以方便地直接对数据进行査询;
开放性:支持在外部创建单独的服务来适配不同的监控系统;
注意:
grafana、Prometheus 会独立部署在一台机器上,node_export 则被部署在被监控的服务器上,收集被监控的服务器资源数据,给 Prometheus,然后再通过 grafana 展示出来。
架构
它是一个维度存储模型,
安装及使用
参考:
普通安装 https://blog.csdn.net/dazhong2012/article/details/139288005
docker安装 https://www.cnblogs.com/sheepboy/p/17242916.html
安装步骤:
🍎 docker命令行,下载镜像包prometheus,并完成安装;
方法1:
直接通过docker pull 下载,由于网络超时问题,会导致下载异常;故此采用博客中提供的网盘链接下载 ;
解压:tar -xvf images_prmetheus.tar.gz ;
采用docker实现xxx.tar.gz导入docker中:一种for命令 一种脚本方式
for循环方式不能实现执行:for %%i in (*) do @docker load -i "%%i"
脚本方式执行:执行脚本方法也不可行;
方法2:
更换镜像;执行后续操作;
// 拉取镜像image
docker pull prom/prometheus
// 创建containers
docker run --name prometheus -d -p 9090:9090 prom/prometheus
// 需要自定义配置部署的,执行该条命令,-v后的内容是将主机自定义的prometheus.yml文件挂在到容器中;
docker run -d --name prometheus -p 9090:9090 -v D:\soft\Prometheus\prometheus.yml:/etc/prometheus/prometheus.yml prom/prometheus
// 浏览器访问查看prometheus启动情况
浏览器访问:http://localhost:9090 结果可以看到下图;
// 将prometheus.yml文件拷贝到宿主主机上,即从contains中拷贝到本地
docker cp prometheus:/etc/prometheus/prometheus.yml D:\soft\Prometheus\prometheus.yml
拷贝后结果为空?可能本来就是空的。
// 配置prometheus.yml文件
方法1-过程图1
方法1-文件解压代码1-不可用;
@echo off
setlocal enabledelayedexpansion
cd /d D:\soft\Prometheus\gz\images_prometheus
for %%i in (*.tar) do (
echo Loading %%i...
docker load -i "%%i"
)
endlocal
🍎 prometheus.yml文件
如下内容:
scrape_configs:
- job_name: 'spring-boot-application' //定义任务抓取的名字 应该是springboot-application-name
metrics_path: 'prometheus-demo/actuator/prometheus' // 指定Prometheus从目标服务器的哪个路基你个去获取度量指标;
scrape_interval: 15s // 设置抓取目标间隔的时间
static_configs:
- targets: ['192.168.10.108:8091'] // 抓取数据的服务地址ip和port
🍇注意:
targets中的ip如果是本地,不能使用localhost实现,而得采用ipconfig查看本地得到的ip地址;
🍎 prometheus启动成功,通过访问localhost:9090即可显示如下页面;
🍎 查询项目中配置的度量
simpleclient实现监控
实现步骤:
1. 项目pom.xml文件中添加依赖项;
dependency>
<groupId>io.prometheus</groupId>
<artifactId>simpleclient</artifactId>
<version>0.16.0</version>
</dependency>
<dependency>
<groupId>io.prometheus</groupId>
<artifactId>simpleclient_httpserver</artifactId>
<version>0.16.0</version>
</dependency>
2. 初始化HTTP服务器来暴露metrics端点,使用simpleclient_httpserver来启动默认的HTTP服务器;
通过return new HTTPServer(prometheusPort); 语句实现;
// 其中prometheusPort是端口号,用来暴露metrics的;
3. 记录数据,通过simpleclient提供的API记录指标数据;
4. 配置prometheus文件,抓取metrics;
scrape_configs:
- job_name: '所监控服务的名字' // 即spring.application.name
static_configs:
- targets: ['localhost:9190'] // 所监控服务的ip以及metrics暴露的端口号;
6. 测试,启动应用和prometheus,访问应用的metrics端点,http请求为:
http://localhost:9190/metrics // 其中ip和端口号于prometheus保持一致;
// 并且端口号与步骤二中的prometheusPort保持一致;
🍓具体实例在实战2;
PromQL
学习文档:https://prometheus.wang/promql/
io.prometheus.client库
统计接口调用量 每分钟或每秒钟;
请求的延迟时间
查看redis缓存容量;
查看本地缓存容量;
监控服务器内存使用情况;
1. 计数器定义
Counter REQUEST_TOTAL = Counter.build() // 创建计数器对象
.name("") // 定义指标名称
.help("") // 添加指标解释信息
.labelNames(PATH, APP_ID) // 定义区分指标的维度
.register(); // 注册计数器到Prometheus的注册中心
// 应用场景:统计某个接口调用量;统计某个应用调用量;
2. Summary,收集数据分布的信息
Summary HTTP_REQUEST_DURATION = Summary.build() // 创建Summary构造器对象
.name("") // 定义指标名称
.help("") // 添加指标解释信息
.labelNames(NAME, "subName", APP_ID) // 定义区分指标的维度
.quantile(0.5, 0.05) // 定义百分位点,以及误差
.quantile(0.9, 0.01) // 计算第90百分位,误差最多1%;
.quantile(0.99, 0.001)
.register(); // 注册到Prometheus的注册中心
// 特点:不划分区间,记录数值的总和及样本数;手动定义百分位;存储信息较少;开销小
// 应用场景:统计延迟时间;
3. Gauge,随时改变的数值的度量
Gauge CHANGE_GAUGE = Gauge.build()
.name("") // 定义指标名称
.help("") // 添加指标解释信息
.labelNames(NAME) // 定义区分指标的维度
.register(); // 注册到Prometheus的注册中心
// 应用场景:cache中的key所占内存;
4. Histogram 收集数据分布的信息
Histogram LATENCY_HISTOGRAM = Histogram.build()
.name("") // 定义指标名称
.help("") // 添加指标解释信息
.labelNames(NAME, "subName", APP_ID) // 定义区分指标的维度
.buckets(10, 50, 100, 200, 300, 500, 800, 1000, 1500, 3000, 10000) // 定义多个桶,表示延迟时间的区间范围 单位ms
.register(); // 注册到Prometheus的注册中心
// 特点:划分区间;提供百分位数;存储更多信息;开销大;
展示:
所遇问题
问题1:simpleclient 、simpleclient_httpserver、micrometer-registry-promethheus之间的区别?
前者,simpleclient 和 simpleclient_httpserver 是Prometheus客户端库的一部分,它们允许你在Java应用程序中直接记录度量数据,并提供一个简单的HTTP服务器来暴露这些度量数据给Prometheus抓取。
后者,micrometer-registry-prometheus: 这个依赖项允许你使用Micrometer来记录度量,并且将这些度量发布到Prometheus。
前者,需要手动管理度量的创建和暴露;更适合对监控有具体需求的情况;需要更多手动配置才可以提供更细的颗粒度;
后者,Micrometer提供了一个抽象层,使得度量的注册和暴露更加容易,尤其是对于那些想要快速集成监控而不想深入细节的应用程序。
Grafana可视化
概述
定义:
grafana,一个开源的可视化平台;
时序数据展示工具;
特征:
常用数据源有:MySQL、prometheus、elasticsearch等;
通过插件来显示数据;
安装及登录
docker 安装 :https://blog.csdn.net/dazhong2012/article/details/139288005
🍎 安装及运行:
安装镜像:
docker pull grafana/grafana
创建并运行容器:
docker run -d --name=grafana -p 3000:3000 grafana/grafana
访问grafana:
http://localhost:3000
账号-密码:xxxadmin-xxxadmin
使用及问题
🍎 项目配置:
🍇 添加数据源
🍇 验证配置数据集是否正常运行
🍎 问题1:与prometheus配置异常
描述:
Post "http://localhost:9090/api/v1query": dialtcp 127.0.0.1:9090: connect: connection refused - There was an error returned querying the Prometheus Apl.
分析:
访问的问题,不能使用localhost这个单词;
windows系统通过ipconfig得到本机ip地址,将localhost替换为查询到ip;
127.0.0.1 这个地址是不可行的;具体本机ip得出方式见下图;
展示度量参数
🍎 手动创建仪表盘Dashboard
具体操作:
dashboard --> create dashboard --> add viusalization --> select data source
1. 创建panel还是row
选择pannel;
视频中,涉及到创建panel还是row,row可以放多个panel;
当前grafana中只涉及到panel;
2. 查询度量参数
🍎 导入现成模板
网站:https://grafana.com/grafana/dashboards/
选择:
基于下载数量、reviews检查、
下载:
download json
案例中涉及到的是flink模板;
数据库读写分离
实战
实战1-Prometheus+Grafana+springboot
🍎 一、储备与思考
Prometheus 监控项目执行的情况,即执行环境的情况(指标采集);
Grafana 将监控情况进行展现;
睿象云 实现异常报警;
思考1:
Premetheus是否可以检测到项目运行是否正常,是否可以评估当前系统前后阶段是否数量一致?
🍎 二、整体步骤
1. 在springboot项目中添加Springboot Actuator和Micrometer prometheus Registry依赖,以及Actuator配置;
2. 下载镜像包prometheus并完成安装,在docker中;
参考 https://blog.csdn.net/qq_44246980/article/details/119981183 该方案失败。
参考 https://blog.csdn.net/dazhong2012/article/details/139288005 该方案失败,目前该方案进展。
参考 https://blog.csdn.net/2403_87851141/article/details/142733680 替换镜像,成功。
🍇1、springboot项目中涉及到prometheus的配置;
1 依赖:
Actuator 提供了一系列内置端点,用于显示运行应用的性能信息,如健康状况、指标等。
Micrometer Prometheus registry 会将这些指标格式化为 Prometheus 可读格式。
具体依赖:
2 配置 Actuator:
management: // 定义管理相关的配置
endpoints: // 指定关于应用端点的配置
web: // web端点的配置
exposure: //哪些端点通过web暴露出来
include: '*' // 所有管理端点
metrics: // 配置与度量指标相关的选项
export: // 指定度量指标导出的相关配置
prometheus: // 特定于prometheus的配置
enabled: true // 启动prometheus格式的度量指标导出
已知项目:只采用endpoints这个配置;且只启动了health
include参数介绍:health--应用程序的健康信息;info--应用程序的基本信息;metrics--应用程序的各种度量指标,如CPU使用率等;prometheus--暴露prometheus格式的度量指标;
🍇 2 docker命令行启动,下载镜像包prometheus,并完成安装;
方法1:
直接通过docker pull 下载,由于网络超时问题,会导致下载异常;故此采用博客中提供的网盘链接下载 ;
解压:tar -xvf images_prmetheus.tar.gz ;
采用docker实现xxx.tar.gz导入docker中:一种for命令 一种脚本方式
for循环方式不能实现执行:for %%i in (*) do @docker load -i "%%i"
脚本方式执行:执行脚本方法也不可行;
方法2:
更换镜像;执行后续操作;
// 拉取镜像image
docker pull prom/prometheus
// 创建containers
docker run --name prometheus -d -p 9090:9090 prom/prometheus
// 需要自定义配置部署的,执行该条命令,-v后的内容是将主机自定义的prometheus.yml文件挂在到容器中;
docker run -d --name prometheus -p 9090:9090 -v D:\soft\Prometheus\prometheus.yml:/etc/prometheus/prometheus.yml prom/prometheus
// 浏览器访问查看prometheus启动情况
浏览器访问:http://localhost:9090 结果可以看到下图;
// 将prometheus.yml文件拷贝到宿主主机上,即从contains中拷贝到本地
docker cp prometheus:/etc/prometheus/prometheus.yml D:\soft\Prometheus\prometheus.yml
拷贝后结果为空?可能本来就是空的。
// 配置prometheus.yml文件
@echo off
setlocal enabledelayedexpansion
cd /d D:\soft\Prometheus\gz\images_prometheus
for %%i in (*.tar) do (
echo Loading %%i...
docker load -i "%%i"
)
endlocal
prometheus启动成功,通过访问localhost:9090即可显示如下页面;
prometheus.yml文件
如下内容:
scrape_configs:
- job_name: 'spring-boot-application' //定义任务抓取的名字 应该是springboot-application-name
metrics_path: 'prometheus-demo/actuator/prometheus' // 指定Prometheus从目标服务器的哪个路基你个去获取度量指标;
scrape_interval: 15s // 设置抓取目标间隔的时间
static_configs:
- targets: ['192.168.10.108:8091'] // 抓取数据的服务地址ip和port
实战2-simpleclient+prometheus+grafana
整体流程:
1. 项目配置文件准备
pom.xml依赖导入;
HTTPserver服务配置类编写;
度量指标自定义编写;
2. prometheus服务配置文件编写
该文件位于本地prometheus的安装目录;Prometheus.yml文件
3. 运行项目测试prometheus
通过http://localhost:port 实现
结合 Grafana服务
🍎一、项目配置文件准备
4. pom依赖导入
<dependency>
<groupId>io.prometheus</groupId>
<artifactId>simpleclient</artifactId>
<version>0.16.0</version>
</dependency>
<dependency>
<groupId>io.prometheus</groupId>
<artifactId>simpleclient_httpserver</artifactId>
<version>0.16.0</version>
</dependency>
5. prometheusConfig文件编写
import io.prometheus.client.exporter.HTTPServer;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
import java.io.IOException;
@Configuration
@ConditionalOnProperty(
value = {"prometheus.enabled"},
havingValue = "true",
matchIfMissing = true
)
public class PrometheusConfig {
@Value("${prometheus.port:9090}")
private int prometheusPort;
@Bean(name = "prometheusServer", destroyMethod = "stop")
@Scope(value = "singleton")
public HTTPServer prometheusServer() throws IOException {
return new HTTPServer(prometheusPort);
}
}
3. 度量指标编写
import io.prometheus.client.Counter; // 记录某个初始点以来累计数量的度量类型;
import io.prometheus.client.Gauge;
// Gauge 用于记录瞬时值,可以任意上下浮动。它能够反映当前系统状态的一个快照,如内存使用情况、活跃连接数等。
import io.prometheus.client.Histogram;
// Histogram 用于收集数值分布,通常用来记录操作的耗时。它可以提供关于数据分布的统计信息,如平均值、中位数等。
import io.prometheus.client.Summary;
// Summary 类似于Histogram,但它的实现更高效,因为它不需要存储所有的桶(buckets)。Summary 通常用于记录数值的分布,但不提供完整的分布信息,而是只提供简单的汇总统计信息。
public interface PrometheusConsts {
String APP_ID = "appId";
String PATH = "path";
String NAME = "name";
/**
* 所有的请求的统计
*/
Counter REQUEST_TOTAL = Counter.build()
.name("")
.help("")
.labelNames(PATH, APP_ID)
.register();
Summary HTTP_REQUEST_DURATION = Summary.build()
.name("")
.help("")
.labelNames(NAME, "subName", APP_ID)
.quantile(0.5, 0.05)
.quantile(0.9, 0.01)
.quantile(0.99, 0.001)
.register();
/**
* 记录cache中的keys和所占内存
*/
Gauge CHANGE_GAUGE = Gauge.build()
.name("")
.help("")
.labelNames(NAME)
.register();
/**
* method name以及是哪个APP_ID的
*/
Histogram LATENCY_HISTOGRAM = Histogram.build()
.name("")
.help("")
.labelNames(NAME, "subName", APP_ID)
.buckets(10, 50, 100, 200, 300, 500, 800, 1000, 1500, 3000, 10000)
.register();
}
🍎二 、prometheus服务配置文件编写
scrape_configs:
- job_name: '所监控服务的名字' // 即spring.application.name
static_configs:
- targets: ['localhost:9190'] // 所监控服务的ip以及metrics暴露的端口号;
🍎 三、prometheus结果查看
http://localhost:9090
# HELP lz_server_requests_total Total number of requests.
# TYPE lz_server_requests_total counter
lz_server_requests_total{path="xxx",appId="xxx",} 1.0
# HELP http_request_duration_millis HTTP request latency in milliseconds.
# TYPE http_request_duration_millis summary
.....