一文搞懂基于 Prometheus Stack 监控 Java 容器

简介: Hello folks,我是 Luga,今天我们来分享一下如何基于 Prometheus Stack 可视化监控运行在 Kubernetes Cluster 上的 Spring Boot 微服务容器实例。这里,主要针对每一个 Java 容器实例的指标进行监控,具体涉及:CPU、内存、线程信息、日志信息、HTTP 请求以及 JVM 等。

    Hello folks,我是 Luga,今天我们来分享一下如何基于 Prometheus Stack 可视化监控运行在 Kubernetes Cluster 上的 Spring Boot 微服务容器实例。这里,主要针对每一个 Java 容器实例的指标进行监控,具体涉及:CPU、内存、线程信息、日志信息、HTTP 请求以及 JVM 等。

01

背景概述


    随着云原生技术体系的崛起以及周边生态理念的日渐成熟,越来越多的公司开始将自身原有的基于传统模型的业务开始迁移至云原生,然而,随着迁移的不断进行,而原有的观测模式也逐渐发生变化,从而使得原有的技术体系在新的生态环境中开始出现水土不服。

    在传统的监控模型体系中,由于所构建的微服务大多数都是运行在传统的虚拟机平台,使得数据的获取相对来说比较容易,无论这些微服务是基于传统的 Zabbix 组件还是新兴的 Prometheus 平台。然而,基于云化改造后的微服务实例,它们以成千上万个 Pod 模型运行在 Kubernetes Cluster 中提供服务,并且分布在不同的 Namespace 中,除此之外,这些 Pod 可能因各种不同的原因频繁重启或重建,导致其对应的 IP 地址发生变化,使得容器中实例的数据采集以及监控成为一个头痛的难题。

02

技术方案

    基于不同的业务场景需求,我们的技术方案参考模型,如下图所示:

    基于上述模型图,我们可以看到,假设 Spring Boot 微服务组件以 Pod 形式运行,我们需要借助相关插件将其内部所关联的指标信息进行暴露并予以 Prometheus 组件采集、加工分析,然后将其展现或对接至第三方系统进行维护。

    在本方案的实现过程中,我们需要重点关注以下 2 部分核心内容,具体如下所示:

    1、集成 Actuator 与 Micrometer 插件

    通常情况下,若我们基于 Prometheus 进行应用级别的数据采集及观测,那么,需要在 Spring Boot 应用中使用 Spring Boot Actuator 插件监控应用、暴露指标,并使用 Micrometer Prometheus 将 Actuator 监控指标转换为 Prometheus 格式。

    同时,Micrometer 为 Java 平台上的性能数据收集提供了一个通用的 API,类似于 SLF4J ,只不过它关注的不是 Logging(日志),而是 Application Metrics(应用指标)。

    2、配置 Prometheus 自动发现

    作为一个开源系统监控和告警工具链组件, 基于其特性,Prometheus 能够采集相关监控指标,并存储为时间序列数据,同时,Prometheus 还提供了灵活的查询语言 PromQL 来查询数据。

    Prometheus 通过拉模型采集指标,因此,我们需要在 Prometheus 集群中配置服务发现(Service Monitor)来定期从应用中抓取指标。

03

实现思路及策略


    在上面的章节中,我们已大概的规划出整体的技术实现方案:Pod 中取数据——>存放 Prometheus——>数据展现等。从上面的流程来看,整个数据的提取、加工以及到展现并非我们想象的那么难以搞定。

    这里,笔者主要分享常用的 2 种方案供大家参考,具体如下。

    1、基于 Service 实现

    言简意赅,即在 Kubernetes Cluster 中,我们需要通过 Service 对外提供 Spring Boot 应用的指标接口。

    基于业务需要,我们的 Spring Boot 微服务组件以 Pod 形式运行在 Kubernetes Cluster 中,因此,需要为 Pod 添加 Service 以便对外提供 HTTP 服务,这样 Prometheus 才可以抓取监控指标。

    具体模型如下所示:

    如下为一个简单的添加 Service 的 Yaml 文件示例,具体可参考:


apiVersion: v1
kind: Service
metadata:
  labels:
    app: spring-boot-demo-exporter
  name: spring-boot-demo-exporter
  namespace: default
spec:
  ports:
    - name: spring-boot-demo-exporter
      port: 9999
      protocol: TCP
      targetPort: 9999
  selector:
    app: spring-boot-demo
  type: NodePort

    这里需要注意的是 spec.selector 需要与 Pod 的标签对应。例如,我们使用 Deployment 进行应用部署,那么,则需要与 Deployment 的 spec.template.metadata.labels 对应,这样 Service 才能知道对应的 Pod。

    在实际的业务场景中,我们基于 Kubernetes 的 Service 实现了监控 Pod 中 Java应用的相关信息,可能是最常见的一种方案。但其实这并不适用于所有的环境,毕竟,基于不同的架构设计,在实际环境中并不是所有的 Pod(微服务)都会有自己对应的 Service,所以那些没有使用到 Service 的 Pod 就无法通过 Service 这种机制来实现微服务应用层面的监控。

   2、基于 Pod Controller 实现

    此种实现主要基于 JMX Exporter 暴露 JVM 监控指标然后进行数据的采集及监控展示。

    与 Service 不同的是,作为一种 Sidecar Docker 容器, JMX Exporter 用于将Prometheus JMX Exporter 注入到我们所构建的 Kubernetes Cluster 中的 Java 应用程序中,然后将相关数据进行暴露。

    具体模型如下所示:

    针对 JMX Exporter,需要将其相关参数定义或添加至 Deployment 或 StatefulSet 的 initContainers 中,如下为一个简单的添加 Service 的 Yaml 文件示例,具体可参考:


...
spec:
  initContainers:
  - name: prometheus-jmx-exporter
    image: spdigital/prometheus-jmx-exporter-kubernetes:0.3.1
    env:
    - name: SHARED_VOLUME_PATH
      value: /shared-volume
    volumeMounts:
    - mountPath: /shared-volume
      name: shared-volume
...

    通常,定义的 init 容器和我们所部署的的 Spring Boot 组件容器将共享一个卷,具体如下所示:


volumes:
- name: shared-volume
  emptyDir: {}

    同时,在 Spring Boot 组件容器中,将 JAVA_OPTS 设置为引用 prometheus-jmx-exporter 容器放置到共享卷中的文件,具体如下所示:


- name: JAVA_OPTS
  value: -javaagent:/shared-volume/jmx_prometheus_javaagent.jar=19000:/shared-volume/configs/springboot-config.yaml

    当然,除了上述最为常见的实现策略外,市面上也有其他可参考的成熟案例可供参考,例如 sfKubeAgent 等,作为一个 Sidecar 容器,监控应用程序 Pod 的 JVM 相关指标信息等。

04

部署实施


    针对上述 2 种不同的技术实现而言,前置的部署相对来说,基本上都相差无几,具体差异主要体现在技术细节层面。接下来,我们简要地描述一下整个监控流程的相关部署操作。

    这里,我主要以基于 Service 实现方式进行部署实施,具体如下:

    1、业务应用配置

    在 POM.XML 文件中引入相关插件,具体如下所示:


...
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <!--桥接Prometheus-->
    <dependency>
      <groupId>io.micrometer</groupId>
      <artifactId>micrometer-registry-prometheus</artifactId>
      <version>1.6.0</version>
    </dependency>
    <!--micrometer核心包, 按需引入, 使用Meter注解或手动埋点时需要-->
    <dependency>
      <groupId>io.micrometer</groupId>
      <artifactId>micrometer-core</artifactId>
      <version>1.6.0</version>
    </dependency>
    <!--micrometer获取JVM相关信息, 并展示在Grafana上-->
    <dependency>
      <groupId>io.github.mweirauch</groupId>
      <artifactId>micrometer-jvm-extras</artifactId>
      <version>0.2.0</version>
    </dependency>
...

    通常情况下,由于 Spring Boot Actuator 因为安全原因默认只开启了 Health 和 Info 接口,故此,我们需要调整下 application.yml 文件,将 Prometheus 组件相关接口开放,具体配置可参考如下:


# metircs
management:
  endpoints:
    web:
      exposure:
        include: prometheus, health
  metrics:
    export:
      simple:
        enabled: false
    tags:
      application: ${spring.application.name}

    至此,应用配置已更新完成,我们可以通过 /actuator/prometheus 接口查看配置是否生效,具体如下所示:


[leonli@Leon ~ ] % curl 'http://localhost:8080/actuator/prometheus' -i -X GET

    2、Prometheus 自动发现配置

    在实际生产环境中,每个服务都有对应的 Service,而此 Service 下面通常会挂载有较多 Pod,此时,我们需要通过 Prometheus 的自动发现来将所有实例 Metrics 信息进行采集。毕竟,Kubernetes Cluster 中的 Prometheus 可以基于 Kubernetes Cluster 自身的机制完成此项操作。

    此时,我们需要在所部署的微服务的 Yaml 文件中定义 annotations,主要用于自动发现,具体如下所示:


...
  annotations:
    prometheus.io/port: "7070" #端口配自己服务的端口
    prometheus.io/spring: "true"
    prometheus.io/path: "actuator/prometheus"
...

    备注:

    上述参数主要配置在 Service 的 metadata 中,具体可参考上述文件配置。

    然后,我们在 Prometheus 配置文件中添加 Spring Boot 项目 Metrics 相关信息,具体可参考如下:


...
      - job_name: 'spring metrics'
        kubernetes_sd_configs:
        - role: endpoints
        relabel_configs:
        - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_spring]
          action: keep
          regex: true
        - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_path]
          action: replace
          target_label: __metrics_path__
          regex: (.+)
        - source_labels: [__address__, __meta_kubernetes_service_annotation_prometheus_io_port]
          action: replace
          target_label: __address__
          regex: ([^:]+)(?::\d+)?;(\d+)
          replacement: $1:$2
        - action: labelmap
          regex: __meta_kubernetes_service_label_(.+)
        - source_labels: [__meta_kubernetes_namespace]
          action: replace
          target_label: spring_namespace
        - source_labels: [__meta_kubernetes_service_name]
          action: replace
          target_label: spring_name
...

    完成如上的配置后,重新进行配置文件加载操作,此时,我们在 Prometheus 控制台可以看到新加进来的 Target 信息。此时,整个监控部署实施完成。

    Adiós !

相关文章
|
1天前
|
存储 安全 Java
Java容器类List、ArrayList、Vector及map、HashTable、HashMap
Java容器类List、ArrayList、Vector及map、HashTable、HashMap
|
3天前
|
Kubernetes Java 调度
Java容器技术:Docker与Kubernetes
Java容器技术:Docker与Kubernetes
13 0
|
5天前
|
存储 设计模式 算法
【C++/STL】stack和queue(容器适配器、优先队列、双端队列)
【C++/STL】stack和queue(容器适配器、优先队列、双端队列)
11 1
|
11天前
|
Prometheus 监控 Cloud Native
使用Prometheus配置监控与报警
通过以上步骤,你可以使用Prometheus和Alertmanager实现监控和报警配置,以确保系统在出现性能问题或故障时能够及时通知相关人员。欢迎关注威哥爱编程,一起学习成长。
|
11天前
|
存储 Java 索引
【亮剑】Java中的并发容器ConcurrentHashMap,它在JDK1.5中引入,用于替换HashTable和SynchronizedMap
【4月更文挑战第30天】本文介绍了Java中的并发容器ConcurrentHashMap,它在JDK1.5中引入,用于替换HashTable和SynchronizedMap。文章展示了创建、添加、获取、删除和遍历元素的基本用法。ConcurrentHashMap的内部实现基于分段锁,每个段是一个独立的Hash表,通过分段锁实现并发控制。每个段内部采用数组+链表/红黑树的数据结构,当冲突过多时转为红黑树优化查询。此外,它有扩容机制,当元素超过阈值时,会逐段扩容并翻倍Segment数量,以保持高性能的并发访问。
|
13天前
|
Prometheus 监控 Cloud Native
构建高效的Docker容器监控体系
【4月更文挑战第28天】 在微服务架构和容器化部署日益普及的今天,对容器进行有效的性能监控成为确保系统稳定性的关键。本文将深入探讨如何构建一个高效的Docker容器监控体系,覆盖从监控指标的选择、数据采集、存储到可视化展示的全流程。我们将分析现有监控工具的优势与局限,并提出一种综合使用Prometheus、Grafana和自定义监控脚本的解决方案,旨在为运维人员提供实时、准确的容器监控数据,帮助快速定位并解决潜在问题。
16 1
|
17天前
|
存储 算法 Java
盘点Java集合(容器)概览,Collection和Map在开发中谁用的最多?
盘点Java集合(容器)概览,Collection和Map在开发中谁用的最多?
30 0
|
22天前
|
JavaScript Java 测试技术
基于Java的新冠病毒校园监控平台的设计与实现(源码+lw+部署文档+讲解等)
基于Java的新冠病毒校园监控平台的设计与实现(源码+lw+部署文档+讲解等)
22 0
|
22天前
|
运维 监控 Java
Java 性能监控和故障排查技巧
【4月更文挑战第19天】Java应用的开发与运行需重视性能监控和故障排查,以确保稳定性和可靠性。利用日志记录、系统性能指标和VisualVM等工具进行监控。通过错误日志分析、分阶段测试、内存和线程分析来排查问题。关注性能瓶颈定位,并提前规划、定期监控,提升数据分析能力和团队协作,以优化应用性能。
|
23天前
|
存储 运维 监控
构建高效稳定的Docker容器监控体系
【4月更文挑战第18天】 在现代微服务架构中,Docker容器已成为部署和运行应用的标准环境。随之而来的挑战是如何有效监控这些容器的性能与健康状况,确保系统的稳定性和可靠性。本文将探讨构建一个高效稳定的Docker容器监控体系的关键技术和方法,包括日志管理、性能指标收集以及异常检测机制,旨在为运维人员提供实用的指导和建议。

热门文章

最新文章