Lock in $30 Savings on PRO—Offer Ends Soon! ⏳

Metriken: von Spring Boot bis zu Grafana-Charts

Metriken: von Spring Boot bis zu Grafana-Charts

Unsere Webapplikationen sollen unsere Kunden glücklich machen und einfach zu betreiben sein – aber wie finden wir heraus, welche Bedürfnisse unsere Kunden haben und welche technischen Änderungen sinnvoll sind, ohne die Kunden direkt zu fragen? Die Antwort ist der Build-Measure-Learn-Zyklus – aber wie setzen wir das "Measure" um? Wie können wir Metriken erfassen, durch die wir verstehen, welche Veränderungen oder neuen Features unsere Kunden am glücklichsten machen? Egal, ob das Ziel eine eher klassische oder eine cloud-basierte, horizontal sklierbare Umgebung ist: ein dazu passender, sehr verbreiteter Technologiestack besteht aus Spring Boot, Micrometer, Prometheus und Grafana. Ich möchte in meinem Vortrag sowohl ein wenig theoretisches Basiswissen über Metriken vermitteln als auch die praktische Umsetzung von der Erfassung von Messwerten bis hin zu hübschen Grafana-Charts anhand von konkreten Beispielen zeigen.

Frank Gerberding

November 10, 2021
Tweet

More Decks by Frank Gerberding

Other Decks in Programming

Transcript

  1. @ MilesBehind69 3 „Man muss messen, was messbar ist, und

    messbar machen, was noch nicht messbar ist.“ ( Archimedes) „There is only one boss. The customer.“ ( Sam Walton) @ MilesBehind69
  2. @ MilesBehind69 6 Informationen und deren Nutzung Über das Verhalten

    der Anwender Über technische interne Details Verbesserung bei UX Verbesserung der Stabilität des Systems Alerting (bei Über-/Unterschreitung von Schwellwerten) Post-Mortem-Analyse bei Ausfällen des Systems Informationen Nutzung
  3. @ MilesBehind69 7 Fragen und Messungen ( 1 ) Wo

    muss die Performance 
 verbessert werden? Wie lange dauern 
 Requests ins Backend? Frage Messung
  4. @ MilesBehind69 8 Fragen und Messungen ( 2 ) Wo

    liegen gute Wartungsfenster? Welche Zeitpunkte sind 
 für Mailings usw. günstig? Nutzung zu welchen 
 Tageszeiten und Wochentagen? Fragen Messung
  5. @ MilesBehind69 9 Fragen und Messungen ( 3 ) Welche

    Funktionen sollten 
 wo im User Interface auftauchen? 
 
 Welche Funktionen werden kaum genutzt und können entfernt werden? Wie häufig werden 
 welche Funktionen genutzt? Frage Messung
  6. @ MilesBehind69 10 Fragen und Messungen ( 4 ) Wie

    groß sollte ein Cache sein? Wie ist die Hit-Rate des Caches? Frage Messung
  7. @ MilesBehind69 11 Fragen und Messungen ( 5 ) Welche

    Datenmengen 
 sind zu erwarten? Wie oft werden welche 
 neuen Daten gespeichert? Frage Messung
  8. @ MilesBehind69 13 Zusammenspiel Spring Boot 
 Application Spring Boot

    Actuator scrape Abstract 
 Micrometer 
 Interface Micrometer Prometheus 
 Implementation Application 
 Code Prometheus Grafana query 
 & 
 aggregate collect and store metrics graphical visualization HTTP ( S ) HTTP ( S )
  9. @ MilesBehind69 14 Spring Boot Actuator + Micrometer/Prometheus Dependencies application.yml

    management: metrics: export: prometheus: enabled: true tags: environment: "development" endpoints: web: exposure: include: metrics, prometheus, health #--------------------------------- # production Profile #--------------------------------- --- spring: profiles: production management: metrics: tags: environment: "production" dependencies { 
 implementation("org.springframework.boot", "spring-boot-starter-actuator") implementation("io.micrometer", "micrometer-registry-prometheus", "1.7.5") 
 }
  10. @ MilesBehind69 16 Zusammenspiel Spring Boot 
 Application Grafana collect

    and store metrics graphical visualization Spring Boot 
 Application Fabio load balancer Consul service discovery Prometheus Analysis balance scrape discover instances discover instances register Gatling load test
  11. @ MilesBehind69 17 Zusammenspiel Spring Boot 
 Application Grafana collect

    and store metrics graphical visualization Spring Boot 
 Application Fabio load balancer Consul service discovery Prometheus Analysis balance scrape discover instances discover instances register Gatling load test
  12. @ MilesBehind69 18 Zusammenspiel Spring Boot 
 Application Grafana collect

    and store metrics graphical visualization Spring Boot 
 Application Fabio load balancer Consul service discovery Prometheus Analysis balance scrape discover instances discover instances register Gatling load test
  13. @ MilesBehind69 21 Counter val taxComputerCounter = Counter .builder("metrics_demo.tax_computer.count") .description("counts

    number of calls to tax computer") .baseUnit(BaseUnits.OPERATIONS) .register(meterRegistry) fun computeTax(…) { taxComputerCounter.increment() return … } Counter-Definition Counter-Nutzung
  14. @ MilesBehind69 23 Single Instance vs. Sum rate(http_server_requests_seconds_count{uri="/computeTaxRate" } [5m])

    sum(rate(http_server_requests_seconds_count{uri="/computeTaxRate" } [5m]))
  15. @ MilesBehind69 24 Counter mit Tags private val maximumIncome =

    300_000 private val incomeGranularity = 10_000 private val taxableIncomeTenThousands: List<Counter> = 
 (0..maximumIncome step incomeGranularity).map { 
 Counter .builder("metrics_demo.taxable_income.ten_thousands") .description("distribution of taxable incomes in steps of ten-thousand") .tag("ten_thousands", it.toString()) .register(meterRegistry) 
 } val bucketIndex = (taxableIncome / incomeGranularity) .coerceAtMost(taxableIncomeTenThousands.size - 1) taxableIncomeTenThousands[bucketIndex].increment() Counter-Definition Counter-Nutzung
  16. @ MilesBehind69 26 Counter in Multi-Node-Umgebungen Counter mit Single-Node: t

    node 1 t1 100 t5 220 t node 1 t1 100 t2 120 t3 180 t4 200 t5 220 query scrape ………….. ………….. t sum delta t1 180 0 t2 120 20 t3 180 60 t4 200 20 t5 220 20 Grafana Micrometer Prometheus
  17. @ MilesBehind69 27 Counter in Multi-Node-Umgebungen Counter mit Single-Node: t

    node 1 t1 100 t5 220 t node 1 t1 100 t2 120 t3 180 t4 200 t5 220 query scrape ………….. ………….. Counter mit Multi-Nodes: t node 1 t1 100 t5 220 t node 1 node 2 t1 100 80 t2 120 110 t3 180 160 t4 200 190 t5 220 200 t sum delta t1 180 0 t2 230 50 t3 340 110 t4 390 50 t5 420 30 query scrape ….. ….. t node 2 t1 ——,80 t5 200 ….. ….. scrape t sum delta t1 100 0 t2 120 20 t3 180 60 t4 200 20 t5 220 20 Grafana Grafana Micrometer Prometheus Micrometer Micrometer Prometheus
  18. @ MilesBehind69 31 Timer @GetMapping("/computeTaxRate") @Timed(description = "duration of tax

    computation requests", histogram = true) fun computeTaxRate(@RequestParam taxableIncome: Euro): ResponseEntity<…> { log.debug("compute tax rate for taxable income {}", taxableIncome) return ResponseEntity.ok(cachingTaxComputer.computeTax(taxableIncome)) } val taxComputerTimer = Timer .builder("metrics_demo.tax_computer.requests_time") .description("duration of tax computation") .publishPercentileHistogram() .register(meterRegistry) taxComputerTimer.record { … } taxComputerTimer.record( 
 Duration.ofMillis(…) ) Timer per Annotation Timer manuell
  19. @ MilesBehind69 32 Perzentile in Multi-Node-Umgebungen Counter mit Single-Node: percentile

    limit 80 % < 80ms 90 % < 120ms 95 % < 140ms 99 % < 200ms query scrape percentile limit 80 % < 80ms 90 % < 120ms 95 % < 140ms 99 % < 200ms percentile limit 80 % < 80ms 90 % < 120ms 95 % < 140ms 99 % < 200ms Micrometer Prometheus Grafana
  20. @ MilesBehind69 33 Perzentile in Multi-Node-Umgebungen Counter mit Single-Node: percentile

    limit 80 % < 80ms 90 % < 120ms 95 % < 140ms 99 % < 200ms query scrape Counter mit Multi-Nodes: query scrape scrape percentile limit 80 % < 80ms 90 % < 120ms 95 % < 140ms 99 % < 200ms percentile limit 80 % < 80ms 90 % < 120ms 95 % < 140ms 99 % < 200ms Micrometer Prometheus Grafana Micrometer Micrometer Prometheus Grafana percentile limit 80 % < 80ms 90 % < 120ms 95 % < 140ms 99 % < 200ms percentile limit 80 % < 70ms 90 % < 110ms 95 % < 130ms 99 % < 180ms 218180ms percentile node 1 node 2 80 % < 80ms 80ms < 70ms 80ms 90 % < 120ms < 110ms 95 % < 140ms < 130ms 99 % < 200ms < 180ms percentile sum 80 % ??? 90 % ??? 95 % ??? 99 % ???
  21. @ MilesBehind69 34 Perzentile in Multi-Node-Umgebungen mit Buckets Counter mit

    Multi-Nodes: query scrape scrape Micrometer Micrometer Prometheus Grafana le count 1 ms 1 2 ms 1 4 ms 2 8 ms 2 16 ms 3 32 ms 5 64 ms 5 le node 1 node 2 1 ms 1 0 2 ms 1 1 4 ms 2 1 8 ms 2 3 16 ms 3 3 32 ms 5 4 64 ms 5 5 le sum 1 ms 1 2 ms 2 4 ms 3 8 ms 5 16 ms 6 32 ms 9 64 ms 10 record 1 ms 3 ms 10 ms 20 ms 25 ms Micrometer le count 1 ms 0 2 ms 1 4 ms 1 8 ms 3 16 ms 3 32 ms 4 64 ms 5 record 2 ms 5 ms 8 ms 30 ms 33 ms pctl ms 50 % 8 ms 80 % 32 ms 90 % 32 ms
  22. @ MilesBehind69 37 Wrap-Up Welche Informationen 
 sind nützlich? Welche

    Metriken 
 sind geeignet? Implementierung der Metriken im Code Umsetzung in Dashboards Analyse 
 der Daten Anpassungen in UI und Backend Last-Tests