Die Überwachung der Anwendungsleistung ist entscheidend in der modernen Softwareentwicklung. In diesem Blog-Artikel zeige ich dir das Performance Monitoring durch die Messung der Ausführungsdauer von Methoden in einer Spring Boot-Anwendung. Wir verwenden dazu benutzerdefinierte Annotations, AOP und Prometheus.
Vorausgesetzter Tech-Stack
- Spring Boot-Anwendung (hier gebaut mit Maven)
- Prometheus als Monitoring-Tool
- Grafana für die Darstellung der Daten
Implementierung
1. Abhängigkeiten hinzufügen
Füge die Abhängigkeiten für den Spring Boot Actuator, AOP und Micrometer in deine pom.xml
ein.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
2. Prometheus Endpoint freigeben
In deiner application.properties
füge gegebenenfalls die folgende Zeile hinzu, um den Endpunkt /actuator/prometheus
zu aktivieren, sodass Prometheus die Metriken hier abrufen kann.
management.endpoints.web.exposure.include=prometheus
3. Annotation TimedMethod
erstellen
Erstelle eine benutzerdefinierte Annotation namens TimedMethod
. Diese Annotation ermöglicht es dir, spezifische Methoden für die Zeitmessung zu markieren.
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface TimedMethod {
String value() default "";
}
4. Aspect TimingAspect
erstellen
Implementiere danach einen Aspect, der die annotierten Methoden abfängt. Die Klasse verwendet Spring’s AOP (Aspect-Oriented Programming) und Micrometer, um die Ausführungszeit der Methode zu messen. Es empfiehlt sich, den Namen der Anwendung als Prefix hinzuzufügen.
@Aspect
@Component
public class TimingAspect {
private final MeterRegistry meterRegistry;
public TimingAspect(MeterRegistry meterRegistry) {this.meterRegistry = meterRegistry;}
@Around("@annotation(TimedMethod)")
public Object timeMethod(ProceedingJoinPoint pjp) {
final var methodName = "performance-monitoring_method_" + pjp.getSignature().getName();
final var timer = Timer.builder(methodName).description("Total time of " +
pjp.getSignature().getName() + " method").register(meterRegistry);
try {
return timer.recordCallable(() -> {
try {
return pjp.proceed();
} catch (Throwable t) {
// Handle or log the exception as needed
throw new RuntimeException(t);
}
});
} catch (Exception e) {
// Handle or log the exception as needed
throw new RuntimeException(e);
}
}
}
5. Methoden annotieren
Die @TimedMethod
-Annotation kann jetzt zu den Methoden ergänzt werden, die du überwachen willst.
@TimedMethod
public void foo() {
// ...
}
@TimedMethod
public void bar() {
// ...
}
6. Prometheus Ausgabe
Nachdem du deine Anwendung gestartet hast, sollten die benutzerdefinierten Metriken unter dem Prometheus-Endpunkt http://localhost:8080/actuator/prometheus
verfügbar sein. Die Ausgabe könnte so aussehen:
Da das Performance Monitoring für zwei Methoden erfolgt, sehen wir auch zwei Blöcke an Metriken.
Füge diese Metriken zu deinem Grafana-Dashboard hinzu, um sie zu überwachen und in verschiedenen Graphen anzuzeigen.
Beispielprojekt
Das ausführbare Beispielprojekt mit sämtlichem Code ist hier zu finden: https://gitlab.com/pep-digital/blog/performance-monitoring
Zusammenfassung
Dieser Blog-Beitrag hat gezeigt, wie die Performance von Methoden in einer Spring Boot-Anwendung effektiv überwacht werden können. Natürlich kann die Implementierung an verschiedenen Stellen noch ausgebaut werden.
Neben Timern bietet Micrometer außerdem eine Reihe weiterer Metrik-Typen, die in Spring Boot Anwendungen genutzt werden können:
- Counter: Ein einfacher Zähler, der nur inkrementiert werden kann. Häufig verwendet für die Zählung von Anfragen, Aufgaben, Fehlern usw.
- Gauge: Ein Messwert, der den aktuellen Wert eines bestimmten Objekts oder einer Variable anzeigt.
- Distribution Summary: Ähnlich wie ein Timer, aber für die Messung von nicht-zeitbezogenen Verteilungen wie Dateigrößen, Punktzahlen usw.
- Long Task Timer: Für die Messung von lang laufenden Aufgaben, die parallel zu anderen Aufgaben laufen können.
- Function Counter: Ein Counter, der den Wert einer Funktion über die Zeit hinweg inkrementiert.
- Function Gauge: Ein Gauge, der den Wert einer Funktion auswertet, wenn der Wert abgerufen wird.
- Time Gauge: Ein Gauge, der die Zeit in Sekunden misst, die eine Funktion zum Ausführen benötigt.
- Meter: Ein allgemeiner Typ für andere benutzerdefinierte Metriken, der mehrere Messungen gleichzeitig darstellen kann.
Diese verschiedenen Metrik-Typen ermöglichen eine umfassende Überwachung und Analyse des Verhaltens von Spring Boot Anwendungen.
Mit Spring Boot, Micrometer, benutzerdefinierten Annotations und Prometheus hast du auf jeden Fall eine starke Lösung für das Performance-Monitoring an der Hand!