Prometheus+JmxExporter 监控告警最佳实践

概述

当你的 Java 应用运行起来之后,如果对其进行监控呢?Prometheus 社区开发了 JMX Exporter 来导出 JVM 的监控指标和自定义指标(自定义MBean),以便使用 Prometheus 来采集监控数据。本文将介绍如何利用 Prometheus 与 JMX Exporter 来监控你 Java 应用,并使用Grafana和Alertmanager对指标进行监控和告警。

动手之前,容我先简单介绍一下Prometheus和JmxExporter

Prometheus简介

Prometheus是由SoundCloud开发的开源监控报警系统和时序列数据库(TSDB)。

prometheus
Prometheus使用Go语言开发,是Google BorgMon监控系统的开源版本。2016年由Google发起Linux基金会旗下的原生云基金会(Cloud Native Computing Foundation)将Prometheus纳入其下第二大开源项目。Prometheus目前在开源社区相当活跃。Prometheus和Heapster(Heapster是K8S的一个子项目,用于获取集群的性能数据。)相比功能更完善、更全面。Prometheus性能也足够支撑上万台规模的集群。

系统架构图

架构


从上图可以看出,Prometheus的主要模块包括:Prometheus server,Pushgateway,exporters,PromQL,Alertmanager以及图形界面。

  • Prometheus Server 主要负责数据采集和存储,提供PromQL查询语言的支持。
  • Alertmanager 警告管理器,用来进行报警。
  • Push Gateway 支持临时性Job主动推送指标的中间网关。
  • Exporters 输出被监控组件信息的HTTP接口。
  • Grafana 监控数据展示Web UI。

基本原理

Prometheus的基本原理是通过HTTP协议周期性抓取被监控组件的状态,任意组件只要提供对应的HTTP接口就可以接入监控。不需要任何SDK或者其他的集成过程。这样做非常适合做虚拟化环境监控系统,比如VM、Docker、Kubernetes等。输出被监控组件信息的HTTP接口被叫做exporter 。目前互联网公司常用的组件大部分都有exporter可以直接使用,比如Varnish、Haproxy、Nginx、MySQL、Linux系统信息(包括磁盘、内存、CPU、网络等等)。其大概的工作流程是:

  • Prometheus server 定期从配置好的 jobs 或者 exporters 中拉 metrics,或者接收来自Pushgateway 发过来的 metrics,或者从其他的 Prometheus server 中拉 metrics。
  • Prometheus server 在本地存储收集到的 metrics,并运行已定义好的 alert.rules,记录新的时间序列或者向 Alertmanager 推送警报。
  • Alertmanager 根据配置文件,对接收到的警报进行处理,发出告警。
  • 在Grafana图形界面中,可视化查看采集数据。

JmxExporter介绍

什么是JmxExporter?

JMX Exporter 利用 Java 的 JMX 机制来读取 JVM 运行时的一些监控数据,然后将其转换为 Prometheus 所认知的 metrics 格式,以便让 Prometheus 对其进行监控采集。

如何使用JmxExporter暴露监控指标?

下面介绍如何通过 JMX Exporter 来暴露 Java 应用的 JVM 监控指标。JMX-Exporter 提供了两种用法:

  1. 启动独立进程。JVM 启动时指定参数,暴露 JMX 的 RMI 接口,JMX-Exporter 调用 RMI 获取 JVM 运行时状态数据,转换为 Prometheus metrics 格式,并暴露端口让 Prometheus 采集。
  2. JVM 进程内启动。JVM 启动时指定参数,通过 -javaagent 的形式运行 JMXExporter 的 jar 包,进程内读取 JVM 运行时状态数据,转换为 Prometheus metrics 格式,并暴露端口让 Prometheus 采集。

官方不推荐使用第一种方式,一方面配置复杂,另一方面因为它需要一个单独的进程,而这个进程本身的监控又成了新的问题,所以本文使用第二种用法暴露监控指标。

部署配置

Prometheus

本文使用docker的方式部署Prometheus,直接使用官方镜像运行。

提前在/Users/zero/Endless/ZhoujPractice/spring-boot-prometheus/config路径下创建Prometheus配置文件prometheus.yml和Prometheus规则文件prometheus_rules.yml,然后通过如下命令挂载到官方镜像中运行:

docker run \
    -p 9090:9090 \
    --name=prometheus \
    -v /Users/zero/Endless/ZhoujPractice/spring-boot-prometheus/config:/etc/prometheus/ \
    prom/prometheus

prometheus.yml配置文件

global:
  scrape_interval: 10s
  evaluation_interval: 10s
##告警组件配置
alerting:
  alertmanagers:
    - static_configs:
        - targets: [ '192.168.164.xx:9093' ]
rule_files:
  - "prometheus_rules.yml"

##数据采集Job配置
scrape_configs:
  ###以下内容为prometheus自身配置
  - job_name: 'prometheus'
    static_configs:
      - targets: [ '192.168.164.xx:9090' ]
        labels:
          appname: 'prometheus'
  ###以下内容为SpringBoot应用配置
  - job_name: 'springboot_prometheus'
    scrape_interval: 5s
    metrics_path: '/actuator/prometheus'
    static_configs:
      - targets: [ '192.168.164.xx:9999' ]
        labels:
          appname: 'springboot_prometheus'
  ###以下内容为jmx-exporter应用配置
  - job_name: 'jmx-exporter'
    scrape_interval: 10s
    metrics_path: '/metrics'
    static_configs:
      - targets: [ '192.168.164.xx:8089' ]
        labels:
          appname: 'jmx-exporter'

prometheus_rules.yml配置文件

groups:
  - name: InstanceDown #定义规则组
    rules:
      - alert: InstanceDown  #定义报警名称
        expr: up == 0   #Promql语句,触发规则
        for: 1m            # 一分钟
        labels: #标签定义报警的级别和主机
          name: instance
          severity: Critical
        annotations: #注解
          summary: " {{ $labels.appname }}" #报警摘要,取报警信息的appname名称
          description: " 服务停止运行 "   #报警信息
          value: "{{ $value }}%"  # 当前报警状态值
  - name: jmx-exporter-alert
    rules:
      - alert: jmx-exporter-qps
        expr: zhouj_practice_springboot_prometheus_springboot_prometheus_bindcount > 10
        for: 1m
        labels:
          severity: 'critical'
        annotations:
          summary: "instance: QPS > 10"
          description: "instance: QPS > 10"
          value: "{{ $value }}"
          instance: "{{ $labels.instance }}"

容器运行起来之后,访问:http://localhost:9090/ 查看Prometheus部署是否成功!

在这里插入图片描述

能正常访问代表安装成功。顺便可以看一下配置的job和告警规则是否加载成功,分别如下图:

job

由于Java应用和JmxExporter还没有部署,所以对应Job状态为down。

rules

Java应用

部署好Premetheus之后,接下来部署要监控的Java应用,本文直接使用Java -jar运行应用,JmxExporter以代理的模式运行。将Java应用的Jar包(spring-boot-prometheus-1.0-SNAPSHOT.jar)、JmxExporter的Jar(jmx_prometheus_javaagent-0.15.0.jar),还有JmxExporter配置文件jmx_exporter_config.yaml,放在相同目录下,执行如下命令:

java -javaagent:./jmx_prometheus_javaagent-0.15.0.jar=8089:jmx_exporter_config.yaml -jar -Dspring.jmx.enabled=true spring-boot-prometheus-1.0-SNAPSHOT.jar

说明:-Dspring.jmx.enabled=true 是因为我使用的spring的jmx注解,增加该参数进行MBean注册。

在这里插入图片描述

应用启动成功后,可以再去看一下Premetheus,此时可以看到所有的job都是UP状态。

在这里插入图片描述

选择一个Endpoint点击,可以看到抓取到的数据指标

在这里插入图片描述
到此,指标采集完成!接下来是指标的监控和指标的告警。

Grafana

虽然 Prometheus 提供的 Web UI 也可以很好的查看不同指标的视图,但是这个功能非常简单,只适合用来调试。要实现一个强大的监控系统,还需要一个能定制展示不同指标的面板,能支持不同类型的展现方式(曲线图、饼状图、热点图、TopN 等),这就是仪表盘(Dashboard)功能。

Grafana是一个用于可视化大型测量数据的开源系统,它的功能非常强大,界面也非常漂亮,使用它可以创建自定义的控制面板,你可以在面板中配置要显示的数据和显示方式,它支持很多不同的数据源,比如:Graphite、InfluxDB、OpenTSDB、Elasticsearch、Prometheus 等,而且它也支持众多的插件 。同样使用docker部署grafana,将宿主机grafana.ini配置文件挂在到容器内,执行以下命令:

docker run \
  -d \
  -p 3000:3000 \
  --name=grafana \
  -v /Users/zero/Endless/ZhoujPractice/spring-boot-prometheus/config/grafana.ini:/etc/grafana/grafana.ini \
  grafana/grafana

说明:grafana.ini只是修改了Grafana邮件告警相关的配置,如果你不打算用Grafana告警,可以不用配置文件。
grafana.ini配置文件

#################################### SMTP / Emailing ##########################
[smtp]
enabled = true
host = smtp.163.com:465
user = xxx@163.com
# If the password contains # or ; you have to wrap it with triple quotes. Ex """#password;"""
password = 必须是授权码
;cert_file =
;key_file =
skip_verify = true
from_address = xxx@163.com
from_name = Grafana
# EHLO identity in SMTP dialog (defaults to instance_name)
;ehlo_identity = dashboard.example.com
# SMTP startTLS policy (defaults to 'OpportunisticStartTLS')
;startTLS_policy = NoStartTLS

[emails]
;welcome_email_on_sign_up = false
;templates_pattern = emails/*.html

运行后访问http://localhost:3000/login,user:admin pass:admin

在这里插入图片描述

添加Prometheus数据源

在这里插入图片描述

点击Add data source进入,选择Prometheus数据源

在这里插入图片描述

配置Prometheus地址,点击右下方保存测试按钮

在这里插入图片描述

出现如下提示,表示数据源配置成功

在这里插入图片描述

接下来是进行自定义指标配置,这里就不详细介绍,自定义指标如下:

在这里插入图片描述

这里添加三个指标,针对每个指标可以设置告警条件,首先需要配置告警渠道,选择你设置的渠道

在这里插入图片描述

配置完,点击Test可以测试渠道是否可以,如果成功会收到如下邮件

在这里插入图片描述

至此,Grafana的部署、配置和使用结束,Java应用的监控和告警功能算是完成(就是说后面的内容可以不用看)!但是在文章的开始,有介绍Prometheus的几个组件,为了保证文章的完成性,最后的AlertManager告警组件还是要介绍一下。

AlertManager

虽然Grafana是可以进行告警,但总觉得它不是专业干这事的,因此接下来介绍AlertManager组件的部署和配置,同样适用docker部署,执行如下命令:

docker run \
  -d \
  -p 9093:9093 \
  --name alertmanager \
  -v /Users/zero/Endless/ZhoujPractice/spring-boot-prometheus/config/alertmanager.yml:/etc/alertmanager/alertmanager.yml \
  -v /Users/zero/Endless/ZhoujPractice/spring-boot-prometheus/config/default-monitor.tmpl:/etc/alertmanager/template/default-monitor.tmpl \
  prom/alertmanager

挂载alertmanager.yml配置文件和default-monitor.tmpl模版配置文件。
alertmanager.yml配置文件

global:
  resolve_timeout: 2m
  smtp_smarthost: smtp.163.com:465
  smtp_from: xxx@163.com
  smtp_auth_username: xxx@163.com
  smtp_auth_password: 必须是授权码
  smtp_require_tls: false

##消息模板
templates:
  - '/etc/alertmanager/template/*.tmpl'

route:
  receiver: 'email'    # 优先使用email发送
  group_wait: 30s
  group_interval: 60s
  repeat_interval: 1h
  group_by: [ cluster, alertname ]
#  routes:  #子路由,使用其他方式发送
#    - receiver: other
#      match_re:
#        serverity: other

receivers:
  - name: 'email'
    email_configs:
      - to: 'xxxx@getui.com'
        send_resolved: true #告警恢复通知
        html: '{{ template "email.html" . }}'
        headers: { Subject: " {{ .CommonAnnotations.summary }}" }

default-monitor.tmpl模版配置文件

{{ define "email.html" }}
<table border="5">
    <tr><td>alertname</td>
        <td>instance</td>
        <td>报警阀值</td>
        <td>开始时间</td>
    </tr>
    {{ range $i, $alert := .Alerts }}
        <tr><td>{{ index $alert.Labels "alertname" }}</td>
            <td>{{ index $alert.Labels "instance" }}</td>
            <td>{{ index $alert.Annotations "value" }}</td>
            <td>{{ $alert.StartsAt }}</td>
        </tr>
    {{ end }}
</table>
{{ end }}

运行成功后,访问http://192.168.0.100/:9093,查看AlertManager运行状态
在这里插入图片描述

根据自己设置的告警条件,如果指标触发会收到相应的告警邮件。

在这里插入图片描述

感谢阅读!

  • 5
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值