20201105 - DeliveryParis - QuickPerf pour mieux maitriser la performance applicative

by Thierry de Pauw on

##DeliveryParis

QuickPerf: librairie de tests pour mieux maîtriser la performance applicative, Jean Bisutti @Jean_bisutti

travaille à Zenika

at Continuous Delivery Paris meetup, @DeliveryParis

Est-ce que vous exécuter vos tests de performances au moins une fois par jour?

Si vous n'exécuter pas vos tests de performances une fois par jours, vous ne savez pas quel commit a impacter la performance.

Qu'est-ce qu'est la Performance?

Comment savoir si la performance est assez bonne pour aller en production?

Throughput/Bandwidth: nombre de requête par seconde

Latency/Response time: le temps de réponse de la requête

un Tuyau:
throughput = diamètre du tuyau
latence = la longueur du tuyau

Load Testing: JMeter, Gatling, ...
il faut le même environnement qu'en production (même DB, OS, type de serveur, ...)

Performance Testing:
- test de throughput / Throughput
- test de latence / Latency
- test d'endurance / Soak => Memory leak detection
= sous mettre l'application sous une longue endurance pour détecter des mauvais comportements

Monitor / Analyze performance:
Dynatrace, datadog, NewRelic, ...
Prometheus

Profiler: JProfiler, YourKit, JDK Mission Control
utilisé sur votre poste de travail

Test de micro benchmarking: Java Microbenchmark Harness (JMH)
= tester la performance pour une toute petite partie de l'application, mais peux être une prise de tête (optimisation JVM), plutôt pour des librairies style trading

Cache applicatif: il faut d'abord chauffer l'application pour remplir le cache avant d'exécuter les tests de performance
=> Tests de Performance prennent plusieurs heures
=> Mini load test/ Mini batch => durée de quelques minutes sur un subset de la base de données et un subset du hardware
=> feedback plus rapide

The longer the time between the point where a problem is introduced and the point of discovering it, the more difficult it will be to find the source of the problem and fix it.
-- Continuous Delivery book

Analyzing and fixing performance issues is time consuming!

étude de JRebel: en général il faut plusieurs jours pour trouver et corriger un problème de performance

Risk on production without an exhaustive feedback on performance
vu que les tests de performance sont long, on ne teste pas tout les uses cases

Si on fesait des tests exhaustive, on aurait besoin d'un plus gros hardware et les builds de nuit pourrait ne pas être terminé à la fin de la nuit

Bottlenecks are like "performance bombs" hidden in the code

Horizontal scaling

pour avoir une performance adéquate

pour moi scaler c'est looser: on compense un problème de performance par du scaling horizontal
=> jeter de l'argent par les venêtres et pas sympa pour la planète

Not everyone needs high performance but the blatant waste and energy consumption of our industry cannot continue
-- Martin Thompson, @mjpt777

Performance issue? -> quand il est corrigé, introduire un nouveau test qui détecte le problème

Early performance checks?

We should target about small efficiencies, say about 97% of the time:
premature optimization is the root of all evil
Yet we should not pass up our opportunities in that critical 3%.
-- Donald Knuth

Dynatrace: Top 10 performance problems
1. too many database calls

Lukas Eder (jOOQ) paper

Early performance checks are context dependant
- database
limit JDBC roundtrips (no N+1 select, JDBC batching, ...)
spot long queries
bind parameters (most of the time a best practice)
=> may be always checked

  • JVM mini batch => check memory allocation (keep it low, no need for 1Gb) memory computation => check memory allocation cache => check and estimate memory allocation no memory leak

donc on a une idée des choses qu'on peut détecter de manière précosse dans le développement applicatif

Measure don't Guess

Test Pyramid

Mike Cohn

plain
^
UI Tests | More integration
Service Tests | More execution time, Cost
Unit Tests |

Qu'est-ce que serait la pyramide des testes en testes de performances?

```plain
Endurance test ~ hours | Isolated prod
Batch, Load test ~ minutes | performance requirements

Mini load test
Mini batch

N+1 select detection -> memory ~ 5 seconds
Not bind params -> memory
Cache with less data -> allocation
=> testes unitaires de perf
```

Try to detect Memory Leaks in seconds instead of after an endurance test that takes hours to execute

=> CI: 3 étapes
1. testes unitaires
2. mini load test
3. load test

Test Driven Development for performance

...

QuickPerf

java
@ExpectJdbcBatching
@Test
public void test_batch_execution() {}

SQL annotations:
java
@ExpectSelect(1)
@Test
public void should_find_all_players() {}

JVM annotations:
java
@MeasureHeapAllocation
@HeapSize(value = 1, unit = AllocationUnit.GIGA_BYTE)
@Test
public void test_batch_execution() {}

@ProfileJvm @ExpectNoJvmIssue

Quickly find why performance-related properties are not as we think
=> JDBC batching is disabled
=> You should check that spring.jpa.hibernate.jdbc.batch_size property has a positive value
=> ...
=> Perhaps you are facing an N+1 select issue

Summary

QuickPerf is a testing library for Java to quickly evaluate and improve some performance-related properties
- provides annotations => Quick and easy to use, i.e. non-regression
- suggestions and JVM profiling helping to improve some properties
- efforts to integrate QuickPerf to the Java ecosystem

Early feedback on some performance-related properties during development or from CI
=> early reduce performance risks
=> reduce time to analyze performance issues
=> less rework
=> more environment-friendly software (ecology)

TDD workflow with some performance related properties
Define quality attribute
=> Red => Implement: Green => Refactor: improve readability and design
TDD architecture using ArchUnit

Works with JUnit 4, JUnit 5, TestNG
Recommendations for Hibernate, Spring Data
preliminary support for Micronaut, Quarkus