Prometheus + Grafana 監控 SpringBoot項目監控系統

整體結構

SpringBoot

的 actuator 提供了監控端點。

Prometheus 是監控系統,可以從 Springboot 獲取監控數據,以時序數據的形式存儲,並提供了監控數據的查詢服務。

Grafana 是專業的 UI 儀表盤系統,支持非常多的數據源,其中就包括 Prometheus,可以便利的從中獲取數據,使用儀表盤展示出來。

springboot 2 中引入了 micrometer,它可以更方便的對接各種監控系統,包括 Prometheus。

Prometheus + Grafana 監控 SpringBoot項目監控系統

所以整體的結構就是:

  • springboot(micrometer)產生監控數據。
  • Prometheus 獲取 springboot 應用的監控數據,存儲,並提供數據查詢服務。
  • Grafana 對接 Prometheus 數據源,調用其數據查詢服務,用專業的儀表盤 UI 進行展示。

實踐步驟

  • 創建應用 -- 作為監控目標,產生監控數據。
  • 集成度量庫 micrometer -- 以便對接監控系統 Prometheus。
  • 部署 prometheus
  • 配置 prometheus -- 監控之前創建的 springboot 應用,瞭解 Prometheus 的查詢服務。
  • 部署 Grafana
  • 添加 Prometheus 數據源
  • 添加 JVM 監控儀表盤 -- 展示之前 springboot 應用的 JVM 狀態。
  • 自定義監控指標 -- 自有的監控指標都是底層基礎數據,業務相關指標需要我們自己寫代碼。
  • 動態變更監控目標 -- 如果監控目標發生變動就改一次 Prometheus 的配置文件,並重新啟動,這是不適合的,需要使用動態配置的方式。

1. 創建應用 集成 micrometer

創建一個最簡的 springboot 應用,添加 micrometer 依賴。

pom.xml :

<code>
<project>\t
<modelversion>4.0.0/<modelversion>\t
<parent>\t\t
<groupid>org.springframework.boot/<groupid>\t\t
<artifactid>spring-boot-starter-parent/<artifactid>\t\t
<version>2.2.4.RELEASE/<version>\t\t
<relativepath>
/<parent>\t
<groupid>com.example/<groupid>\t
<artifactid>springboot2demo/<artifactid>\t
<version>0.0.1-SNAPSHOT/<version>\t
<name>springboot2demo/<name>\t
<description>Demo project for Spring Boot/<description>\t
<properties>\t\t
<java.version>1.8/<java.version>\t
/<properties>\t
<dependencies>\t\t
<dependency>\t\t\t
<groupid>org.springframework.boot/<groupid>\t\t\t
<artifactid>spring-boot-starter-actuator/<artifactid>\t\t
/<dependency>\t\t
<dependency>\t\t\t
<groupid>org.springframework.boot/<groupid>\t\t\t
<artifactid>spring-boot-starter-web/<artifactid>\t\t
/<dependency>\t\t
<dependency>\t\t\t
<groupid>io.micrometer/<groupid>\t\t\t
<artifactid>micrometer-registry-prometheus/<artifactid>\t\t\t
<version>1.1.4/<version>\t\t
/<dependency>\t\t
<dependency>\t\t\t

<groupid>org.springframework.boot/<groupid>\t\t\t
<artifactid>spring-boot-starter-test/<artifactid>\t\t\t
<scope>test/<scope>\t\t\t
<exclusions>\t\t\t\t
<exclusion>\t\t\t\t\t
<groupid>org.junit.vintage/<groupid>\t\t\t\t\t
<artifactid>junit-vintage-engine/<artifactid>\t\t\t\t
/<exclusion>\t\t\t
/<exclusions>\t\t
/<dependency>\t
/<dependencies>\t
<build>\t\t
<plugins>\t\t\t
<plugin>\t\t\t\t
<groupid>org.springframework.boot/<groupid>\t\t\t\t
<artifactid>spring-boot-maven-plugin/<artifactid>\t\t\t
/<plugin>\t\t
/<plugins>\t
/<build>
/<project>/<code>

application.properties

<code>spring.application.name=springboot2demo
# 打開所有 Actuator 服務
management.endpoints.web.exposure.include=*
# 將應用名稱添加到計量器的 tag 中去
# 以便 Prometheus 根據應用名區分不同服務
management.metrics.tags.application=${spring.application.name}/<code>

在啟動類中添加Bean,用於監控JVM性能指標:

<code>package com.example.springboot2demo;
import io.micrometer.core.instrument.MeterRegistry;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.actuate.autoconfigure.metrics.MeterRegistryCustomizer;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
@SpringBootApplicationpublic class Springboot2demoApplication {
public static void main(String[] args) {
SpringApplication.run(Springboot2demoApplication.class, args);
}
@Bean
MeterRegistryCustomizer<meterregistry> configurer(

@Value("${spring.application.name}") String applicationName) {
return (registry) -> registry.config().commonTags("application", applicationName);
}
}/<meterregistry>/<code>

啟動服務。

查看監控端點信息:

Prometheus + Grafana 監控 SpringBoot項目監控系統

2. 部署 Prometheus

官網:

https://prometheus.io/

可以下載安裝包來安裝,但下載速度極其慢,幾乎下載不了。

可以使用 docker 部署,因為國內有docker鏡像,所以速度很快。

docker 方式啟動:

<code>$ docker run --name prometheus -d -p 127.0.0.1:9090:9090 prom/prometheus/<code>

執行完成後就OK了,可以看一下 Prometheus 的界面。

http://localhost:9090/targets 是監控目標列表頁:

Prometheus + Grafana 監控 SpringBoot項目監控系統

http://localhost:9090/graph 是查詢控制檯,也有簡單的圖表展示:

Prometheus + Grafana 監控 SpringBoot項目監控系統

現在還沒對接應用,後面對接之後可以看到詳細的內容。

3. Prometheus + Springboot應用

監控應用,需要在 Prometheus 配置文件中添加應用的相關信息。

配置文件在容器中的路徑:/etc/prometheus。

查看一下配置文件的默認內容:

<code>$ docker exec -it [容器ID] cat /etc/prometheus/prometheus.yml/<code>
Prometheus + Grafana 監控 SpringBoot項目監控系統

紅框內是我們要關注的部分,按照這個形式添加我們的應用即可。

需要添加的內容為:

<code>- job_name: 'springboot_app'    
scrape_interval: 5s
metrics_path: '/actuator/prometheus'
static_configs:
- targets: ['192.168.31.6:8080']
"labels": {
"instance": "springboot2-A",
"service": "springboot2-A-service"
}/<code>

metrics_path 指定監控端點的路徑。

targets 指定應用的IP端口,這裡使用了IP,沒有使用localhost,因為 Prometheus 是容器運行的,如果使用 localhost 就會訪問容器內部。

配置不是直接在容器內部修改,可以把容器內部的配置文件拷貝出來一份,修改後,重啟啟動容器,掛載本地修改過的配置文件。

拷貝容器中的配置文件:

<code>$ docker cp [容器ID]:/etc/prometheus/prometheus.yml ./<code>

修改配置文件,添加配置,最終的內容:

<code># my global configg
lobal: scrape_interval: 15s
# Set the scrape interval to every 15 seconds. Default is every 1 minute. evaluation_interval: 15s
# Evaluate rules every 15 seconds. The default is every 1 minute.
# scrape_timeout is set to the global default (10s).
# Alertmanager configurationalerting:
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=` to any timeseries scraped from this config. - job_name: 'prometheus'
# metrics_path defaults to '/metrics'
# scheme defaults to 'http'.
static_configs: - targets: ['localhost:9090']
- job_name: 'springboot_app'
scrape_interval: 5s
metrics_path: '/actuator/prometheus'
static_configs:
- targets: ['192.168.31.6:8080']
"labels": {
"instance": "springboot2-A",

"service": "springboot2-A-service"
}
/<code>

停掉之前的容器,重新啟動:

<code>$ docker run --name prometheus -d \\    
-p 9090:9090 \\
-v [PATH]/prometheus.yml:/etc/prometheus/prometheus.yml \\
prom/prometheus/<code>

訪問監控列表頁 http://localhost:9090/targets 就可以看到我們的應用了:

Prometheus + Grafana 監控 SpringBoot項目監控系統

點擊端點鏈接,可以看到監控數據,例如:

Prometheus + Grafana 監控 SpringBoot項目監控系統

進入查詢控制檯頁面 http://localhost:9090/graph,可以查詢一個指標,例如 http_server_requests_seconds_sum,效果:

Prometheus + Grafana 監控 SpringBoot項目監控系統

4. 部署 Grafana

docker方式運行:

<code>$ docker run -d \\    
-p 3000:3000 \\
--name=grafana \\
grafana/grafana/<code>

啟動後,訪問:http://localhost:3000,默認用戶名密碼 admin/admin。

Prometheus + Grafana 監控 SpringBoot項目監控系統

Prometheus + Grafana 監控 SpringBoot項目監控系統

5. 添加 Prometheus 數據源

Prometheus + Grafana 監控 SpringBoot項目監控系統

Prometheus + Grafana 監控 SpringBoot項目監控系統

Prometheus + Grafana 監控 SpringBoot項目監控系統

6. 展示應用的 JVM 信息

Grafana 中已經有現成的 JVM 儀表盤,我們直接導入使用即可。

這個儀表盤的編號為 4701。

Prometheus + Grafana 監控 SpringBoot項目監控系統

Prometheus + Grafana 監控 SpringBoot項目監控系統

Prometheus + Grafana 監控 SpringBoot項目監控系統

Prometheus + Grafana 監控 SpringBoot項目監控系統

至此,Prometheus + Grafana + Springboot 的整體流程已經跑通了。

但是,這些指標都是底層通用指標,在業務層面一定會有個性需求,下面我們自己定義一些監控指標。

7. 自定義監控指標

需求:監控所有接口的請求次數。

應用中添加依賴:

<code><dependency>\t\t\t
<groupid>org.aspectj/<groupid>\t\t\t
<artifactid>aspectjrt/<artifactid>\t\t\t
<version>1.9.4/<version>\t\t
/<dependency>\t\t
<dependency>\t\t\t
<groupid>org.aspectj/<groupid>\t\t\t
<artifactid>aspectjweaver/<artifactid>\t\t\t
<version>1.9.4/<version>\t\t
/<dependency>\t\t
<dependency>\t\t\t
<groupid>cglib/<groupid>\t\t\t
<artifactid>cglib/<artifactid>\t\t\t
<version>3.2.12/<version>\t\t
/<dependency>/<code>

使用AOP方式對接口請求計數:

<code>package com.example.springboot2demo;
import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.MeterRegistry;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
@Component
@Aspect
public class APICounterAop {
@Pointcut("execution(public * com.example.springboot2demo.*.*(..))")
public void pointCut() {
}
ThreadLocal<long> startTime = new ThreadLocal<>();
@Autowired
MeterRegistry registry;
private Counter counter;
@PostConstruct
private void init() {
counter = registry.counter("requests_total", "status", "success");
}
@Before("pointCut()")
public void doBefore(JoinPoint joinPoint) throws Throwable {
System.out.println("do before");
counter.increment();
//請求計數
}

@AfterReturning(returning = "returnVal", pointcut = "pointCut()")
public void doAfterReturning(Object returnVal) {
System.out.println("do after");
}
}/<long>/<code>

創建一個測試接口:

<code>package com.example.springboot2demo;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class TestController {
@RequestMapping("/hello")
public String hello() {
return "hello";
}
}/<code>

重啟應用,多訪問幾次測試接口,然後查看 Prometheus 中的應用監控端點頁面,就可以看到監控結果:

Prometheus + Grafana 監控 SpringBoot項目監控系統

然後,我們把這個指標在 Grafana 中顯示出來。

Prometheus + Grafana 監控 SpringBoot項目監控系統

Prometheus + Grafana 監控 SpringBoot項目監控系統

8. 動態變更監控目標

上面 Prometheus 配置文件中定義的監控目標使用的是靜態方式,改配置文件後需要重啟。

如果服務變更了,或者增加服務了,經常重啟 Prometheus 肯定不合適。

Prometheus 提供了動態加載的方式,把服務信息放到一個單獨的文件中,Prometheus 配置中指定這個外部文件,內容變化後,Prometheus 就會自動重新加載。

服務信息配置文件例如:

<code>[    
{
"targets": [
"192.168.31.6:8080"
],
"labels": {
"instance": "springboot2-A",
"service": "springboot2-A-service"
}
}
]/<code>

Prometheus 配置文件中的寫法:

<code>...  
- job_name: 'springboot_app'
scrape_interval: 5s
metrics_path: '/actuator/prometheus'
file_sd_configs:
- files:
- /home/*.json
refresh_interval: 1m/<code>

啟動 Prometheus 容器時要掛載這個服務信息配置文件的目錄:

<code>$ docker run --name prometheus -d -p 9090:9090 \\\t
-v [PATH]/prometheus.yml:/etc/prometheus/prometheus.yml \\\t
-v [PATH]:/home \\\tprom/prometheus/<code>


分享到:


相關文章: