简介:SpringBoot 微服务的开发、发布与部署只占其生命周期的一小部分,应用和系统运维才是重中之重。而运维过程中,监控工作更是占据重要位置。那么,为了对系统的状态进行持续地观测,面向Spring Boot应用我们该如何快速实现Prometheus监控接入。本文为大家详细讲解完整接入流程与接入事项!

作者:凡星

对于开发者而言,大部分传统 SSM 结构的 MVC 应用背后的糟糕体验都是来自于搭建项目时的大量配置,稍有不慎就可能踩坑。为了解决上述问题,Spring Boot 应运而生。正如其名,Spring Boot 的核心价值就是自动配置,只要存在相应 jar 包,Spring 可以自动配置。如果默认配置不能满足需求,还可以替换掉自动配置类,使用自定义配置,快速构建企业级应用程序。

但构建 Spring Boot 应用只是第一步,随着应用上线之后,我们又该如何进行监测?

基础知识及概念

首先,在正式讲解前,先向大家讲解本次分享所需要的基本知识和概念。一般来说,搭建一套完整易用的监测系统主要包含以下几个关键部分。

收集监测数据

目前,行业常见的收集监测数据方式主要分为推送(Push)和抓取(Pull)两个模式。以越来越广泛应用的 Prometheus 监测体系举例,Prometheus 就是以抓取(Pull)模式运行的典型系统。应用及基础设施的监测数据以 OpenMetrics 标准接口的形式暴露给 Prometheus,由 Prometheus 进行定期抓取并长期存储。

这里简单介绍一下 OpenMetrics。作为云原生、高度可扩展的指标协议, OpenMetrics 定义了大规模上报云原生指标的事实标准,并支持文本表示协议和 Protocol Buffers 协议,文本表示协议在其中更为常见,也是在 Prometheus 进行数据抓取时默认采用的协议。下图是一个基于 OpenMetrics 格式的指标表示格式样例。

指标的数据模型由指标(Metric)名,以及一组 key/value 标签(Label)定义的,具有相同的度量名称以及标签属于相同时序集合。例如  acme_http_router_request_seconds_sum{path="/api/v1",method="GET"} 可以表示指标名为 acme_http_router_request_seconds_sum,标签 method 值为 POST 的一次采样点数据。采样点内包含一个 float64 值和一个毫秒级的 UNIX 时间戳。随着时间推移,这些收集起来的采样点数据将在图表上实时绘制动态变化的线条。

目前,对于云原生体系下的绝大多数基础组件,大多能够支持以上面提到的 OpenMetrics 的文本协议格式暴露指标,对于尚未能够支持自身暴露指标的组件, Prometheus 社区也存在极其丰富的 Prometheus Exporter 供开发及运维人员使用。这些组件(或 Exporter)通过响应来自 Prometheus 的定期抓取请求来及时地将自身的运行状况记录到 Prometheus 以便后续的处理及分析。对于应用开发者,还可以通过 Prometheus 多语言 SDK,进行代码埋点,将自身的业务指标也接入到上述的 Prometheus 生态当中。

数据可视化及分析

在获取应用或基础设施运行状态、资源使用情况,以及服务运行状态等直观信息后,通过查询和分析多类型、多维度信息能够方便的对节点进行跟踪和比较。同时,通过标准易用的可视化大盘去获知当前系统的运行状态。比较常见的解决方案就是 Grafana,作为开源社区中目前热度很高的数据可视化解决方案,Grafana 提供了丰富的图表形式与模板。在阿里云 ARMS Prometheus 监控服务中,也基于 Grafana 向用户提供了全托管版的监测数据查询、分析及可视化。

及时的告警和应急管理

当业务即将出现故障时,监测系统需要迅速反应并通知管理员,从而能够对问题进行快速的处理或者提前预防问题的发生,避免出现对业务的影响。当问题发生后,管理员需要对问题进行认领和处理。通过对不同监测指标以及历史数据的分析,能够找到并解决根源问题。

接入流程概览

接下来,我们讲讲面向部署在 Kubernetes 集群上的 Spring Boot 微服务应用如何进行 Prometheus 接入。针对 Spring Boot 应用,社区提供了开箱即用的 Spring Boot Actuator 框架,方便 Java 开发者进行代码埋点和监测数据收集、输出。从 Spring Boot 2.0 开始,Actuator 将底层改为 Micrometer,提供了更强、更灵活的监测能力。Micrometer 是一个监测门面,可以类比成监测界的 Slf4j 。借助 Micrometer,应用能够对接各种监测系统,例如:AppOptics,Datadog,Elastic,InfluxDB 等,当然,也包括我们今天所介绍的 Prometheus。

Micrometer 在将 Prometheus 指标对接到 Java 应用的指标时,支持应用开发者用三个类型的语义来映射:

  • MicroMeter 中的 Counter 对应于 Prometheus 中的 Counter,用来描述一个单调递增的变量,如某个接口的访问次数,缓存命中/访问总次数等。Timer 在逻辑上蕴含了 Counter,即如果使用 Timer 采集每个接口的响应时间,必然也会采集访问次数。故无需为某个接口同时指定 Timer 与 Counter 两个指标
  • MicroMeter 中的 Gauge 对应于 Prometheus 中的 Gauge,用来描述在一个范围内持续波动的变量,如 CPU 使用率,线程池任务队列数等。
  • MicroMeter 中的 Timer 对应于 Prometheus 中的 Histogram,用来描述与时间相关的数据,如某个接口 RT 时间分布等等。
  • Micrometer 中的 DistributionSummary 对应 Prometheus 中的 Summary ,与  Histogram 类似,Summary 也是用于统计数据分布的,但由于数据的分布情况是在客户端计算完成后再传入 Prometheus 进行存储,因此 Summary 的结果无法在多个机器之间进行数据聚合,无法统计全局视图的数据分布,使用起来有一定局限性。

当我们需要把部署在 Kubernetes 集群中的 Spring Boot 应用接入到 Prometheus 时,需要按照代码埋点->部署应用->服务发现这个流程来进行。

首先,我们需要在代码中引入 Spring Boot Actuator 相关 maven 依赖,并对我们需要监测的数据进行注册,或对 Controller 内的方法打上响应的注解。

其次,我们将埋点后的应用部署在 Kubernetes 中,并向 Prometheus 注册向应用拉取监测数据的端点(也就是 Prometheus 服务发现)。阿里云 Prometheus 服务提供了使用 ServiceMonitor CRD 进行服务发现的方法。

最后在目标应用的监测采集端点被 Prometheus 成功发现后,我们就可以开始在 Grafana 上面配置数据源及相应的大盘了。当然,我们同时也需要根据某些关键指标进行对应的告警配置。这些需求在阿里云 Prometheus 监控服务都能很方便地满足。

接入流程详解

接下来,我们进入实战演练环节,这里选取一个基于 Spring Boot & Spring Cloud Alibaba 构建的云原生微服务应用(https://github.com/aliyun/alibabacloud-microservice-demo)作为我们改造的基线。

我们最终目标是:

1、监测系统的入口:Frontend 服务是一个基于 SpringMVC 开发的入口应用,承接外部的客户流量,我们主要关注的是外部接口的关键 RED 指标(调用率 Rate,失败数 Error,请求耗时 Duration);

2、监测系统的关键链路:对后端服务 critical path 上的对象进行监测,如线程池的队列情况、进程内 Guava Cache 缓存的命中情况;

3、对业务强相关的自定义指标(比如某个接口的 UV 等等);

4、对 JVM GC 及内存使用情况进行监测;

5、对上述指标进行统一汇聚展示、以及配置关键指标的告警。

第一步,引入 Spring Boot Actuator 依赖,进行初始配置

首先,我们需要引入 Spring Boot Actuator 的相关依赖,在 application.properties 配置中暴露监测数据端口(这里定义为 8091)。成功后,我们即可访问应用的 8091 端口的/actuator/prometheus 路径拿到 OpenMetrics 标准的监测数据。

<!-- spring-boot-actuator依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- prometheus依赖 -->
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
# application.properties添加以下配置用于暴露指标
spring.application.name=frontend management.server.port=8091
management.endpoints.web.exposure.include=*
management.metrics.tags.application=${spring.application.name}

第二步,代码埋点及改造

为了获取某个 Api 接口的 RED 指标,我们需要在对应的接口方法上打下面的 @Timed 注解。我们以演示项目中的 index 页面接口为例。注意这里,@Timed 注解中的 value 即为暴露到/actuator/prometheus 中的指标名字,histogram=true 表示我们暴露这个接口请求时长的 histogram 直方图类型指标,便于我们后续计算 P99,P90 等请求时间分布情况。

@Timed(value = "main_page_request_duration", description = "Time taken to return main page", histogram = true)
@ApiOperation(value = "首页", tags = {"首页操作页面"})
@GetMapping("/")
public String index(Model model) {
model.addAttribute("products", productDAO.getProductList()); model.addAttribute("FRONTEND_APP_NAME", Application.APP_NAME);
model.addAttribute("FRONTEND_SERVICE_TAG", Application.SERVICE_TAG);
model.addAttribute("FRONTEND_IP", registration.getHost()); model.addAttribute("PRODUCT_APP_NAME", PRODUCT_APP_NAME);
model.addAttribute("PRODUCT_SERVICE_TAG", PRODUCT_SERVICE_TAG);
model.addAttribute("PRODUCT_IP", PRODUCT_IP); model.addAttribute("new_version", StringUtils.isBlank(env));
return "index.html";
}

如果我们的应用中使用了进程内缓存库,比如最为常见的 Guava Cache 库等等。如果我们想追踪进程内缓存的运行状况,我们需要按照 Micrometer 提供的修饰方法,对待监测的关键对象进行封装。

  • Guava Cache 改造主要是四步骤,代码改动比较小,很容易就可以接入:

1、注入 MeterRegistry,这里注入的具体实现是 PrometheusMeterRegistry,由 Spring Boot 自行注入即可

2、使用工具类 api,即图中展示的 GuavaCacheMetrics.monitor 包装一下本地缓存

3、开启缓存数据记录,即调用一下.recordStats()方法

4、增加一个名称,用于生成对应的指标。

  • 线程池改造主要是三步骤,也并不是很复杂:

1、注入 MeterRegistry,这里注入的具体实现是 PrometheusMeterRegistry;

2、使用工具类 api 包装一下线程池;

3、增加一个名称,用于生成对应的指标。

当然,我们在开发过程中一定还有许多业务强相关的自定义指标,为了监测这些指标,我们在向 Bean 中注入 MeterRegistry 后,需要按照我们的需求和对应场景构造 Counter,Gauge 或 Timer(这些类型的区别和使用场景上文有提到)来进行数据统计,并将其注册到 MeterRegistry 进行指标暴露,下面是一个简单的例子。

@Service
public class DemoService { Counter visitCounter; public DemoService(MeterRegistry registry) {
visitCounter = Counter.builder("visit_counter")
.description("Number of visits to the site")
.register(registry);
} public String visit() {
visitCounter.increment();
return "Hello World!";
}
}

至此,我们的应用代码改造工作到这里就全部完成了,下一步工作就是将应用镜像重新构建并重新部署到已安装 ARMS Prometheus 的 Kubernetes 集群中。之后,我们 ARMS Prometheus 控制台中配置 ServiceMonitor,进行服务发现。

添加好 ServiceMonitor 后,我们可以在 Targets 列表中看到刚注册的应用 Service。

第三步,看板配置

应用的监测数据已成功收集并存储到 ARMS Prometheus。接下来,也是最关键的一步,就是根据这些数据,配置相应的大盘及告警。这里,我们借助 Grafana 社区中开源大盘模板来构建我们自己的业务监测模板。主要基于以下两个模板:

  • Spring Boot 2.1 Statistics:

Spring Boot 2.1 Statistics dashboard for Grafana | Grafana Labs

  • JVM (Micrometer):

JVM (Micrometer) dashboard for Grafana | Grafana Labs

借助这些模板以及 ARMS Prometheus 内置的 Grafana 服务,我们可以很方便地将日常开发和运维过程中非常关心的指标组织在一张的 Grafana Dashboard 上。这里给大家抛砖引玉一下,放一张我们内部基于上述模板和自身业务构建的一个真实的大盘。这里面包含了一些总览,比如组件运行时间,内存使用率等等,也有一些细节指标,如堆内堆外内存,分代 GC 情况等等,还有像接口请求的 RED 等等,这里就不过多赘述了,大家可以充分发挥自己的想象力来创造独一无二的酷炫大盘~

原文链接

本文为阿里云原创内容,未经允许不得转载。

最佳实践|Spring Boot 应用如何快速接入 Prometheus 监控的更多相关文章

  1. Spring Boot WebFlux-01——WebFlux 快速入门实践

    第01课:WebFlux 快速入门实践 Spring Boot 2.0 spring.io 官网有句醒目的话是: BUILD ANYTHING WITH SPRING BOOT Spring Boot ...

  2. 《深入实践Spring Boot》阅读笔记之一:基础应用开发

    上上篇「1718总结与计划」中提到,18年要对部分项目拆分,进行服务化,并对代码进行重构.公司技术委员会也推荐使用spring boot,之前在各个技术网站中也了解过,它可以大大简化spring配置和 ...

  3. Spring Boot 学习(一) 快速搭建SpringBoot 项目

    快速搭建一个 Spring Boot 项目 部分参考于<深入实践Spring Boot>.<Spring实战 第四版>与程序猿DD的有关博客. 参考(嘟嘟独立博客):http: ...

  4. spring boot / cloud (十七) 快速搭建注册中心和配置中心

    spring boot / cloud (十七) 快速搭建注册中心和配置中心 本文将使用spring cloud的eureka和config server来搭建. 然后搭建的模式,有很多种,本文主要聊 ...

  5. 《深入实践Spring Boot》阅读笔记之三:核心技术源代码分析

    刚关注的朋友,可以回顾前两篇文章: 基础应用开发 分布式应用开发 上篇文章总结了<深入实践Spring Boot>的第二部分,本篇文章总结第三部分,也是最后一部分.这部分主要讲解核心技术的 ...

  6. 《深入实践Spring Boot》阅读笔记之二:分布式应用开发

    上篇文章总结了<深入实践Spring Boot>的第一部分,这篇文章介绍第二部分:分布式应用开发,以及怎么构建一个高性能的服务平台. 主要从以下几个方面总结: Spring Boot SS ...

  7. Spring Boot 2.x 快速入门(下)HelloWorld示例详解

    上篇 Spring Boot 2.x 快速入门(上)HelloWorld示例 进行了Sprint Boot的快速入门,以实际的示例代码来练手,总比光看书要强很多嘛,最好的就是边看.边写.边记.边展示. ...

  8. Spring boot 集成 Dubbo 快速搭建

    架构: 1.ZooKeeper:服务注册中心 2.api工程:提供对外暴露的服务API 3.provider:服务提供者 4.consumer:服务消费者 示例如下: (一)新建 Maven 项目 a ...

  9. Spring Boot 2.0 快速集成整合消息中间件 Kafka

    欢迎关注个人微信公众号: 小哈学Java, 每日推送 Java 领域干货文章,关注即免费无套路附送 100G 海量学习.面试资源哟!! 个人网站: https://www.exception.site ...

  10. Spring Boot 2.x 快速集成Kafka

    1 Kafka Kafka是一个开源分布式的流处理平台,一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者在网站中的所有动作流数据.Kafka由Scala和Java编写,2012年成为Apache ...

随机推荐

  1. JSF之常用注解

    @ManagedBean 以托管 bean 的形式注册一个类实例,然后将其放入到使用其中一个 @...Scoped 注释指定的范围内.如果没有指定任何范围,JSF 将把此 bean 放入请求范围,如果 ...

  2. LeNet-5 论文及原理分析(笨鸟角度)

    PS:要转载请注明出处,本人版权所有. PS: 这个只是基于<我自己>的理解, 如果和你的原则及想法相冲突,请谅解,勿喷. 前置说明   本文作为本人csdn blog的主站的备份.(Bl ...

  3. Sealos 云开发:Laf 出嫁了,与 Sealos 正式结合!

    千呼万唤始出来,Laf 云开发最近已正式与 Sealos 融合,入住 Sealos!大家可以登录 Sealos 公有云 体验和使用,现在正式介绍一下 Sealos 云开发. Sealos 云开发是什么 ...

  4. ElasticSearch8 - SpringBoot整合ElasticSearch

    前言 springboot 整合 ES 有两种方案,ES 官方提供的 Elasticsearch Java API Client 和 spring 提供的 [Spring Data Elasticse ...

  5. 工具推荐--DRAWIO流程图软件

    简介 DRAWIO是一款开源的流程图软件,可以快速绘制各种流程图,支持图形导入和图像插入,且可以类似excel一样分页,能够以最简介的方式实现最复杂的功能; 基础功能 作为一款流程图软件,绘制流程图的 ...

  6. KingbaseES V8R3集群运维案例之---主库数据库服务down后failover切换详解

    案例说明: 对KingbaseES V8R3集群,主库数据库服务down后,failover切换进行分析,详解其执行切换的过程,本案例可用于对KingbaseES V8R3集群failover故障的分 ...

  7. KingbaseESV8R6延迟提交参数

    前言 队列理论在我们生活中的应用随处可见,例如我们去食堂打饭需要排队,我们生活中随处可见排队的场景. 在计算机领域中,性能诊断等地方使用队列理论的案例也很多.服务器硬件分为动态设备和静态设备.CPU和 ...

  8. 冒泡排序【Java】

    1 public class Paixu { 2 public static void main(String args[]) { 3 int myNum[] = {2,6,4,1,5}; 4 //从 ...

  9. 一种基于DeltaE(CIE 1976)的找色算法Cuda实现

    书接上文 一种基于DeltaE(CIE 1976)的找色算法 Delta E 是评估色彩准确度的重要测量指标.摄影师.影片编辑和平面设计师等创意专业人士都应重视这项标准,因其是选择专业级显示器的重要考 ...

  10. 空间音频技术与生态发展高峰论坛成功举办,业界首个Audio Vivid创作工具花瓣三维声亮相

    11月26日至27日,UWA世界超高清视频产业联盟(以下简称"UWA联盟").上海交通大学-南加州大学文化创意产业学院.华为联合举办了"互联智慧,共赢未来" 超 ...