$30 off During Our Annual Pro Sale. View Details »

[CLOUD NORD 22] Java dans le Cloud:Avec Spring ou Quarkus?

[CLOUD NORD 22] Java dans le Cloud:Avec Spring ou Quarkus?

Après presque 20 ans, la vieille guerre « Java EE vs Spring » semble enfin terminée ! Comparer une spécification avec un framework n’avait pas grand sens. Surtout quand on a réalisé que Spring s’appuie (en partie) sur Java (maintenant Jakarta) EE.

Et voici un nouvel acteur arriver : Quarkus … Un framework Subatomic et Supersonic !

Spring vs Quarkus, framework vs framework : une nouvelle guerre en vue ? Une vraie ? Pas forcément ... Plutôt que de les opposer, nous vous proposons de les comparer concrètement sur des cas d’usage précis : API REST, persistance, programmation réactive, code natif, test …

Nous avons besoin de vous pour y voir plus clair : nous vous mettrons à contribution avec des sondages en live pendant nos démos.

A l’issue de cette présentation, nous aurons une vue complète et objective de ce qui les rapproche et ce qui les différencie. Nous saurons également comment transposer cette réflexion et faire le bon choix pour nos prochains projets.

Alexandre Touret

September 30, 2022
Tweet

More Decks by Alexandre Touret

Other Decks in Programming

Transcript

  1. Java dans le Cloud:
    Avec Spring ou Quarkus?
    Jean-François JAMES @jefrajames
    Alexandre TOURET @touret_alex

    View Slide

  2. Qui sommes-nous?
    Jean-François JAMES
    @jefrajames
    jefrajames.fr
    Alexandre TOURET
    @touret_alex
    blog.touret.info
    2

    View Slide

  3. Un rapide sondage
    3
    bit.ly/javacloud-cloudnord-1

    View Slide

  4. From Enterprise to Cloud-native applications
    4
    Enterprise Cloud-native
    Traditional monitoring Based on built-in observability
    Feature driven development API driven development
    Hardware-based fault tolerance Software built-in fault tolerance
    Embedded config files External and extendable configuration
    A few long-lasting instances Many ephemeral instances
    Slow dev & test lifecycle Fast dev & test lifecycle
    Imperative only programming Imperative & reactive programming

    View Slide

  5. Deux frameworks
    ▷ Spring est né dans les 2000’s
    ▷ Spring Boot est né en 2014
    ▷ Spring Boot a pour but de
    créer des applications Spring
    de manière simple
    ▷ Il a évolué au fil des ans pour
    répondre aux contraintes du
    Cloud
    ▷ Lancé par Red Hat en 2019
    ▷ Réutilisation :
    ○ Jakarta EE, MicroProfile
    ○ Vert.x, SmallRye, WildFly
    ▷ Innovation :
    ○ Facilité de Dev & Test
    ○ Démarrage & chauffe rapide
    ○ Empreinte mémoire réduite
    ○ Exécution en mode natif
    5

    View Slide

  6. 6

    View Slide

  7. Six rounds pour les challenger

    Round 1: Modèle de programmation

    Round 2: Persistence en base de données

    Round 3: Monitoring & Observabilité

    Round 4: Tolérance aux pannes

    Round 5: La programmation réactive

    Round 6: Cloud
    7

    View Slide

  8. 1.
    Notre cas d’utilisation
    Ou comment challenger Spring et Quarkus sur un cas
    concret …
    8

    View Slide

  9. Application
    Bookstore
    9
    User
    BookStoreService
    API
    Provides an API to manage books
    BookNumberService
    API
    Provides ISBN Numbers
    Get/Create Books
    [JSON/HTTP]
    JAEGER
    Store Exposes distributed
    tracing logs
    Get ISBN
    [JSON/HTTP]
    JDBC
    Pull
    Metrics
    Pull
    Metrics
    Send tracing
    [UDP]
    Send Tracing
    [UDP]

    View Slide

  10. Deux implémentations
    https://github.com/alexandre-
    touret/bookstore_spring
    https://github.com/alexandre-
    touret/bookstore-reactive_spring
    https://github.com/jefrajames/bookstore
    10

    View Slide

  11. 2.
    Modèle de programmation
    11

    View Slide

  12. Des nuances sans réels différenciants
    12
    REST API Spring MVC
    Spring Web Reactive
    RestEasy imperatif &
    reactive
    API Documentation Swagger/OpenAPI MicroProfile OpenApi
    Injection de dépendance Spring IoC Jakarta EE CDI
    Configuration Intégré dans Spring Boot MicroProfile Config

    View Slide

  13. Quid du mode natif ?
    13

    View Slide

  14. Natif vs JVM
    ▷ Un même code base, 2 modes d'exécution
    ▷ Basé sur GraalVM : projet expérimental Oracle
    ▷ Compilation binaire : Ahead Of Time (vs JIT) compiler
    ▷ Exécution avec SubstrateVM : une JVM "triviale"
    ▷ Démarrage ultra rapide x10
    ▷ Empreinte mémoire réduite %2
    ▷ Processus de build long et gourmand > 3min
    14
    SubstrateVMCE pas aussi puissante qu’une « vraie» JVM (Hotspot, J9)
    Pas de class de chargement et d'instrumentation de classes à la volée

    View Slide

  15. Spring native vs Quarkus
    ▷ Spring supporte depuis peu la
    création de binaires natifs via
    spring-native
    ▷ Prévu pour Spring Boot 3
    ▷ "Support natif" du mode natif
    ▷ Red Hat Mandrel : distribution
    spécialisée GraalVM
    ▷ Ne pas oublier les tests natifs !
    15
    Le mode natif cible les instances éphémères
    La JVM reste pertinente pour les instances de longue durée
    Approche hybride : instances longues durées pour le flux standard +
    instances éphémères pour les pics de trafic

    View Slide

  16. 3.
    Persistence des données
    16

    View Slide

  17. Spring Data vs Panache
    ▷ Spring Data supporte plusieurs technos
    ▷ Implémente le pattern Repository
    ▷ Fournit plusieurs fonctionnalités
    avancées : pagination, tri, …
    ▷ JPA avec Panache !
    ▷ Pagination, filtrage, audit ...
    ▷ Patterns Repository & Active Record
    ▷ Supporte aussi MongoDB
    ▷ Des extensions pour Redis, Cassandra,
    Neo4J et Elasticsearch
    17

    View Slide

  18. Spring Data vs Panache
    18
    public long count() {
    return bookRepository.count();
    }
    public Optional findBookById(Long id) {
    return bookRepository.findById(id);
    }
    public Book updateBook(@Valid Book book) {
    return bookRepository.save(book);
    }
    @ApplicationScoped
    public class BookService {
    public List findAllBooks() {
    return Book.listAll();
    }
    public long count() {
    return Book.count();
    }
    @Transactional
    public Book registerBook(@Valid Book book) {
    Book.persist(book);
    return book;
    }
    […]
    }
    @Entity
    public class Book extends PanacheEntity {
    public String title;
    public Integer nbOfPages;
    […]
    }

    View Slide

  19. 4.
    Monitoring & Observabilité
    19

    View Slide

  20. Observabilité

    Au-delà du monitoring « traditionnel »

    Des services distribués, déployés
    « quelque part » dans le cloud

    Pas de maîtrise de l'infra

    Besoin avancé de télémétrie
    20
    Distributed
    tracing
    Metrics
    Health checks

    View Slide

  21. Spring Actuator vs MicroProfile
    ▷ Spring Actuator
    ○ Audit
    ○ Health
    ○ Metrics
    ▷ Micrometer Metrics
    ▷ OpenTelemetry
    ▷ MicroProfile
    ○ Health
    ○ Metrics
    ○ OpenTracing
    ▷ Supporte également
    ○ Micrometer
    ○ OpenTelemetry
    21

    View Slide

  22. 5.
    Tolérance aux pannes
    22

    View Slide

  23. “Gérer” les pannes
    23
    Comment gérer les
    “timeout” ?
    Comment gérer les
    “retry”
    Comment faire un
    “fallback” ?
    Comment éviter
    l’effet “boule de
    neige” quand tout
    commence à aller
    mal ?
    Les pannes et latences sont
    inévitables!

    View Slide

  24. Fault Tolerance
    24
    Basé sur MP FaultTolerance:
    o @Timeout, @Retry, @Fallback, @CircuitBreaker,
    @Asynchronous, @BulkHead
    Basé sur Resilience4J:
    o En remplacement de Hystrix
    o Configuration programmatique
    @Bean
    public Customizer
    createSlowNumbersAPI…() {
    return factory -> factory.configure(
    builder ->
    builder.circuitBreakerConfig(CircuitBreakerConfig.ofDefaults())
    .timeLimiterConfig(TimeLimiterConfig.custom()
    .timeoutDuration(Duration.ofSeconds(timeoutInSec))
    .build()), "slowNumbers");
    }
    public Book registerBook(@Valid Book book) {
    circuitBreakerFactory.create("slowNumbers").run(
    () -> persistBook(book),
    throwable -> fallbackPersistBook(book)
    );
    @Fallback(fallbackMethod = "fallbackPersistBook")
    public Book registerBook(@Valid Book book) {
    IsbnNumbers numbers=proxy.generateIsbnNumbers();
    […]
    }
    // Number service not available!
    private Book fallbackPersistBook(Book book) {
    // Store the book creation request locally
    […]
    }

    View Slide

  25. 6.
    Programmation réactive
    25

    View Slide

  26. Les enjeux de la programmation réactive
    26
    Modèle de concurrence historique Java basé sur threads OS
    Programmation impérative simple : un thread/requête, bloqué en IO
    Mais thread OS lourd et limité en quantité
    Comment gérer facilement des millions de requêtes concurrentes?
    La programmation réactive apporte une réponse ...
    Peu de threads, jamais bloqués
    Programmation plus complexe

    View Slide

  27. Programmation réactive
    27
    Vert.X : moteur d'exécution réactif
    Codage métier impératif ou réactif
    API réactive "intuitive" Mutiny
    Réactif de bout en bout :
    ▪ façade
    ▪ logique métier
    ▪ persistance
    Le projet Reactor fournit tous les outils pour
    rendre réactif une application
    Netty: moteur d’exécution
    L' API Spring WebFlux
    L’ API impérative et réactive n’est pas totalement
    unifiée (R2DBC pour les SGBDR)
    Courbe d'apprentissage "brutale" pour passer au réactif !
    Pas valable si traitement limité par la CPU

    View Slide

  28. La promesse de Loom
    28
    Programmation simple et concurrence efficace
    "Virtual Thread" léger géré par la JVM
    Potentiellement des millions/JVM
    Des threads OS en arrière-plan et en nombre limité ('"carrier thread")
    Disponible en "preview" avec Java 19 (09/2022) => en LTS avec Java 21 (09/2023)
    L'écosystème Java doit s'adapter dans sa globalité : exemple de Helidon Nima
    Quarkus compatible Loom
    Annotation @RunOnVirtualThread
    Méthodes non bloquantes pour le "carrier thread"

    View Slide

  29. 7.
    Cloud
    31

    View Slide

  30. Images Docker
    ▷ Spring fournit l’outillage pour
    créer des images avec ou sans
    Dockerfile
    ▷ Cloud Native Buildpack
    ▷ Des extensions pour créer des
    images JVM et natives
    ▷ Docker classique
    ▷ JIB
    ▷ S2I
    ▷ BuildPack
    32

    View Slide

  31. Et notre application dans tout ça ?
    Pour l’ application rest-book (Spring)
    ▷ Temps de démarrage
    ○ Version impérative
    ■ JVM: ~10sec
    ■ RSS: ~600Mo
    ○ Version “réactive”
    ■ JVM: ~4 sec
    ■ RSS: ~300Mo
    ▷ Taille des images Docker:
    330Mo
    Pour l’ application rest-book
    ▷ Temps de démarrage:
    ○ JVM : ~2 sec, RSS: ~200 Mo
    ○ Native : ~0,3 sec, RSS: ~95 Mo
    ▷ Taille des images Docker :
    ○ De 200 à 440 Mo
    33

    View Slide

  32. Intégration avec Kubernetes
    ▷ L’observabilité est
    réalisée avec Actuator
    ▷ Grâce à Spring Cloud,
    on peut interagir avec
    K8S
    ▷ Attention au temps de
    démarrage!
    ▷ "A Kubernetes Native Java stack"
    ▷ Runtime :
    ○ Démarrage & chauffe accélérée
    ○ Empreinte mémoire réduite
    ▷ Appli :
    ○ Observable
    ○ Résistante aux pannes
    ○ Réactive
    ▷ Config K8S "ready-to-use”
    34

    View Slide

  33. Intégration avec les composants des
    clouds publics
    ▷ Spring cloud offre un
    panel de starters pour
    interagir avec les
    clouds publics
    ▷ Spring Cloud Function
    ▷ AWS: Lambda, S3, DynamoDB,
    Secret Manager …
    ▷ GCP: Big Query, Big Table, Pub
    Sub, Google Cloud Functions …
    ▷ Azure Functions
    ▷ Attention au support Red Hat
    35

    View Slide

  34. 36
    Differenciator
    API support ***** ***** no
    Dependency Injection ***** ***** no
    Configuration ***** ***** no
    Persistency ***** **** yes
    Batch processing ***** **** yes
    Reactive programming **** ***** yes
    Testing ***** ***** yes
    Observability ***** ***** no
    Fault tolerance **** ***** yes
    Native execution *** ***** yes
    Containerization support ***** ***** no
    K8S support **** ***** yes
    Public cloud support ***** ***** yes
    Adoption & ecosystem ***** **** yes

    View Slide

  35. Nos conseils
    37
    ▷ Quarkus : une transition aisée pour les dev "pur Java EE"
    ▷ SpringBoot : une continuité pour les dev Spring
    ▷ Aujourd'hui:
    ○ Net avantage Quarkus sur natif et réactif
    ○ Ecosystème et adoption en faveur de Spring
    ▷ Ce "comparatif" va évoluer au fil du temps et des versions
    ▷ Au final: une saine compétition entre 2 solutions qui modernisent Java pour le Cloud

    View Slide

  36. Un rapide sondage
    38
    bit.ly/javacloud-cloudnord-2

    View Slide

  37. Merci de votre feedback!
    39

    View Slide

  38. Merci!
    Des questions?
    Jean-François JAMES @jefrajames
    Alexandre TOURET @touret_alex
    40

    View Slide