Prometheus监控JVM

618 阅读11分钟

介绍

image-20240907164148665.png

Prometheus Server 组成部分

Prometheus Server 组成部分

由三个部分组成:Retrieval,TSDB,HTTP Server

  • Retrieval:负责在活跃的 target(被监控的系统)主机上抓取监控指标数据。
  • TSDB:时间序列数据库,主要是把采集到的数据存储到磁盘中。默认为 15 天。
  • HTTP Server:为告警和出图提供查询接口。(通过PromQL进行查询)

Prometheus 的两种采集指标方式

  • pull方式

    被监控的系统提供HTTP接口方式暴露指标,Prometheus 通过HTTP协议去定时采集指标

  • push方式

    采集短周期任务的指标时,发现采集时被采集的对象可能已经停止,这时需要用到push方式。

    客户端主动将推数据到Push Gateway缓存一下,由Prometheus从push gateway pull指标过来。

    需要额外搭建Push Gateway

服务发现

用来动态的发现待监控的Target(目标主机/目的地址)。它可以通过第三方提供的接口,由Prometheus查询到需要监控的Target列表,然后轮询这些Target来获取监控数据。

Alertmanager

独立的告警模块,从 Prometheus server 端接收到 “告警通知” 后,会进行去重、分组,并路由到相应的接收方,发出报警, 常见的接收方式有:电子邮件、钉钉、企业微信等。 Prometheus Server 仅负责生成告警指示,具体的告警行为由另一个独立的应用程序 AlertManager 负责;告警指示由 Prometheus Server 基于用户提供的告警规则周期性计算生成,Alertmanager 接收到 Prometheus Server 发来的告警指示后,基于用户定义的告警路由向告警接收人发送告警信息。

Exporters

Exporter将监控数据采集的端点通过HTTP服务的形式暴露给Prometheus Server,Prometheus Server通过访问该Exporter提供的Endpoint端点,即可获取到需要采集的监控数据。

一般来说可以将Exporter分为2类:

  • 直接采集:这一类Exporter直接内置了对Prometheus监控的支持,比如cAdvisor,Kubernetes,Etcd,Gokit等,都直接内置了用于向Prometheus暴露监控数据的端点。
  • 间接采集:间接采集,原有监控目标并不直接支持Prometheus,因此我们需要通过Prometheus提供的Client Library编写该监控目标的监控采集程序。例如: Mysql Exporter,JMX Exporter,Consul Exporter等。

PushGateway

由于Prometheus数据采集基于Pull模型进行设计,因此在网络环境的配置上必须要让Prometheus Server能够直接与Exporter进行通信。 当这种网络需求无法直接满足时,就可以利用PushGateway来进行中转。可以通过PushGateway将内部网络的监控数据主动Push到Gateway当中。而Prometheus Server则可以采用同样Pull的方式从PushGateway中获取到监控数据。

安装Prometheus

下载路径:prometheus.io/download/

上面有Exporter(MySQL、Node...),也有pushgateway的安装包

liunx二进制包安装

**1、下载二进制包:**prometheus-x.x.x.linux-amd64.tar.gz

**2、解压包:**tar -xvzf prometheus-x.x.x.linux-amd64.tar.gz

**3、移动到安装目录:**mv prometheus-x.x.x.linux-amd64 /usr/local/prometheus

**4、进入目录:**cd /usr/local/prometheus

# 解压包解压到/usr/local/;应用一般放在usr/local这个路径
tar -zxvf prometheus-2.8.1.linux-amd64.tar.gz -C /usr/local/

# 修改解压的路径
cd /usr/local
mv prometheus-2.8.1.linux-amd64/ prometheus

#启动服务
cd /usr/local/prometheus
./prometheus --config.file=prometheus.yml

# 启动时常用的参数
    # 指定配置文件
    --config.file="prometheus.yml"
    # 指定监听地址端口
    --web.listen-address="0.0.0.0:9090" 
    # 最大连接数
    --web.max-connections=512
    # tsdb数据存储的目录,默认当前data/
    --storage.tsdb.path="data/"
    # premetheus 存储数据的时间,默认保存15天
    --storage.tsdb.retention=15d 

将Prometheus配置为系统服务

**1、进入systemd目录下:**cd /usr/lib/systemd/system **2、创建文件:**vim prometheus.service

[Unit]
  Description=https://prometheus.io
  
  [Service]
  Restart=on-failure
  ExecStart=/usr/local/prometheus/prometheus --config.file=/usr/local/prometheus/prometheus.yml

  [Install]                      
  WantedBy=multi-user.target

3、生效服务

# 生效系统system文件
systemctl daemon-reload

# 停止服务
systemctl stop prometheus.service
# 启动服务
systemctl start prometheus.service
# 查看服务
systemctl status prometheus
# 开机自启配置
 systemctl enable prometheus

Docker 容器安装部署

# 下载镜像
docker pull prom/prometheus

# 创建配置文件挂载目录,并新建配置文件
mkdir /var/prometheus 
cd /var/prometheus 
touch prometheus.yml
chmod -R 777 /var/prometheus
# 备注:必须新建配置文件,否则会出现目录挂载失败,如以下提示: OCI runtime create failed: runc create failed

# 创建并运行Prometheus,将9090端口映射出来,并且映射配置文件路径
docker run --name=prometheus -d -p 9090:9090 --restart=always -v /var/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml prom/prometheus

启动完成

启动完成后,Prometheus会启动一个9090 端口,该端口为web UI端口,也会暴露自身的指标metrics

Prometheus的UI界面:http://localhost:9090/graph

菜单下的功能:

​ Statu-->Configuration:prometheus.yml的配置

​ Statu-->Targets:展示监控具体的监控目标

Prometheus的暴露指标:http://localhost:9090/metrics (可以自己监控自己)

img

安装Pushgateway

下载地址:prometheus.io/download/#p…

默认端口:9091

web地址:http://ip:9091

指标暴露地址:http://ip:9091/metrics

流程

如果加入了pushgateway,那么Prometheus就不是到每个应用去pull数据,而是应用主动将指标通过http请求发给Pushgateway,然后Prometheus再拉取Pushgateway就能获取到所有的指标

graph LR

subgraph 应用
a1(APP1)
a2(APP2)
end

pw(pushgateway<br>端口:9091) 
pm(prometheus)

a1 --push---> pw
a2 --push---> pw
pw --"pull<br>get: http://ip:9091/metrics"---> pm

二进制包安装

# 下载安装包
wget https://github.com/prometheus/pushgateway/releases/download/{版本号}/pushgateway-{版本号}.linux-amd64.tar.gz
# 解压
tar xzvf pushgateway-{版本号}.linux-amd64.tar.gz 
# 移动到/usr/local/pushgateway路径
mv pushgateway-{版本号}.linux-amd64 /usr/local/pushgateway

#启动
cd /usr/local/pushgateway
./pushgateway

容器安装

# 获取最新版官方镜像
docker pull prom/pushgateway
# 启动 
docker run -d --name pushgateway -p 9091:9091 prom/pushgateway

Prometheus连接配置

文件:prometheus.yml

prometheus serverprometheus.yml文件中定义一个 job,然后targets指向pushgateway所在的ip和9091端口

......
scrape_configs:
  # 作业名称作为标签‘ job=<job_name> ’添加到从该配置中抓取的任何时间序列中
  - job_name: 'prometheus'
    # metrics_path 指标默认路径:'/metrics'
    # scheme 默认:'http'.
    # static_configs 静态配置方式
    static_configs:
    - targets: ['ip:port']
    
  # 配置从pushgateway获取指标
  - job_name: 'pushgateway'					#定义一个job
    static_configs:
    - targets: ['ip:9091']		#指定pushgateway所在的ip和端口
    
  - job_name ....

配置后需要重启Prometheus

kill -9 206697 && nohup ./prometheus & 

持久化启动

默认 PushGateway 不做数据持久化操作

需要加参数实现持久化

# 持久化文件pg_file,保存5分钟内的数据
./pushgateway -persistence.file=pg_file –persistence.interval=5m

# 参数
-persistence.file:本地持久化的文件,将 Push 的指标数据持久化保存到指定文件
-persistence.interval:指标数据保留时间,若设置为 5m,则表示 5 分钟后将删除存储的指标数据

Prometheus常用配置

指标说明

​ **global:**全局配置

​ **alerting:**告警配置

​ **rule_files:**告警规则

​ **scrape_configs:**配置数据源,称为target,每个target用job_name命名。又分为静态配置和服务发现

global:
  # 全局配置,定义抓取和评估时间间隔
  scrape_interval: 30s  # 抓取时间间隔
  scrape_timeout: 10s  # 抓取超时时间
  evaluation_interval: 30s  # 对告警规则做计算时间间隔,更新告警状态
  # 该服务端在与其他系统对接所携带的标签
  external_labels:
    prometheus: zenap/k8s  # 外部标签,用于标识监控实例
    prometheus_replica: prometheus-k8s-0  # 另一个外部标签,用于标识监控副本

alerting:
  alert_relabel_configs:  # 告警重标记配置
  - separator: ;  # 分隔符
    regex: prometheus_replica  # 正则表达式匹配
    replacement: $1  # 替换字符串
    action: labeldrop  # 操作类型

rule_files:
- /etc/prometheus/rules/prometheus-k8s-rulefiles-0/*.yaml  # 告警规则文件的路径

scrape_configs:
- job_name: dynamic-sd  # 动态服务发现作业
  honor_timestamps: true  # 尊重时间戳
  scrape_interval: 30s  # 抓取时间间隔
  scrape_timeout: 10s  # 抓取超时时间
  metrics_path: /metrics  # 指标路径
  scheme: http  # 使用的协议
  msb_sd_configs:
  - server: 192.168.10.5:10081  # MSB服务器地址
    base_path: /api/microservices/v1/services  # 基础路径
    labels:  # 标签配置
      interval: 30s  # 更新间隔
    services:  # 服务配置
    - name: dynamic-sd  # 服务名称
      version: v1  # 版本
      type: inst  # 类型
      namespace: default  # 命名空间
      url: metrics  # URL
      msb_denied_discovery_namespaces: admin,opcs,default  # 被拒绝的发现命名空间
      msb_service_selector:  # 服务选择器
        prometheus: service  # Prometheus服务类型
    refresh_interval: 1m  # 刷新间隔

Pushgateway API

推送指标数据到PushGateway

URL中 /instance/< instance> 可选,不写instance为null

在调推送接口时,默认新增了 push_time_secondspush_failure_time_seconds 两个指标,这两个是 PushGateway 系统自动生成的相关指标

  • URL: /metrics/job/<job>/instance/<instance>

  • 方法: PUT

  • 作用: 将指标数据推送到PushGateway中

  • 请求参数:

    参数名类型描述示例
    jobURL作业/任务名称some_job
    instanceURL实例名称some_instance
    data--data-binary要推送的指标数据
    格式:指标名称{标签名="value"} 值
    metric_name{label="value"} 123.45
  • 响应参数: 无

  • 样例:

  • # 上传http_requests_total指标,通过label可以分为两条数据
    cat <<EOF | curl --data-binary @- http://10.235.6.86:29475/metrics/job/some_job/instance/some_instance
    http_requests_total{method="post", handler="/messages"} 1027
    http_requests_total{method="get", handler="/messages"} 724
    EOF
    

image-20241016151007191转存失败,建议直接上传图片文件

删除指定指标

  • URL: /metrics/job/<job>/instance/<instance>

  • 方法: DELETE

  • 作用: 删除特定作业和实例的所有指标数据

  • 请求参数:

    参数名类型描述示例
    jobURL作业/任务名称some_job
    instanceURL实例名称some_instance
  • 响应参数: 无

  • 样例:

    # 删除some_job任务,实例some_instance的所有指标
    curl -X DELETE http://10.235.6.86:29475/metrics/job/some_job/instance/some_instance
    

metrics消息体说明

  1. TYPE: 指标类型,包括counter(计数器)、gauge(仪表)、histogram(直方图)和summary(摘要)。指定了指标类型后,Prometheus就能够正确地对待相应的数据,并且可以执行相应的操作,例如聚合或者展示。
  2. HELP: 指标描述信息,包括该指标所代表的含义、它的单位、以及其他相关说明。

Type指标类型

  1. Counter(计数器):

    • 用途:表示单调递增的数值,例如请求数、任务完成数等。通常用于统计事件发生的次数或累积值。

    • 举例:监控服务接收的请求数量、错误发生次数等。

    • 示例:

      # TYPE http_requests_total counter
      http_requests_total{method="get", handler="/api"} 100
      
  2. Gauge(仪表):

    • 用途:表示一个可变的数值,例如服务器当前的连接数、内存使用量等。通常用于表示某个状态的即时数值。

    • 举例:监控CPU使用率、内存占用情况等。

    • 示例:

      # TYPE cpu_usage gauge
      cpu_usage{host="server1"} 0.75
      
  3. Histogram(直方图):

    • 用途:用于观察一组数据的分布情况,例如请求延迟、响应时间等。通常用于测量数值的分布情况以及百分位数。

    • 举例:监控请求处理时间的分布情况、数据库查询耗时的分布等。

    • 示例:

      # TYPE http_request_duration_seconds histogram
      http_request_duration_seconds_bucket{le="0.1"} 20
      http_request_duration_seconds_bucket{le="0.5"} 50
      
  4. Summary(摘要):

    • 用途:类似于直方图,用于观察一组数据的分布情况,但它更关注一些百分位数和总体样本数量等摘要信息。

    • 举例:监控请求处理时间的分布情况、API调用耗时的分布等。

    • 示例:

      # TYPE api_request_duration summary
      api_request_duration{quantile="0.5"} 123
      api_request_duration{quantile="0.9"} 456
      

消息体

数据格式:指标名称{标签名="value"} 值

# TYPE http_requests_total counter
# HELP http_requests_total 请求统计
http_requests_total{method="post", handler="/messages"} 1027
http_requests_total{method="get", handler="/messages"} 724

java 项目对接Prometheus

上报方式到Pushgateway

pom依赖

<!--simpleclient_pushgateway和simpleclient_hotspot版本保持一致-->
<!--与Pushgateway通讯-->
<dependency>
    <groupId>io.prometheus</groupId>
    <artifactId>simpleclient_pushgateway</artifactId>
    <version>0.5.0</version>
</dependency>
<!--收集JVM指标-->
<dependency>
    <groupId>io.prometheus</groupId>
    <artifactId>simpleclient_hotspot</artifactId>
    <version>0.5.0</version>
</dependency>

代码

// SpringbootDemoApplication.java
@SpringBootApplication
// 开启定时任务
@EnableScheduling
public class SpringbootDemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringbootDemoApplication.class, args);
    }
}

// MetricsConfiguration.java

@Slf4j
@Configuration
public class MetricsConfiguration {

    PushGateway pushGateway;

    @Value("${spring.application.name}")
    public String appName;

    Counter requestsTotal;

    // 初始化方法,设置PushGateway并初始化JVM指标
    @PostConstruct
    public void init() {

        try {
            // pushgateway的IP和端口
            String pushGatewayAddress = "10.235.6.86:29475";
            log.info("init push gateway,url={}",pushGatewayAddress);
            this.pushGateway = new PushGateway(pushGatewayAddress);

            // Initialize default JVM metrics
            DefaultExports.initialize();

            // 获取JVM 指标注册表
            CollectorRegistry registry = CollectorRegistry.defaultRegistry;

            // 创建一个Counter自定义指标,类型是counter
            requestsTotal = Counter.build()
                    // 指标名称
                    .name("my_requests_total")
                    // 指标描述
                    .help("Total number of requests received")
                    // 将指标注入到指标注册表中
                    .register(registry);

        } catch (Throwable e) {
            log.error(e.getMessage(), e);

        }
    }

    /**
     * 30秒推送一次JVM指标到pushgateway
     *
     * @throws Exception
     */
    // 定时任务,用于定期推送JVM指标
    @Scheduled(cron = "*/30 * * * * ?")
    public void pushJvmMetrics() {
        log.info("push jvm metrics");
        // 获取JVM 指标注册表
        CollectorRegistry registry = CollectorRegistry.defaultRegistry;
        try {
            // 模拟应用程序处理请求并增加计数
            for (int i = 0; i < 10; i++) {
                requestsTotal.inc();
            }
            // pushGateway.pushAdd(registry, appName);
            // pushAdd(指标, 任务名,实例名)
            pushGateway.pushAdd(registry, appName,"instance:"+appName);
        } catch (Throwable e) {
            log.error("push metric error", e);

        }
    }
}

Springboot暴露Metrics

maven依赖

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

<!--暴露histogram-->
<dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-registry-prometheus</artifactId>
    <version>1.5.1</version>
</dependency>

application.yml

server:
  port: 8096
 
spring:
  application:
    name: gift
 
management:
  endpoint:
    health:
      show-details: always
  endpoints:
    web:
      exposure:
        include: 'prometheus'  # 暴露/actuator/prometheus
  metrics:
    tags:
      application: ${spring.application.name}  # 暴露的数据中添加application label

添加自定义指标

不填加则只暴露JVM自带指标

添加则暴露:自定义+JVM自带指标

// 添加my_requests_total指标
@Service
// 该类用于监控应用程序的指标
public class MyAppMetrics {

    private final Counter requestsTotal;

    @Autowired
    // 构造函数,接收MeterRegistry实例并初始化请求计数器
    public MyAppMetrics(MeterRegistry registry) {
        //registry 可新增其他指标
        this.requestsTotal = registry.counter("my_requests_total");
    }

    // 处理请求的方法,增加请求计数
    public void processRequest() {
        // 操作指标
        requestsTotal.increment();
    }

    // 其他指标的定义和更新逻辑
}

启动springboot项目

访问 http://localhost:8080/actuator/prometheus 查看指标是否正常

Prometheus配置

  - job_name: "jvm"
    # 多久采集一次数据
    scrape_interval: 5s
    # 采集时的超时时间
    scrape_timeout: 5s
    # 采集的路径
    metrics_path: '/actuator/prometheus'
    # 采集Springboot服务的地址
    static_configs:
      - targets: ['127.0.0.1:8080']

启动prometheus,查看指标情况 prometheus.exe --config.file=file

http://127.0.0.1:9090/targets

Prometheus服务发现

介绍

在Prometheus中,服务发现是一种自动发现和监控新实例的机制。通过服务发现,Prometheus可以自动发现和监控您的应用程序、容器、云服务等各种组件,而无需手动配置每个实例。

Prometheus支持多种服务发现机制,包括静态配置、基于DNS的服务发现、Consul服务发现、Kubernetes服务发现等。下面简要介绍其中的几种:

  1. 静态配置:您可以在Prometheus配置文件中直接指定需要监控的目标,这些目标可以是IP地址、主机名、端口等。这是最简单的服务发现方式,但不太适合动态环境。
  2. 基于DNS的服务发现:Prometheus可以通过DNS来自动发现目标。例如,您可以使用特定的命名约定将要监控的实例注册到DNS中,Prometheus会根据这些约定自动发现并监控这些实例。
  3. Consul服务发现:如果您的应用使用Consul作为服务注册与发现工具,Prometheus可以通过Consul API自动发现并监控注册在Consul中的服务实例。
  4. Kubernetes服务发现:如果您部署在Kubernetes集群中,Prometheus可以通过Kubernetes API自动发现并监控Kubernetes服务和Pod实例。

实现服务发现

在Prometheus的Configuration 配置文件中scrape_configs:下进行配置

...
scrape_configs:
- job_name: dynamic-sd
  honor_timestamps: true
  scrape_interval: 30s
  scrape_timeout: 10s
  metrics_path: /metrics
  scheme: http
  # 这里指定那种类型的服务发现进行获取监控的服务
  static_configs:
  - targets: ['localhost:9090', 'some-other-target:8080']

在Prometheus中实现服务发现,可以根据您的具体场景选择不同的方法。以下是一些常见的服务发现方法以及它们的简要实现步骤:

  1. 静态配置:最简单的服务发现方式,直接在Prometheus配置文件中指定需要监控的目标。

    static_configs:
      - targets: ['localhost:9090', 'some-other-target:8080']
    
  2. 基于DNS的服务发现:通过DNS来自动发现目标。

    在Prometheus配置文件中使用dns_sd_configs进行配置,例如:

    dns_sd_configs:
      - names: ['my-service-name.local']
        type: 'A'
        port: 8080
    
  3. Consul服务发现:通过Consul API自动发现并监控注册在Consul中的服务实例。

    配置Consul服务发现的示例:

    consul_sd_configs:
      - server: 'consul.service.consul'
        token: 'your-consul-token'
    
  4. Kubernetes服务发现:通过Kubernetes API自动发现并监控Kubernetes服务和Pod实例。

    使用Kubernetes服务发现的示例:

    kubernetes_sd_configs:
      - role: service
      - role: endpoints
    

以上仅是一些示例配置,具体的配置方式取决于您的环境、需求和服务发现工具。在实际情况下,您需要将这些配置添加到Prometheus的配置文件中,并确保Prometheus能够访问到相应的服务发现源(如Consul、Kubernetes等)。

Grafana数据可视化

介绍

Grafana是一个流行的开源数据可视化工具,用于监控和分析大量不同来源的数据。它提供了直观、灵活的界面,允许用户根据自己的需求创建各种仪表盘和图表,展示来自各种数据源的信息。

Grafana的特点包括:

  • 数据源多样性:支持从各种不同类型的数据源中获取数据,例如Prometheus、InfluxDB、Elasticsearch、Graphite等。
  • 灵活的仪表盘和图表:用户可以自由设计和定制仪表盘,选择图表类型、添加指标、设置图表样式等。
  • 强大的查询功能:支持使用多种查询语言和功能来提取和处理数据,如PromQL、SQL等。
  • 警报功能:能够基于数据的阈值设定触发警报,及时通知用户系统状态异常或趋势变化。
  • 社区支持:Grafana拥有庞大的用户社区和丰富的插件生态系统,用户可以分享、下载各种仪表盘模板和插件。

仪表盘创建

登录地址http://ip:3000 默认用户和密码均为admin

模板地址 grafana.com/grafana/das…

官网地址:grafana.com

仪表盘创建有如下三个核心配置点:

  1. 创建数据源;
  2. 创建面板;
  3. 创建仪表盘;

1.添加数据源

点击connection->data sources -> add new source->搜索Prometheus->填写Prometheus的链接信息即可。

2.创建面板

选择Dashboards->New->填写对应信息即可。

创建有多种方式,import:可根据官网提供的模版信息进行自动创建,见上方模版地址