微服务监控之三:Prometheus + Grafana Spring Boot 应用可视化监控

摘要:
一、Springboot增加Prometheus1、SpringBoot应用暴露监控指标,添加如下依赖org.springframework.bootspring-boot-starter-actuatorio.prom

一、Springboot增加Prometheus

1、Spring Boot 应用暴露监控指标,添加如下依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
    <groupId>io.prometheus</groupId>
    <artifactId>simpleclient_spring_boot</artifactId>
    <version>0.0.26</version>
</dependency>
gradle配置:
    compile 'org.springframework.boot:spring-boot-starter-actuator'
    compile 'io.prometheus:simpleclient_spring_boot:0.0.26'

2、然后,在启动类 Application.java 添加如下注解:

@SpringBootApplication
@EnablePrometheusEndpoint
@EnableSpringBootMetricsCollector
public classApplication {
    public static voidmain(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

3、配置文件设置

在application.xml里设置属性:spring.metrics.servo.enabled=false,  
去掉重复的metrics,不然在prometheus的控制台的targets页签里,会一直显示此endpoint为down状态。  
#应用可视化监控  
management.security.enabled=false
spring.metrics.servo.enabled=false  

4、访问:http://192.168.10.213:6010/prometheus,可以看到 Prometheus 格式的指标数据

微服务监控之三:Prometheus + Grafana Spring Boot 应用可视化监控第1张

二、自定义prometheus注解

2.1、自定义prometheus注解

import java.lang.annotation.*;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interfacePrometheusMetrics {
    /**
     * 默认为空,程序使用method signature作为Metric name 如果name有设置值,使用name作为Metric name
     * 
     * @return
     */
    String name() default "";
}

2.2、自定义prometheus切面

importio.prometheus.client.Counter;
importio.prometheus.client.Histogram;
importorg.apache.commons.lang3.StringUtils;
importorg.aspectj.lang.ProceedingJoinPoint;
importorg.aspectj.lang.annotation.Around;
importorg.aspectj.lang.annotation.Aspect;
importorg.aspectj.lang.annotation.Pointcut;
importorg.aspectj.lang.reflect.MethodSignature;
importorg.springframework.stereotype.Component;
importorg.springframework.web.context.request.RequestContextHolder;
importorg.springframework.web.context.request.ServletRequestAttributes;
importjavax.servlet.http.HttpServletRequest;
@Aspect
@Component
public classPrometheusMetricsAspect {
    private static final Counter requestTotal = Counter.build().name("couter_all").labelNames("api")
            .help("total request couter of api").register();
    private static final Counter requestError = Counter.build().name("couter_error").labelNames("api")
            .help("response Error couter of api").register();
    private static final Histogram histogram = Histogram.build().name("histogram_consuming").labelNames("api")
            .help("response consuming of api").register();
    //自定义Prometheus注解的全路径
    @Pointcut("@annotation(com....annotation.PrometheusMetrics)")
    public voidpcMethod() {
    }
    @Around(value = "pcMethod() && @annotation(annotation)")
    public Object MetricsCollector(ProceedingJoinPoint joinPoint, PrometheusMetrics annotation) throwsThrowable {
        MethodSignature methodSignature =(MethodSignature) joinPoint.getSignature();
        PrometheusMetrics prometheusMetrics = methodSignature.getMethod().getAnnotation(PrometheusMetrics.class);
        if (prometheusMetrics != null) {
            String name;
            if(StringUtils.isNotEmpty(prometheusMetrics.name())) {
                name =prometheusMetrics.name();
            } else{
                HttpServletRequest request =((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
                        .getRequest();
                name =request.getRequestURI();
            }
            requestTotal.labels(name).inc();
            Histogram.Timer requestTimer =histogram.labels(name).startTimer();
            Object object;
            try{
                object =joinPoint.proceed();
            } catch(Exception e) {
                requestError.labels(name).inc();
                throwe;
            } finally{
                requestTimer.observeDuration();
            }
            returnobject;
        } else{
            returnjoinPoint.proceed();
        }
    }
}

2.3、被监控的方法上添加--自定义prometheus注解

@PrometheusMetrics
    @PostMapping(value = "isBacklist")
    @ApiOperation(value = "黑名单判断", notes = "是否在黑名单中,如果存在并且记录状态为2,则为黑名单,返回true,否则返回:false")
    @Log
    public RespResult<Boolean> isBacklist(@RequestBody BacklistReqDTO reqDTO) {

三、Prometheus 采集 Spring Boot 指标数据

首先,获取 Prometheus 的 Docker 镜像:
docker pull prom/prometheus
3.1、然后,编写配置文件 prometheus.yml :
# my globalconfig
global:
  scrape_interval:     15s # Set the scrape interval to every 15 seconds. Default is every 1minute.
  evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1minute.
  # scrape_timeout is set to the global default(10s).
# Alertmanager configuration
alerting:
  alertmanagers:
  -static_configs:
    -targets:
      # - alertmanager:9093
# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
rule_files:
  # - "first_rules.yml"
  # - "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 thisconfig.
  - job_name: 'prometheus'
 # metrics_path defaults to '/metrics'
    # scheme defaults to 'http'.
static_configs:
- targets: ['10.200.110.100:8080']   #此处填写 Spring Boot 应用的 IP + 端口号
3.2、接着,启动 Prometheus :
docker run -d -p 9090:9090
-u root 
-v /opt/prometheus/tsdb:/etc/prometheus/tsdb 
-v /opt/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml 
--privileged=true prom/prometheus 
--storage.tsdb.path=/etc/prometheus/tsdb 
--storage.tsdb.retention=7d 
--config.file=/etc/prometheus/prometheus.yml
非docker环境的启动方式:
./prometheus --config.file=prometheus2.yml

结果:

duanxz@ubuntu:~/Downloads/prometheus-2.0.0.linux-amd64$ ./prometheus --config.file=prometheus2.yml
level=info ts=2018-06-19T08:27:47.222527495Z caller=main.go:215 msg="Starting Prometheus" version="(version=2.0.0, branch=HEAD, revision=0a74f98628a0463dddc90528220c94de5032d1a0)"
level=info ts=2018-06-19T08:27:47.222895906Z caller=main.go:216 build_context="(go=go1.9.2, user=root@615b82cb36b6, date=20171108-07:11:59)"
level=info ts=2018-06-19T08:27:47.223110655Z caller=main.go:217 host_details="(Linux 4.4.0-128-generic #154~14.04.1-Ubuntu SMP Fri May 25 14:58:51 UTC 2018 x86_64 ubuntu (none))"
level=info ts=2018-06-19T08:27:47.227443134Z caller=web.go:380 component=web msg="Start listening for connections" address=0.0.0.0:9090
level=info ts=2018-06-19T08:27:47.234616341Z caller=main.go:314 msg="Starting TSDB"
level=info ts=2018-06-19T08:27:47.244932582Z caller=targetmanager.go:71 component="target manager" msg="Starting target manager..."
level=info ts=2018-06-19T08:27:47.24608357Z caller=main.go:326 msg="TSDB started"
level=info ts=2018-06-19T08:27:47.246514727Z caller=main.go:394 msg="Loading configuration file" filename=prometheus2.yml
level=info ts=2018-06-19T08:27:47.247799187Z caller=main.go:371 msg="Server is ready to receive requests."
最后,访问http://127.0.0.1:9090/targets, 检查 Spring Boot 采集状态是否正常。

微服务监控之三:Prometheus + Grafana Spring Boot 应用可视化监控第2张

四、Grafana 可视化监控数据

首先,获取 Grafana 的 Docker 镜像:
docker pull grafana/grafana
然后,启动 Grafana:
docker run -d -p 3000:3000
-v /opt/grafana:/var/lib/grafana
-e "GF_SMTP_ENABLED=true"
-e "GF_SMTP_HOST=smtp.139.com:25"
-e "GF_SMTP_USER=13616052510@139.com"
-e "GF_SMTP_PASSWORD=like110120"
-e "GF_SMTP_FROM_ADDRESS=13616052510@139.com"
--privileged=true grafana/grafana
接着,访问http://localhost:3000/配置 Prometheus 数据源:
Grafana 登录账号 admin 密码 admin

五、常用Prometheus 表达式

QPS[5分钟]
rate(lz_http_requests_total{job="02_lzmh_microservice_base_service_docker"}[5m]) > 0
QPS[5分钟],根据handler分组
sum(rate(lz_http_requests_total{job="lzmh_microservice_weixin_applet_api"}[5m])) by (handler) > 0
平均响应时间[5分钟]
(
rate(lz_http_response_time_milliseconds_sum{job="02_lzmh_microservice_base_service_docker"}[5m])
/
rate(lz_http_response_time_milliseconds_count{job="02_lzmh_microservice_base_service_docker"}[5m])
) > 0
平均响应时间[5分钟],根据handler分组
sum(
rate(lz_http_response_time_milliseconds_sum{job="lzmh_microservice_weixin_applet_api"}[5m])
/
rate(lz_http_response_time_milliseconds_count{job="lzmh_microservice_weixin_applet_api"}[5m])
) by (handler) > 0

微服务监控之三:Prometheus + Grafana Spring Boot 应用可视化监控第3张

参考:http://www.spring4all.com/article/265

免责声明:文章转载自《微服务监控之三:Prometheus + Grafana Spring Boot 应用可视化监控》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇.NET实现微博粉丝服务平台接口DelphiXE7中创建WebService(服务端+客户端) good下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

2、Docker基础用法

容器镜像:https://hub.docker.com/ Docker架构图:https://ruby-china.org/topics/22004 Docker使用客户端-服务器(client-server)架构模式。Docker客户端会与Docker守护进程进行通信。Docker守护进程会处理复杂繁重的任务,例如建立、运行、发布你的Docker容器。...

Traefik-v2.x快速入门

一、概述 traefik与nginx一样,是一款优秀的反向代理工具,或者叫Edge Router。至于使用它的原因则基于以下几点 无须重启即可更新配置 自动的服务发现与负载均衡 与docker的完美集成,基于container label的配置 漂亮的dashboard界面 metrics的支持,对prometheus和k8s的集成 接下来讲一下它的...

【Docker】镜像分层存储与镜像精简

Linux操作系统### Linux操作系统由内核空间和用户空间组成。 内核空间是kernel,用户空间是rootfs, 不同Linux发行版的区别主要是rootfs.比如 Ubuntu 14.04 使用 upstart 管理服务,apt 管理软件包;而 CentOS 7 使用 systemd 和 yum。这些都是用户空间上的区别,Linux kernel...

Grafana数据可视化

1.1 Grafana简介 1.1.1 Grafana是什么? 一个类似Kibana的东西,也是对后端的数据进行实时展示,那么Grafana和Kibana有什么区别?在我看来区别不大,不过在大家的日常使用中Kibana是跟着Logstash、ElasticSearch等组件一起使用做日志展示、索引、分析的,造成了一种假象就是Kibana就只有这种用...

使用kubeadm部署K8S v1.17.0集群

环境信息 操作系统:CentOS Linux release 7.7.1908 (Core) docker:19.03.8 kubernetes:v1.17.0 集群信息 hostname IP k8s-master 192.168.87.10 k8s-node01 192.168.87.11 一、准备工作(所有节点执行) 1.1、...

Windows10安装Docker

1.下载和安装 1)下载地址:https://hub.docker.com/editions/community/docker-ce-desktop-windows/,直接下载 2)先检查是否开启电脑的虚拟化 依次控制面板->程序->启用或关闭Windows功能,把Hyper-v勾上。勾选后重启电脑 3)开启后双击下载的 "Docker D...