微服务实践之量度监控(micrometer,prometheus,grafana)-SpringCloud(2021.0.x)-5

Posted ShuSheng007

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了微服务实践之量度监控(micrometer,prometheus,grafana)-SpringCloud(2021.0.x)-5相关的知识,希望对你有一定的参考价值。

[版权申明] 非商业目的注明出处可自由转载
出自:shusheng007

文章目录

前言

作为应用开发者你是否觉得监控应该是运维的活?嗯,大部分是这样的,例如监控服务器资源的情况,网络情况,监控redis服务器的情况,监控 myslq服务器的情况等等,但是有一些应用相关的指标我们开发者也是需要关心的,这就要求我们在开发过程中进行埋点。

由于微服务的流行,我们在一套系统中部署的服务越来越多,新催生出的角色DevOps也越来越关心统计应用系统的指标并从中进行学习推断系统的状况,老板也要直观的看到实时的下单量,成交金额等指标…

不过总的来说,监控离普通的业务开发者而言还是稍微有一点点远,但是了解一下是很有必要的

概念

目前在监控方面非常流行的做法是使用Prometheus搭配Grafana来实现

Prometheus(普罗米修斯)

官方介绍

The Prometheus monitoring system and time series database.

Prometheus是一个监控系统,也是一个时序数据库,它是目前在监控界非常耀眼,你应该多关注一下它…

其架构图如下:


那它如何工作呢?

假如现在我们要监控一下mysql的运行指标,那么我们就需要一个Mysql-exporter,就是一个程序,它可以采集mysql的运行指标,然后将其转化为普罗米修斯要求的格式。普罗米修斯定期找它pull数据,然后进行存储、展示或报警等操作。

本文只是简单介绍如何入门使用,不会对其架构进行深入的解析,有兴趣的小伙伴可以找相关资料学习。

Grafana

官方定义

Grafana: The open and composable observability and data visualization platform. Visualize metrics, logs, and traces from multiple sources like Prometheus, Loki, Elasticsearch, InfluxDB, Postgres and many more.

Grafana是一个数据可视化平台,你给它提供数据,它给你使用各种漂亮的图形展示出来。不过要配置一个漂亮的监控界面也不是一件容易的事情,幸好对于流行的监控场景已经有很多牛人画出了特别棒的Dashboard,它是json的形式存在的,你可以直接使用,一会我们一起看一下。

Micrometer

官方定义

An application metrics facade for the most popular monitoring tools. Think SLF4J, but for metrics.

它是Java生态中一个组件,官方介绍说的很清楚拉,你就把它理解为metric界的SLF4J就OK。

为什么会有这个一个东西呢?相信你听过要面向抽象编程,不要面向细节编程。因为某一个领域都不可能只有一个玩家,即使像国有垄断行业还都弄个两三家一起搞,防止一家独大呢,例如中国移动和中国联通,中石油和中石化等等,那么对于自由竞争的环境下那就更是如此了。像这个监控领域也存在很多个玩家,使用一个面板就可以将下面具体使用的实现细节给屏蔽了,我们只针对Micrometer来编程,而不关心下面使用的是哪个系统。

Micrometer支持如下监控系统:AppOptics, Azure Monitor, Netflix Atlas, CloudWatch, Datadog, Dynatrace, Elastic, Ganglia, Graphite, Humio, Influx/Telegraf, JMX, KairosDB, New Relic, Prometheus, SignalFx, Google Stackdriver, StatsD, Wavefront。

关键概念

其实对于初学者我觉得Micrometer也挺难的,我第一次看到可懵逼了,但是等你静下心稍微学习一下也就不难了,真的是万事开头难,当然在一个领域要达到一定的深度也很难,但是那种难和入门时候的难不是一种,你自己品吧…。好了,言归正传,要使用Micrometer需要理解各种metric的概念,至少要理解下面这几个概念。

Meter

Meter可以认为是你要搜集的各种量度(metric)的一个抽象吧。例如你要监控某个接口被调用了多少次需要用什么metric,你要监控某段时间内内存的使用情况需要用什么metric,等等。这些metric都叫Meter。Meter具体有很多种,我们只简绍常用的几个便于我们的示例可以往下走。

  • Counter

顾名思义,这就是一个计数器,但是单调递增的,只能一直往上加。例如你要统计某个API一天内被调用的次数就可以用这个。

  • Timer

用来描述某个操作耗时多长时间。但要注意操作一般耗时较短,例如你可以使用Timer来监控某个Api的执行耗时

  • Gauge(尺度)

用来描述某个可以上下浮动的监控量度。例如某段时间,JVM的内存使用情况,它的特点就是一会低了一会高了。

MeterRegistry

清楚了啥是Meter,那么还有一个概念需要了解,就是MeterRegistry。每个Meter都是要保存到MeterRegistry里面的,然后再把这些量度传递给其他监控系统,例如Prometheus。

Tag

Tag汉语的意思为标签,我们一般都会说:你不要给人家贴标签,别顿不顿就说人家是绿茶婊。你看我们可以通过给人贴标签来将人群分类,在监控界也是这么个意思。

例如老板说:我想看下天津地区5月的成交单量数据,如果你没有给成交单量这个Meter打上天津这个tag,你怎么查呢?所以说,tag这个玩意就是为了从不同维度来统计数据而生的。

理解了上面那些概念就差不多可以简单使用了,让我们开始吧。

安装环境

我们以docker来安装Prometheus与Grafana,下面是其docker-compose文件的一部分,完整的可以在文章后面的源码中查看。

...
  ms_prometheus:
    image: prom/prometheus:latest
    container_name: ms_prometheus
    ports:
      - 9090:9090
    volumes:
      - ~/software/prometheus/config/prometheus.yml:/etc/prometheus/prometheus.yml
      - ~/software/prometheus/data:/prometheus
    networks:
      ms_network:
        ipv4_address: 172.171.1.14
  ms_grafana:
    image: grafana/grafana:latest
    container_name: ms_grafana
    ports:
      - 3000:3000
    volumes:
      - ~/software/grafana/data:/var/lib/grafana
    networks:
      ms_network:
        ipv4_address: 172.171.1.15

其中普罗米修斯那个配置文件prometheus.yml需要关注一下。

# my global config
global:
  scrape_interval: 15s  #15 秒pull一次数据
  evaluation_interval: 15s #15秒计算一次
  ...

scrape_configs:
  - job_name: "prometheus"
    static_configs:
      - targets: ["172.171.1.14:9090"]

  - job_name: 'spring_micrometer'
    metrics_path: '/actuator/prometheus'
    scrape_interval: 5s
    static_configs:
      - targets: ['192.168.31.210:7001']

关键就两部分,global:部分设置一些全局的配置,而scrape_configs:则是具体配置各种exporter的地方。上面我们配置了两个,一个是prometheus本身,一个就是我们的micrometer,那个targets节点填写应用的坐标。

安装好了环境,我就开始集成测试。

实战

引入依赖

引入Micrometer与Prometheus的依赖。

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

<!--        metrics监控-->
        <dependency>
            <groupId>io.micrometer</groupId>
            <artifactId>micrometer-registry-prometheus</artifactId>
        </dependency>

其中micrometer-registry-prometheus 作为Prometheus的Micrometer-Expoter,Prometheus就是通过它来拉取我们程序的量度(metric)的。

配置

暴露actuator上的prometheus端点。

management:
  endpoints:
    web:
      exposure:
        include: prometheus,metrics, health,info

将我们集成了Micrometer的程序(现在它已经是一个exporter了)信息配置到普罗米修斯的配置文件中,注意因为我在docker-compose使用的是自定义网络,那个IP一定要写你本地的ip,不能写localhost,否则连接不上。

  - job_name: 'spring_micrometer'
    metrics_path: '/actuator/prometheus'
    scrape_interval: 5s
    static_configs:
      - targets: ['192.168.31.210:7001']

使用

运行应用程序,posman访问http://localhost:7001/actuator/prometheus,如果输出如下内容说明我们的程序可以正常输出prometheus格式的数据了:

# HELP jvm_gc_max_data_size_bytes Max size of long-lived heap memory pool
# TYPE jvm_gc_max_data_size_bytes gauge
jvm_gc_max_data_size_bytes 2.863661056E9
# HELP tomcat_sessions_active_current_sessions  
# TYPE tomcat_sessions_active_current_sessions gauge
tomcat_sessions_active_current_sessions 0.0
# HELP jvm_gc_pause_seconds Time spent in GC pause
# TYPE jvm_gc_pause_seconds summary
jvm_gc_pause_seconds_countaction="end of minor GC",cause="Allocation Failure", 584.0
jvm_gc_pause_seconds_sumaction="end of minor GC",cause="Allocation Failure", 2.511
# HELP jvm_gc_pause_seconds_max Time spent in GC pause
# TYPE jvm_gc_pause_seconds_max gauge
jvm_gc_pause_seconds_maxaction="end of minor GC",cause="Allocation Failure", 0.004
...

接下来看下,micrometer这个exporter是否已经成功连接到了prometheus服务器上没有,我们也可以访问:http://localhost:9090/,然后点击Status菜单里面的Targets就可以看到各种exporter的状态了。

从下图可以看到,我们的micrometer已经成功连接了,就是那个spring_micrometer。


如果看到连接成功了,我们就可查看那些监控metric了。actuator默认帮我们暴露了一些metric,通过访问http://localhost:7001/actuator/metrics可查看详情:


    "names": [
        "application.ready.time",
        "application.started.time",
        "disk.free",
        "disk.total",
        "executor.active",
        "executor.completed",
        "executor.pool.core",
        "executor.pool.max",
        "executor.pool.size",
        "executor.queue.remaining",
        "executor.queued",
        "goods.payment",
        "http.server.requests",
        "jvm.buffer.count",
        "jvm.buffer.memory.used",
        "jvm.buffer.total.capacity",
        "jvm.classes.loaded",
        "jvm.classes.unloaded",
        "jvm.gc.live.data.size",
        "jvm.gc.max.data.size",
        "jvm.gc.memory.allocated",
        "jvm.gc.memory.promoted",
        "jvm.gc.overhead",
        "jvm.gc.pause",
        "jvm.memory.committed",
        "jvm.memory.max",
        "jvm.memory.usage.after.gc",
        "jvm.memory.used",
        "jvm.threads.daemon",
        "jvm.threads.live",
        "jvm.threads.peak",
        "jvm.threads.states",
        "logback.events",
        "process.cpu.usage",
        "process.files.max",
        "process.files.open",
        "process.start.time",
        "process.uptime",
        "system.cpu.count",
        "system.cpu.usage",
        "system.load.average.1m",
        "tomcat.sessions.active.current",
        "tomcat.sessions.active.max",
        "tomcat.sessions.alive.max",
        "tomcat.sessions.created",
        "tomcat.sessions.expired",
        "tomcat.sessions.rejected",
		...
    ]

所以我们可以直接在prometheus中查看这些metric。例如下图我们查看了"jvm.memory.used"这个指标,这样我们就能看到内存的变化情况了。

自定义Metric

上面是actuator内置帮我们内置的一些metric,有时我们还需要自己在程序中埋点,例如我要监控某个方法的耗时。

  • 构建Meter

因为我们要监控方法耗时,所以应该是用Timer这个Meter。

@Slf4j
@Configuration
public class MetricsConfig 
    @Bean
    public TimedAspect timedAspect(MeterRegistry registry)
        log.info("meterRegistry类型:", registry.getClass().getCanonicalName());
        return new TimedAspect(registry);
    

其中那个MeterRegistry的具体实现类为io.micrometer.prometheus.PrometheusMeterRegistry,其由SpringBoot自动注入。前我们说过meter都是要先注册到MeterRegistry的,然后PrometheusMeterRegistry就会把meter信息交给prometheus服务器。

  • 触发meter

在要监控的方法上使用@Timed注解来标记,注意那个名称是以.号连接的。

    @Timed(value = "goods.payment",description = "商品服务的支付方法耗时")
    @Override
    public String payment(String orderId) 
		...
        return String.format("你已经成功购买:%s",result.getGoodsName());
    

通过上面两步我们就自定义了一个meter,我们请求一下方法,然后从prometheus上看下结果。

使用grafana展示

启动grafana服务端后,登录http://localhost:3000/用户名和密码都为:admin。

  • 添加prometheus为数据源

  • 添加dashboard


然后自己添加panel,自己添加metric就可以了,但是我画的是真心丑。

  • 导入社区中成熟的dashboard

如果你自己不会画dashboard还是去社区找找别人画的吧,然后import进来,这么丑完全征服不了老板啊…。

首先去https://grafana.com/grafana/dashboards/ 去搜索,例如我们这里使用micrometer,咱就搜索micrometer,然后选择一个你中意的,copy它的id。

然后到grafana中import进去。

结果如下,是不是瞬间就高大上了啊

小技巧:如果你必须自己配置dashboard可以先找一个别人画好的,然后在上面修改。其实大部分的通用监控都有社区提供的dashboard可以用。

总结

这块离运维比较近,离开发稍微有一丢丢远,不过微服务时代提倡敏捷开发,DevOps将dev与ops结合的越来越紧密,所以开发的小伙伴也应该了解一下,如果感兴趣可以去深挖,本文就到止为止拉…。

源码

一如既往,你可以从Github获得本文的源码master-microservice,星星点一点,猿猿不迷路…

以上是关于微服务实践之量度监控(micrometer,prometheus,grafana)-SpringCloud(2021.0.x)-5的主要内容,如果未能解决你的问题,请参考以下文章

微服务实践之网关(Spring Cloud Gateway)详解-SpringCloud(2021.0.x)-3

微服务实践之服务注册与发现(Nacos)-SpringCloud(2020.0.x)-1

spring cloud微服务实践四

微服务实践之通信(OpenFeign)详解-SpringCloud(2021.0.x)-6

微服务实践之通信(OpenFeign)详解-SpringCloud(2021.0.x)-6

微服务实践之负载均衡(Spring Cloud Load Balancer)-SpringCloud(2020.0.x)-2