最简单使用promethus+spring boot admin搭建spring boot应用监控系统

最简单使用promethus+spring boot admin搭建spring boot应用监控系统

promethus的安装使用

下载

官网地址 https://prometheus.io/

打开download页面,选择操作系统(Operating system),cpu架构(Architecture)后选择对应的软件下载即可

  • prometheus是监控系统,和一个内嵌的时间序列数据库
  • alertmanager是告警的组件

因为是springboot应用的监控 所以主要使用这两个就可以(其他组件提供了探测功能,spring boot自身使用actuator提供这些探测信息)

因为主要是在linux上使用,所以下面讲的都是linux的操作

解压到prometheus到一个指定的位置,暂定**/app/monitor-admin/prometheus/**

解压之后有各种各样的文件

  • prometheus是可执行文件,要有x权限才能使用
  • prometheus.yml是配置文件,yml风格如果手写比较容易出错,最好使用相应的编辑器编写

解压alertmanager到**/app/monitor-admin/prometheus/里面,所以目录是/app/monitor-admin/prometheus/alertmanager**

文件命名风格基本一致

  • alertmanager是可执行文件,要有x权限才能使用
  • alertmanager.yml是配置文件

启动

启动prometheus最好使用如下命令

./prometheus --config.file=./prometheus.yml --web.enable-lifecycle
#--config.file=./prometheus.yml 指定配置
#--web.enable-lifecycle这个参数的主要目的是为了运行时重载配置

启动完成后使用ip:9090就可以访问到Prometheus的页面了

启动alertmanager可以使用类似的命令

alertmanager的默认端口是9093

简单配置

一个简单的prometheus.yml配置如下

# my global config
global:
  scrape_interval:     15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
  evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.
  # scrape_timeout is set to the global default (10s).

# Alertmanager configuration 这个是Alertmanager的配置
alerting:
  alertmanagers:
  - static_configs:
    - targets:
       - 127.0.0.1:9093

# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
rule_files:
   - "agent_monitor.yml" #这个是页面上的rules的配置文件
  # - "second_rules.yml"

# A scrape configuration containing exactly one endpoint to scrape:
# Here it's Prometheus itself.
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'.
  - job_name: 'agent-server-monitor' #某个job的名字
    metrics_path: '/actuator/prometheus' #Prometheus采集的uri,在这里是spring boot提供的promethus接口
    scrape_interval: 15s
    static_configs:
    - targets: ['192.168.6.28:8099'] #目标,实际上就是一个应用的ip:port
      labels:
        instance: server #实例
        name: 192.168.6.28:8099 #区分各个实例,这个标签是可以任意添加的,在这里我的instance代表的是应用的功能,name作为区分
    - targets: ['192.168.5.22:8099']
      labels:
        instance: server
        name: 192.168.5.22:8099

agent_monitor.yml 这个配置可以这样子检查

promtool check rules /path/to/example.rules.yml
groups:
- name: monitor
  rules:
  - alert: InstanceDown
    expr: up == 0
    for: 1m
    labels:
      serverity: server
    annotations:
      summary: "Instance {{ $labels.name }} down"
      description: "应用 {{ $labels.name }} down" #这个labels就是引用的targets.labels,因此可以获取到其中自定义的名字
  - alert: process_cpu_usage
    expr: process_cpu_usage > 0.3
    for: 15s
    labels:
      serverity: server
    annotations:
      summary: "app {{ $labels.name }} cpu high"
      description: "应用 {{ $labels.name }} cpu使用率过高 当前值 {{ $value }}" #value就是查询出来的值
  - alert: system_cpu_usage
    expr: system_cpu_usage > 0
    for: 15s
    labels:
      serverity: server
    annotations:
      summary: "system {{ $labels.name }} cpu high"
      description: "应用 {{ $labels.name }} 所在服务器cpu负载过高 当前值 {{ $value }}"
  - alert: heap_memory_usage
    expr: jvm_memory_used_bytes{area="heap"} * 100/ jvm_memory_used_bytes{area="heap"} > 0
    for: 15s
    labels:
      serverity: server
    annotations:
      summary: "instance {{ $labels.name }} heap_memory_usage high"
      description: "应用 {{ $labels.name }} 的heap内存使用率过高 当前值 {{ $value }}"

具体的配置可以参考这篇博客https://blog.csdn.net/u012394095/article/details/81902630或者自行寻找

这篇博客中的获取查询语言也可以在Prometheus的Graph的Console中获取,具体方式是

  1. 在下拉菜单中找到需要的内容
  2. 点击execute
  3. 在Console中会出现查询语句

alertmanager.yml的配置如下,这里我使用的是web.hook,便于和spring-boot-admin配合使用

global:
  resolve_timeout: 5m

route:
  group_by: ['alertname']
  group_wait: 10s
  group_interval: 10s
  repeat_interval: 1h
  receiver: 'web.hook'
receivers:
- name: 'web.hook'
  webhook_configs:
  - url: 'http://127.0.0.1:8080/alarm' #web的接口,这里使用的是post请求
inhibit_rules:
  - source_match:
      severity: 'critical'
    target_match:
      severity: 'warning'
    equal: ['alertname', 'dev', 'instance']

重载配置使用这个命令,当然也可以做成页面按钮进行重载

curl -X POST http://localhost:9090/-/reload

在spring-boot中启用prometheus

prometheus的使用需要一个prometheus的依赖

 <dependency>
     <groupId>io.micrometer</groupId>
     <artifactId>micrometer-registry-prometheus</artifactId>
</dependency>

还需要actuator的配合

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

另外2.x的需要手动配置进行端点暴露

最简单的配置像这样,具体的详细配置需要查看官方文档https://spring.io/projects/spring-boot/#learn用endpoints关键词搜索即可,有一个对应的大章

management:
  endpoints:
    web:
      exposure:
        include: "*"  # * 在yaml 文件属于关键字,所以需要加引号
  endpoint:
    health:
      show-details: always #这个会显示health的具体内容
  metrics:
    web:
      server:
        auto-time-requests: true

spring-boot-admin

spring-boot-admin分为两个部分

一个是server,提供监控的页面可以查看

一个是client,是被监控的应用的插件

实际上可以认为是actuator的一个扩展,图形化的界面

使用spring-boot-admin很简单,只需要在需要监控的应用上添加admin-client的依赖,然后配置server的地址,server上添加admin-server的依赖,然后enableAdmin即可

server

server依赖

        <!-- https://mvnrepository.com/artifact/de.codecentric/spring-boot-admin-server-ui -->
        <dependency>
            <groupId>de.codecentric</groupId>
            <artifactId>spring-boot-admin-server-ui</artifactId>
            <version>2.1.2</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/de.codecentric/spring-boot-admin-server -->
        <dependency>
            <groupId>de.codecentric</groupId>
            <artifactId>spring-boot-admin-server</artifactId>
            <version>2.1.2</version>
        </dependency>

第一个是图形依赖,第二个是组件

启动admin-server使用

@EnableAdminServer

启动后即可访问ip:port

对于2.1.2版本,如果启动后没有client连接上,则页面会一直在Loading applications,这是正常情况

启动一个client后,就会显示为一个应用,点击之后就可以看到actuator的图形化界面了

长这样

aabbcc

问题

在2.1.2的spring-boot中,这里有一个问题

admin-server的后台会一直报错,实际上是tomcat的一个bug,切换web容器成jetty就可以了

报错大概长这样

dd

具体看这里https://blog.csdn.net/l1161558158/article/details/86569748

client

client依赖

 <dependency>
     <groupId>de.codecentric</groupId>
     <artifactId>spring-boot-admin-starter-client</artifactId>
     <version>2.1.2</version><!--版本要和springboot的版本对应-->
</dependency>

配置如下

spring:
    boot:
        admin:
            client:
                url: "http://127.0.0.1:8080" #server的地址
                instance:
                    name: agent-server #实例的名字,会显示在admin的页面上
                    prefer-ip: true #使用ip,否则的话默认使用主机名

之后启动应用的时候(没有开admin-server的时候)会显示这样子的一段错误,实测不影响使用,其实原理是client发起一次次http的请求

在这里插入图片描述

对接spring-admin和Prometheus

说是对接,实际上是prometheus借用spring-admin-server的web通道而已

alertmanager 的webhook使用的是post请求的一个json,这里我直接定义了两个Java类,映射到这个json

class AlarmInfo {
    String receiver;
    String status;
    List<Alert> alerts;
    Map<String,String > commonLabels;
    Map<String,String > groupLabels;
    Map<String,String > commonAnnotations;
    Map<String,String > annotations;
    String externalURL;
    String version;
}
 class Alert {
    String status;
    Map<String,String> labels;
    Map<String,String> annotations;
    Date startsAt;
    Date endsAt;
    String generatorURL;
}

然后需要开放一个接口供Prometheus使用

@Slf4j
@RestController
public class ReceiveAlarm {
    private final AlarmService alarmService;

    public ReceiveAlarm(AlarmService alarmService) {
        this.alarmService = alarmService;
    }

//    @ApiOperation(value = "发送告警",notes = "告警会插入到短信表中,然后会发送短信通知,实际上webhook可以做任何通知,电话,钉钉,邮件之类的")
    //实际上Prometheus自身集成了很多告警通知方式,邮件什么的可以直接使用
//    @ApiImplicitParam(name = "alarmInfo",required = true,dataType = "AlarmInfo")
    @RequestMapping(value = "/alarm")//这里配置的url就是提供给 alertmanager.yml的webhook
    public void receiveAlarm(@RequestBody AlarmInfo info){
        //这里是我的业务逻辑
        List<Alert> alerts = info.getAlerts();
        alerts.forEach(alert -> {
            Map<String, String> labels = alert.getLabels();
            String name=labels.get("name");
            String alertName=labels.get("alertname");
            Map<String, String> annotations = alert.getAnnotations();
            String description=annotations.get("description");
            alarmService.sendAlarm(alertName+" "+name,description);
        });
        log.info("{}",info);
    }
}

ps

后续会增加如何自定义端点,进行个性化的监控

发布了27 篇原创文章 · 获赞 6 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/l1161558158/article/details/88717151