Wieso ist meine Anwendung eigentlich so langsam?

snail emoji

JUG Saxony Day 2022 · 23.09.2022 · Radebeul bei Dresden


tgbyte bk
Thilo-Alexander Ginkel · Stefan Reuter · TG Byte Software GmbH
kontakt@tgbyte.de · www.tgbyte.de

Wie merke ich, dass meine Anwendung langsam ist?

 
 
 
 
 
 
 
 
 
 
 

Lasttest

  • Erzeugt synthetisch eine reproduzierbare Last auf der Anwendung

  • Lastprofil, das durch Lasttest erzeugt wird, sollte repräsentativ für tatsächliche Nutzung der Anwendung sein

  • Sollte regelmäßig, idealerweise automatisiert im Rahmen der CI/CD-Pipeline ausgeführt werden

Gatling

  • Lasttest mit Fokus auf HTTP-basierten Anwendungen

  • Erzeugen von Szenarios über Capture/Replay ("Recorder") oder über DSL (Java, Kotlin oder Scala)

  • Apache License, Version 2.0

  • gatling.io

Demo

Demo

Woran liegt es, dass meine Anwendung langsam ist?

Ursachen

  • Verwendung ineffizienter Algorithmen

  • Verwendung inperformanter Bibliotheken

  • Behinderung der parallelen Verarbeitung durch ungünstiges Locking

  • Erzeugen unnötig vieler Objekte

  • Erzeugen von Objekten, die nicht wieder freigegeben werden ("Memory Leak")

Profiling

Profiling

  • Analyse des Laufzeitverhaltens von Software

    • Messen von Geschwindigkeit

    • Nebenläufigkeit

    • Speichernutzung

  • umgesetzt über Instrumentierung oder statistische Auswertung (Sampling)

async-profiler

  • Open-Source-Profiler für Java mit geringem Overhead

  • Standalone nutzbar (verbindet sich mit laufendem Java-Prozess) oder als Java Agent

  • Visualisierung als sogenannter Flame Graph

  • Apache License, Version 2.0

  • GitHub Mark 120px plus jvm-profiling-tools/async-profiler

CPU-Profiling

CPU-Profiling

  • Erfasst, wieviel Zeit die JVM in welcher Methode verbringt

  • Sampled Stacktraces, die Java-Methoden, Native-Calls, JVM-Code bis zum Aufruf von Kernelfunktionen umfassen

  • Nutzt perf_events aus dem Linux-Kernel und AsyncGetCallTrace aus der JVM

  • Tipp: JVM mit Debug-Symbolen verwenden, damit Aufrufe innerhalb von libjvm aufgelöst werden können

  • Kernel-Optionen, um als Nicht-Root-Nutzer perf_events zu nutzen:

sysctl kernel.kptr_restrict=0
sysctl kernel.perf_event_paranoid=1

CPU-Profiling

async-profiler -f profile-cpu.html -d 30 -e cpu PetClinicApplication

Lock Profiling

Lock Profiling

  • Erfasst, wie lange Code auf das Betreten eines Monitors/Locks gewartet hat

  • Zähler ist die kumulierte Wartezeit auf das Lock

  • Top Frame: Klasse des Monitors

async-profiler -f profile-lock.html -d 30 -e lock PetClinicApplication

Allocation Profiling

Allocation Profiling

  • Sampled (grobgranular) die Allokation von Speicher

  • Darstellung als Flame Graph, Top Frame: Klasse des allozierten Objekts

async-profiler -f profile-alloc.html -d 30 -e alloc PetClinicApplication

…​und mehr

  • Basic Events:

    • wall, itimer

  • Aufruf von Java-Methoden:

    • ClassName.methodName

  • Perf Events:

    • page-faults, context-switches

    • cycles, instructions

    • cache-references, cache-misses

    • branch-instructions, branch-misses

    • …​

Pyroscope

pyroscope logo

Pyroscope

  • Continuous Profiling

  • Unterstützt viele Technologien (Go, Python, Ruby, PHP, NodeJS, Rust, Java)

  • Java Agent basiert auf async-profiler

  • Apache License, Version 2.0

  • pyroscope.io

pyroscope deployment

Java Integration (1/2)

  • Dependency hinzufügen:

<dependency>
    <groupId>io.pyroscope</groupId>
    <artifactId>agent</artifactId>
    <version>0.10.1</version>
</dependency>
  • Aus Java-Coder heraus starten (z.B. in der main-Methode):

PyroscopeAgent.start(
    new Config.Builder()
        .setApplicationName("petclinic-rest")
        .setProfilingEvent(EventType.CPU)
        .setProfilingLock("0")
        .setProfilingInterval(Duration.of(500, MICROS))
        .setServerAddress("http://localhost:4040")
        .build()
);

Java Integration (2/2)

  • Alternativ beim Starten als Java-Agent angeben:

java -javaagent:pyroscope.jar -jar app.jar
  • Konfiguration über Umgebungsvariablen, u.a.

    • PYROSCOPE_APPLICATION_NAME

    • PYROSCOPE_SERVER_ADDRESS

    • PYROSCOPE_PROFILING_INTERVAL

    • PYROSCOPE_PROFILER_EVENT

    • PYROSCOPE_PROFILER_LOCK

    • PYROSCOPE_PROFILER_ALLOC

Demo

Q&A – Fragen?

 
 
 
 
 

tgbyte bk
www.tgbyte.de

Thilo-Alexander Ginkel · Stefan Reuter
thilo.ginkel@tgbyte.de · stefan.reuter@tgbyte.de

Bildnachweis (1/2)

Bildnachweis (2/2)