大數據

SLS時序監控實戰: Spring Boot應用監控最佳實踐

前言
當今隨著雲原生和微服務的盛行, 我們的應用的運行環境也變得越來越複雜, 也使得我們越來越難以掌握它的運行狀態, 也因此誕生了一批開源軟件來幫助我們提升應用的可觀察性, 例如prometheus, grafana, open tracing, open telementry等, 這些多半是比較通用的技術, 在實際的場景下, 我們需要怎麼從各個層面來做監控和數據的分析呢, 我們就以大家使用最多的技術棧: Java + Spring Boot為例, 來詳細闡述應用監控的最佳實踐

監控軟件選型

採集, 存儲, 查詢: Prometheus

在雲原生領域, Prometheus幾乎已經是監控的標準, 它也有著豐富的生態, 支持從操作系統, 數據庫, 到各類中間件的監控, 對各種語言也都提供了相應的SDK, 關於Prometheus的介紹我們不再贅述. 本文就選擇Prometheus作為基礎的監控軟件, 圍繞它展開監控最佳實踐
但Prometheus也有它的問題: 如數據無法長時間存儲, 大數據量下無法拓展, 只能單機運行等
而SLS的時序存儲恰好解決了這些問題, 支持PromQL, 並且支持Prometheus的API, 可以直接替換開源的Prometheus的存儲查詢層

可視化: Grafana

Prometheus自身提供的可視化能力很弱, 因此通常會選擇Grafana對接Prometheus去配置dashboard, 這兩個可以說是最佳搭檔

通知: alertmanager

alertmanager是Prometheus提供的一個組件, 它提供了豐富的通知路由, 發送方式

監控分層

按監控對象分:
操作系統監控(OS)
中間件/數據庫監控(MySQL, Kafka, ES, Hbase, etc)
應用監控(JVM, Tomcat, Spring)
業務監控(SDK, Log)

按數據流分:

暴露指標 -> 採集 -> 存儲 -> 可視化 -> 分析                                          
                        -> 報警

主機監控

主機監控, 即操作系統層面的監控有很多種姿勢:

  1. Prometheus官方有node_exporter, 如果你是非阿里雲的機器, 跑的是主流的Linux, 那麼這是比較推薦的方式來暴露指標
  2. 我們的Logtail也提供了主機監控的插件, 可以暴露絕大多數常用指標, 如果是阿里雲的機器, 那麼這種方式操作起來也非常簡單, 可參考文檔: 採集主機監控數據_數據接入_時序存儲_日誌服務-阿里雲
  3. 同時假如你已經使用了telegraf, 那麼也可以使用telegraf來接入SLS
  4. 雲上ECS已有云監控, 因此也可以直接導入雲監控數據, 不重複採集: 導入雲監控數據_數據接入_時序存儲_日誌服務-阿里雲, 由於雲監控只採集一些核心指標, 因此這種方式獲得的指標會較少
    SLS以儘量開放的姿態, 兼容各種開源軟件和協議, 幫助你以最舒服的方式接入數據

中間件/數據庫監控

各類主流的開源中間件通常也都和開源的監控軟件結合的比較好, 例如MySQL可以使用telegraf進行採集, Prometheus exporter對大部分開源軟件的支持也都比較好: Exporters and integrations | Prometheus
同主機監控, 如果你使用的是阿里雲提供的數據庫或中間件, 那很可能雲監控上已經有相關的指標, 因此也可以選擇導入雲監控數據

應用監控

Spring Boot Actuator

Spring Boot作為最主流的Java Web框架, 自然也少不了對監控的支持, 那就是Actuator, 要使用Actuator需要先添加依賴:

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

Actuator默認提供了13個接口:
DE2B29AD-D36D-452C-802B-AE2B585522E7.png
這些接口默認只開放了/heath/info, 可以修改配置打開其他的接口:

management:
  endpoints:
    web:
      exposure:
        include: '*'

在Spring Boot 2.0以上, 它使用了micrometer作為底層的度量工具, micrometer是監控度量的門面, 相當於slf4j在日誌框架中的作用,它能支持按照各種格式來暴露數據, 其中就有Prometheus.
我們引入一個很小的依賴來暴露Prometheus數據:

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

這個依賴的作用就是會開啟一個endpoint, 輸出兼容Prometheus exporter的結果, 方便Prometheus來採集
同時記得修改spring boot配置:

server:
  port: 8080
spring:
  application:
    name: spring-demo
management:
  endpoints:
    web:
      exposure:
        include: 'prometheus' # 暴露/actuator/prometheus
  metrics:
    tags:
      application: ${spring.application.name} # 暴露的數據中添加application label

然後啟動應用, 訪問http://localhost:8080/actuator/prometheus 應該會得到如下結果:

# HELP jvm_memory_committed_bytes The amount of memory in bytes that is committed for the Java virtual machine to use
# TYPE jvm_memory_committed_bytes gauge
jvm_memory_committed_bytes{application="spring-demo",area="heap",id="PS Eden Space",} 1.77733632E8
jvm_memory_committed_bytes{application="spring-demo",area="nonheap",id="Metaspace",} 3.6880384E7
jvm_memory_committed_bytes{application="spring-demo",area="heap",id="PS Old Gen",} 1.53092096E8
jvm_memory_committed_bytes{application="spring-demo",area="heap",id="PS Survivor Space",} 1.4680064E7
jvm_memory_committed_bytes{application="spring-demo",area="nonheap",id="Compressed Class Space",} 5160960.0
jvm_memory_committed_bytes{application="spring-demo",area="nonheap",id="Code Cache",} 7798784.0
# HELP jvm_classes_unloaded_classes_total The total number of classes unloaded since the Java virtual machine has started execution
# TYPE jvm_classes_unloaded_classes_total counter
jvm_classes_unloaded_classes_total{application="spring-demo",} 0.0
# HELP jvm_memory_max_bytes The maximum amount of memory in bytes that can be used for memory management
jvm_memory_max_bytes{application="spring-demo",area="nonheap",id="Code Cache",} 2.5165824E8
# HELP jvm_classes_loaded_classes The number of classes that are currently loaded in the Java virtual machine
# TYPE jvm_classes_loaded_classes gauge
jvm_classes_loaded_classes{application="spring-demo",} 7010.0
# HELP jvm_threads_daemon_threads The current number of live daemon threads
# TYPE jvm_threads_daemon_threads gauge
jvm_threads_daemon_threads{application="spring-demo",} 24.0
# HELP jvm_threads_states_threads The current number of threads having NEW state

# 太長, 後面省略

這就是Prometheus exporter的格式

JVM監控

我們看到裡面暴露了很詳細的jvm的指標, 這樣我們就可以來配置jvm監控了
首先Prometheus需要增加對http://localhost:8080/actuator/prometheus的採集, 我們修改一下配置:

global:
  scrape_interval: 15s
scrape_configs:
  - job_name: "spring-demo"
    metrics_path: "/actuator/prometheus"
    static_configs:
    - targets: ["localhost:8080"]

啟動Prometheus, 沒報錯的話應該就已經在正常採集了, 我們訪問prometheus的web ui看一下數據:http://localhost:9090/graph
CD29EFE5-6B74-40F6-A872-C2B2F33A0B98.png
看到這樣的結果說明數據採集正常, 寫入Prometheus後通過他的remote write協議可以把數據持久化到SLS中, 可參見文檔: 採集Prometheus監控數據
然後可以把SLS時序庫作為Grafana的數據源來配置, 同樣有相關文檔: 時序數據對接Grafan
那麼一切準備就緒了, 我們就可以開始配置dashboard了, 我們在grafana.com上傳了一個模板dashboard, 直接在grafana中導入即可:
選擇+ -> Import -> 粘貼url:
https://grafana.com/grafana/dashboards/12856
然後選擇上面創建的Prometheus數據源, 即可導入, 完整的效果如下:
micrometer_grafana1.png

大家在使用SLS中遇到的任何問題,請加釘釘群,我們有專門的日誌女僕24小時在線答疑,還有火鍋哥和燒烤哥專業支持!~ SLS微信公眾號定期會發布各類日誌、監控領域的技術分享文章並定期舉行抽獎,歡迎小夥伴們關注~
另外歡迎對大數據、分佈式、機器學習等有興趣的同學加入,轉崗、內推,來者不拒,請用簡歷狠狠的砸我,聯繫郵箱[email protected] !~
image.png

Leave a Reply

Your email address will not be published. Required fields are marked *