SpringBoot Admin與Prometheus集成監(jiān)控
摘要
本文深入探討Spring Boot Admin與Prometheus的集成監(jiān)控方案,包括指標(biāo)收集、數(shù)據(jù)導(dǎo)出、可視化展示等關(guān)鍵技術(shù)點(diǎn)。通過詳細(xì)的技術(shù)解析和實(shí)踐示例,幫助開發(fā)者構(gòu)建完整的微服務(wù)監(jiān)控體系。
1. 引言
Prometheus作為開源的系統(tǒng)監(jiān)控和報(bào)警工具包,已經(jīng)成為云原生監(jiān)控的標(biāo)準(zhǔn)。Spring Boot Admin結(jié)合Prometheus可以提供更強(qiáng)大的監(jiān)控能力。本文將詳細(xì)介紹如何實(shí)現(xiàn)兩者的集成。
2. Prometheus基礎(chǔ)
2.1 Prometheus架構(gòu)
Prometheus生態(tài)系統(tǒng)包含以下組件:
- Prometheus Server:收集和存儲(chǔ)指標(biāo)數(shù)據(jù)
- Client Libraries:用于應(yīng)用代碼中暴露指標(biāo)
- Pushgateway:支持批處理作業(yè)的指標(biāo)推送
- Alertmanager:處理報(bào)警
- 可視化工具:如Grafana
2.2 數(shù)據(jù)模型
Prometheus使用時(shí)間序列數(shù)據(jù)模型,每個(gè)時(shí)間序列由指標(biāo)名稱和鍵值對(duì)標(biāo)簽標(biāo)識(shí)。
3. 集成配置
3.1 依賴配置
<dependencies>
<!-- Spring Boot Admin Server -->
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-server</artifactId>
</dependency>
<!-- Spring Boot Actuator -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- Micrometer Prometheus Registry -->
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
<!-- Spring Boot Starter Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
3.2 應(yīng)用配置
# application.yml
server:
port: 8022
spring:
application:
name: admin-server-prometheus
# Actuator配置
management:
endpoints:
web:
exposure:
include: health,info,metrics,prometheus
base-path: /actuator
endpoint:
health:
show-details: always
prometheus:
enabled: true
metrics:
export:
prometheus:
enabled: true
distribution:
percentiles-histogram:
all: true
sla:
http.server.requests: 10ms, 50ms, 100ms, 200ms, 500ms, 1000ms
# Spring Boot Admin配置
boot:
admin:
server:
ui:
title: 'Prometheus集成監(jiān)控平臺(tái)'
brand: '<img src="assets/img/icon-spring-boot-admin.svg"><span>Prometheus集成監(jiān)控平臺(tái)</span>'
info:
app:
name: ${spring.application.name}
version: ${project.version}
description: Spring Boot Admin與Prometheus集成示例
4. 指標(biāo)收集與暴露
4.1 自定義指標(biāo)收集器
package com.springboot.admin.prometheus;
import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.Gauge;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.binder.MeterBinder;
import org.springframework.stereotype.Component;
@Component
public class CustomMetricsCollector implements MeterBinder {
private Counter requestCounter;
private Counter errorCounter;
@Override
public void bindTo(MeterRegistry registry) {
// 請(qǐng)求計(jì)數(shù)器
requestCounter = Counter.builder("http_requests_total")
.description("Total number of HTTP requests")
.register(registry);
// 錯(cuò)誤計(jì)數(shù)器
errorCounter = Counter.builder("http_errors_total")
.description("Total number of HTTP errors")
.register(registry);
// 系統(tǒng)指標(biāo)
Gauge.builder("system_cpu_usage")
.description("System CPU usage")
.register(registry, this, obj -> getSystemCpuUsage());
Gauge.builder("system_memory_usage")
.description("System memory usage")
.register(registry, this, obj -> getSystemMemoryUsage());
}
public void incrementRequest() {
if (requestCounter != null) {
requestCounter.increment();
}
}
public void incrementError() {
if (errorCounter != null) {
errorCounter.increment();
}
}
private double getSystemCpuUsage() {
// 獲取系統(tǒng)CPU使用率
return Math.random() * 100; // 模擬數(shù)據(jù)
}
private double getSystemMemoryUsage() {
// 獲取系統(tǒng)內(nèi)存使用率
long totalMemory = Runtime.getRuntime().totalMemory();
long freeMemory = Runtime.getRuntime().freeMemory();
return (double) (totalMemory - freeMemory) / totalMemory * 100;
}
}
4.2 業(yè)務(wù)指標(biāo)收集
package com.springboot.admin.prometheus;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Tag;
import io.micrometer.core.instrument.Timer;
import org.springframework.stereotype.Service;
import java.util.concurrent.TimeUnit;
@Service
public class BusinessMetricsService {
private final MeterRegistry meterRegistry;
private final Timer businessOperationTimer;
public BusinessMetricsService(MeterRegistry meterRegistry) {
this.meterRegistry = meterRegistry;
// 業(yè)務(wù)操作計(jì)時(shí)器
this.businessOperationTimer = Timer.builder("business.operation.duration")
.description("Business operation duration")
.register(meterRegistry);
}
public <T> T recordBusinessOperation(String operationName, java.util.function.Supplier<T> operation) {
return businessOperationTimer
.tag("operation", operationName)
.recordCallable(operation::get);
}
public void recordBusinessEvent(String eventType, String service) {
meterRegistry.counter("business.events.total",
Tag.of("type", eventType),
Tag.of("service", service))
.increment();
}
public void recordBusinessGauge(String name, double value, String service) {
meterRegistry.gauge("business." + name,
Tag.of("service", service),
value);
}
}
5. Prometheus配置
5.1 Prometheus配置文件
# prometheus.yml
global:
scrape_interval: 15s
evaluation_interval: 15s
rule_files:
- "alert_rules.yml"
scrape_configs:
- job_name: 'admin-server'
static_configs:
- targets: ['localhost:8022']
metrics_path: '/actuator/prometheus'
scrape_interval: 10s
scrape_timeout: 5s
honor_labels: true
relabel_configs:
- source_labels: [__address__]
target_label: instance
- job_name: 'microservices'
metrics_path: '/actuator/prometheus'
scrape_interval: 10s
scrape_timeout: 5s
static_configs:
- targets: ['service1:8080', 'service2:8081', 'service3:8082']
relabel_configs:
- source_labels: [__address__]
target_label: instance
alerting:
alertmanagers:
- static_configs:
- targets: ['alertmanager:9093']
5.2 告警規(guī)則配置
# alert_rules.yml
groups:
- name: admin_server_alerts
rules:
- alert: AdminServerDown
expr: up{job="admin-server"} == 0
for: 1m
labels:
severity: critical
annotations:
summary: "Admin Server is down"
description: "Admin Server {{ $labels.instance }} has been down for more than 1 minute."
- alert: HighCpuUsage
expr: system_cpu_usage > 80
for: 2m
labels:
severity: warning
annotations:
summary: "High CPU usage on {{ $labels.instance }}"
description: "CPU usage is above 80% on instance {{ $labels.instance }}."
- alert: HighMemoryUsage
expr: system_memory_usage > 85
for: 2m
labels:
severity: warning
annotations:
summary: "High memory usage on {{ $labels.instance }}"
description: "Memory usage is above 85% on instance {{ $labels.instance }}."
- alert: HighErrorRate
expr: rate(http_errors_total[5m]) > 10
for: 2m
labels:
severity: warning
annotations:
summary: "High error rate on {{ $labels.instance }}"
description: "Error rate is above 10 requests per minute on instance {{ $labels.instance }}."
6. 數(shù)據(jù)導(dǎo)出與格式化
6.1 自定義指標(biāo)格式化
package com.springboot.admin.prometheus;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.prometheus.PrometheusMeterRegistry;
import org.springframework.stereotype.Component;
@Component
public class PrometheusCustomFormatter {
public void customizePrometheusRegistry(PrometheusMeterRegistry registry) {
// 自定義指標(biāo)格式化
registry.config()
.meterFilter(new io.micrometer.core.instrument.config.MeterFilter() {
@Override
public io.micrometer.core.instrument.Meter.Id map(io.micrometer.core.instrument.Meter.Id id) {
// 添加自定義標(biāo)簽
if (id.getName().startsWith("http.")) {
return id.withTags(io.micrometer.core.instrument.Tag.of("application", "admin-server"));
}
return id;
}
});
}
}
6.2 指標(biāo)數(shù)據(jù)處理
package com.springboot.admin.prometheus;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Tag;
import org.springframework.stereotype.Component;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
@Component
public class MetricsProcessor {
private final MeterRegistry meterRegistry;
private final ConcurrentHashMap<String, AtomicLong> customCounters = new ConcurrentHashMap<>();
public MetricsProcessor(MeterRegistry meterRegistry) {
this.meterRegistry = meterRegistry;
}
public void incrementCustomCounter(String name, String... tags) {
String key = buildKey(name, tags);
AtomicLong counter = customCounters.computeIfAbsent(key, k -> new AtomicLong(0));
long value = counter.incrementAndGet();
// 同步到Prometheus
meterRegistry.counter("custom." + name,
buildTags(tags))
.increment();
}
public void recordCustomGauge(String name, double value, String... tags) {
meterRegistry.gauge("custom." + name,
java.util.Arrays.asList(buildTags(tags)),
value);
}
private String buildKey(String name, String... tags) {
StringBuilder key = new StringBuilder(name);
for (String tag : tags) {
key.append(".").append(tag);
}
return key.toString();
}
private Iterable<Tag> buildTags(String... tags) {
java.util.List<Tag> tagList = new java.util.ArrayList<>();
for (int i = 0; i < tags.length; i += 2) {
if (i + 1 < tags.length) {
tagList.add(Tag.of(tags[i], tags[i + 1]));
}
}
return tagList;
}
}
7. 監(jiān)控面板集成
7.1 Grafana配置
{
"dashboard": {
"id": null,
"title": "Admin Server Dashboard",
"tags": ["admin", "spring-boot", "prometheus"],
"timezone": "browser",
"panels": [
{
"id": 1,
"title": "HTTP Requests",
"type": "graph",
"targets": [
{
"expr": "rate(http_requests_total[1m])",
"legendFormat": "Requests per second"
}
]
},
{
"id": 2,
"title": "System CPU Usage",
"type": "singlestat",
"targets": [
{
"expr": "system_cpu_usage",
"legendFormat": "CPU Usage"
}
]
},
{
"id": 3,
"title": "System Memory Usage",
"type": "graph",
"targets": [
{
"expr": "system_memory_usage",
"legendFormat": "Memory Usage"
}
]
}
]
}
}
7.2 監(jiān)控?cái)?shù)據(jù)API
package com.springboot.admin.api;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.prometheus.PrometheusMeterRegistry;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api/metrics")
public class MetricsApiController {
@Autowired
private MeterRegistry meterRegistry;
@Autowired
private PrometheusMeterRegistry prometheusRegistry;
@GetMapping("/prometheus")
public ResponseEntity<String> getPrometheusMetrics() {
return ResponseEntity.ok(prometheusRegistry.scrape());
}
@GetMapping("/summary")
public ResponseEntity<MetricsSummary> getMetricsSummary() {
MetricsSummary summary = new MetricsSummary();
// 獲取各種指標(biāo)的摘要信息
summary.setTotalMeters(meterRegistry.getMeters().size());
summary.setGauges(meterRegistry.find("gauge").meters().size());
summary.setCounters(meterRegistry.find("counter").meters().size());
summary.setTimers(meterRegistry.find("timer").meters().size());
return ResponseEntity.ok(summary);
}
public static class MetricsSummary {
private int totalMeters;
private int gauges;
private int counters;
private int timers;
// getter和setter方法
public int getTotalMeters() { return totalMeters; }
public void setTotalMeters(int totalMeters) { this.totalMeters = totalMeters; }
public int getGauges() { return gauges; }
public void setGauges(int gauges) { this.gauges = gauges; }
public int getCounters() { return counters; }
public void setCounters(int counters) { this.counters = counters; }
public int getTimers() { return timers; }
public void setTimers(int timers) { this.timers = timers; }
}
}
8. 高級(jí)功能
8.1 指標(biāo)過濾與轉(zhuǎn)換
package com.springboot.admin.prometheus;
import io.micrometer.core.instrument.config.MeterFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MetricsFilterConfig {
@Bean
public MeterFilter metricsFilter() {
return MeterFilter.maximumAllowableMetrics(1000)
.andThen(MeterFilter.maximumAllowableTags("http.server.requests", "uri", 100))
.andThen(MeterFilter.denyUnless(meter ->
meter.getName().startsWith("http.") ||
meter.getName().startsWith("jvm.") ||
meter.getName().startsWith("system.") ||
meter.getName().startsWith("tomcat.")
));
}
@Bean
public MeterFilter namingConventionFilter() {
return MeterFilter.renameTag("http.server.requests", "method", "httpMethod")
.andThen(MeterFilter.renameTag("http.server.requests", "uri", "httpUri"));
}
}
8.2 指標(biāo)聚合
package com.springboot.admin.prometheus;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Tag;
import io.micrometer.core.instrument.Timer;
import org.springframework.stereotype.Component;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
@Component
public class MetricsAggregator {
private final MeterRegistry meterRegistry;
private final ConcurrentHashMap<String, Timer.Sample> activeOperations = new ConcurrentHashMap<>();
public MetricsAggregator(MeterRegistry meterRegistry) {
this.meterRegistry = meterRegistry;
}
public void startOperation(String operationName, String service) {
Timer.Sample sample = Timer.start(meterRegistry);
String key = operationName + ":" + service;
activeOperations.put(key, sample);
}
public void endOperation(String operationName, String service) {
String key = operationName + ":" + service;
Timer.Sample sample = activeOperations.remove(key);
if (sample != null) {
sample.stop(Timer.builder("operation.duration")
.description("Operation duration")
.tags(Tag.of("operation", operationName), Tag.of("service", service))
.register(meterRegistry));
}
}
public void recordHistogram(String metricName, double value, String... tags) {
meterRegistry.timer(metricName, buildTags(tags))
.record((long) value, TimeUnit.MILLISECONDS);
}
private Iterable<Tag> buildTags(String... tags) {
java.util.List<Tag> tagList = new java.util.ArrayList<>();
for (int i = 0; i < tags.length; i += 2) {
if (i + 1 < tags.length) {
tagList.add(Tag.of(tags[i], tags[i + 1]));
}
}
return tagList;
}
}
9. 部署配置
9.1 Docker配置
# Dockerfile FROM openjdk:8-jre-alpine # 創(chuàng)建應(yīng)用目錄 RUN addgroup -S spring && adduser -S spring -G spring USER spring:spring WORKDIR /app # 復(fù)制應(yīng)用文件 COPY --chown=spring:spring target/admin-server-prometheus.jar app.jar # 暴露端口 EXPOSE 8022 # 啟動(dòng)命令 ENTRYPOINT ["java", "-jar", "app.jar"]
9.2 Docker Compose配置
# docker-compose.yml
version: '3.8'
services:
admin-server:
build: .
container_name: admin-server-prometheus
ports:
- "8022:8022"
environment:
- SPRING_PROFILES_ACTIVE=prometheus
networks:
- monitoring
prometheus:
image: prom/prometheus:latest
container_name: prometheus
ports:
- "9090:9090"
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--web.console.libraries=/etc/prometheus/console_libraries'
- '--web.console.templates=/etc/prometheus/consoles'
networks:
- monitoring
grafana:
image: grafana/grafana:latest
container_name: grafana
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
volumes:
- grafana-storage:/var/lib/grafana
networks:
- monitoring
depends_on:
- prometheus
volumes:
grafana-storage:
networks:
monitoring:
driver: bridge
10. 性能優(yōu)化
10.1 指標(biāo)收集優(yōu)化
package com.springboot.admin.optimization;
import io.micrometer.core.instrument.config.MeterFilter;
import io.micrometer.core.instrument.distribution.DistributionStatisticConfig;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MetricsOptimizationConfig {
@Bean
public MeterFilter metricsFilter() {
return MeterFilter.maximumAllowableMetrics(1000)
.andThen(MeterFilter.denyUnless(meter ->
meter.getName().startsWith("http.") ||
meter.getName().startsWith("jvm.") ||
meter.getName().startsWith("system.")
));
}
@Bean
public MeterFilter distributionConfigFilter() {
return new MeterFilter() {
@Override
public DistributionStatisticConfig configure(io.micrometer.core.instrument.Meter.Id id,
DistributionStatisticConfig config) {
if (id.getName().startsWith("http.server.requests")) {
return DistributionStatisticConfig.builder()
.percentiles(0.5, 0.95, 0.99)
.build()
.merge(config);
}
return config;
}
};
}
}
11. 總結(jié)
本文詳細(xì)介紹了Spring Boot Admin與Prometheus的集成監(jiān)控方案,包括:
- Prometheus基礎(chǔ)概念和架構(gòu)
- 集成配置和依賴管理
- 指標(biāo)收集與暴露
- Prometheus配置和告警規(guī)則
- 數(shù)據(jù)導(dǎo)出與格式化
- 監(jiān)控面板集成
- 高級(jí)功能實(shí)現(xiàn)
- 部署配置方案
- 性能優(yōu)化策略
通過合理的集成配置,可以構(gòu)建一個(gè)功能完善的微服務(wù)監(jiān)控體系,為系統(tǒng)運(yùn)維提供有力支持。
12. 擴(kuò)展閱讀
13. 參考資料
- Prometheus GitHub: https://github.com/prometheus/prometheus
- Micrometer GitHub: https://github.com/micrometer-metrics/micrometer
- Spring Boot Admin GitHub: https://github.com/codecentric/spring-boot-admin
本文為CSDN博主「Spring Cloud技術(shù)棧」原創(chuàng)文章,轉(zhuǎn)載請(qǐng)附上原文出處鏈接和本聲明。
到此這篇關(guān)于SpringBoot Admin與Prometheus集成監(jiān)控的文章就介紹到這了,更多相關(guān)SpringBoot Prometheus監(jiān)控內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- SpringBoot整合Prometheus如何實(shí)現(xiàn)資源監(jiān)控
- springboot整合prometheus實(shí)現(xiàn)資源監(jiān)控的詳細(xì)步驟
- SpringBoot集成 Prometheus進(jìn)行高效監(jiān)控的實(shí)現(xiàn)
- SpringBoot使用Prometheus實(shí)現(xiàn)監(jiān)控
- SpringBoot集成Prometheus實(shí)現(xiàn)監(jiān)控的過程
- Prometheus監(jiān)控Springboot程序的實(shí)現(xiàn)方法
- SpringBoot使用prometheus監(jiān)控的示例代碼
- SpringBoot+Prometheus+Grafana實(shí)現(xiàn)應(yīng)用監(jiān)控和報(bào)警的詳細(xì)步驟
相關(guān)文章
jdbc連SQL?server顯示1433端口連接失敗圖文解決方法
這篇文章主要給大家介紹了關(guān)于jdbc連SQL?server顯示1433端口連接失敗的圖文解決方法,文中通過圖文介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2024-06-06
Spring切面優(yōu)先級(jí)與基于xml的AOP實(shí)現(xiàn)方法詳解
這篇文章主要介紹了Spring切面的優(yōu)先級(jí)與基于xml的AOP的詳細(xì)步驟,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-11-11
idea中一鍵自動(dòng)生成序列化serialVersionUID方式
這篇文章主要介紹了idea中一鍵自動(dòng)生成序列化serialVersionUID方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-09-09
java利用正則表達(dá)式處理特殊字符的方法實(shí)例
這篇文章主要給大家介紹了關(guān)于java利用正則表達(dá)式處理特殊字符的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12
Spring Boot 中的 CommandLineRunner 原理及使用示例
CommandLineRunner 是 Spring Boot 提供的一個(gè)非常有用的接口,可以幫助你在應(yīng)用程序啟動(dòng)后執(zhí)行初始化任務(wù),本文通過多個(gè)示例詳細(xì)介紹了如何在實(shí)際項(xiàng)目中使用 CommandLineRunner,感興趣的朋友一起看看吧2025-04-04
詳細(xì)總結(jié)Java for循環(huán)的那些坑
在平常寫代碼的過程中循環(huán)是不可避免的,雖然for的語法并不復(fù)雜,但是在開發(fā)中還是會(huì)遇到一些坑,雖然大部分的坑都是自己的騷操作導(dǎo)致的.今天來總結(jié)一下for循環(huán)在開發(fā)中可能遇到的坑,不要在同樣的問題上再次犯錯(cuò).需要的朋友可以參考下2021-05-05

