Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Faster, greener, and happier- why Quarkus should be your next tech stack

Faster, greener, and happier- why Quarkus should be your next tech stack

Java never went away, but it’s having a renaissance. After some initial teething pains on the cloud (too big, too slow, too hard to configure) a new breed of Java frameworks are changing everything. In this talk, Holly will introduce Quarkus and then delve into some of the advanced features you might not know about. She’ll cover native binaries, what makes Quarkus super-fast running on the JVM, TDD with Quarkus, and Quarkus’s carbon footprint. The talk includes some theory (what underpins Quarkus’s surprising speed?) and also live demos (does Quarkus really start faster than a light bulb? What does an integration testing flow with Quarkus look like?)

Holly Cummins

March 06, 2024
Tweet

More Decks by Holly Cummins

Other Decks in Programming

Transcript

  1. Holly Cummins Senior Principal Software Engineer, Quarkus Voxxed Days Zurich

    March 7, 2024 @[email protected] faster greener happier why quarkus should be your next tech stack
  2. @holly_cummins #RedHat tea: slow feedback loop→developers drink a lot of

    tea the problems: typing: verbose programming model → repetitive boilerplate
  3. @holly_cummins #RedHat tea: slow feedback loop→developers drink a lot of

    tea the problems: typing: verbose programming model → repetitive boilerplate tedium
  4. @holly_cummins #RedHat “I can’t bring up the microservices in my

    Java dev stack … on my brand new Apple laptop with a M1 chip and 64GB of RAM.” - fintech CTO
  5. @holly_cummins #RedHat in production, it’s worse example microservices maths: airline

    maintenance scheduling system single service: ½ core + 1 GB RAM
  6. @holly_cummins #RedHat in production, it’s worse example microservices maths: airline

    maintenance scheduling system single service: ½ core + 1 GB RAM HA → 3x instances
  7. @holly_cummins #RedHat in production, it’s worse example microservices maths: airline

    maintenance scheduling system single service: ½ core + 1 GB RAM HA → 3x instances ~100 microservices
  8. @holly_cummins #RedHat in production, it’s worse example microservices maths: airline

    maintenance scheduling system single service: ½ core + 1 GB RAM HA → 3x instances ~100 microservices = 150 cores + 300 GB RAM
  9. @holly_cummins #RedHat Container platform machine node.js node.js node.js node.js node.js

    node.js node.js machine go go go go go go go go go go go go go go
  10. @holly_cummins #RedHat Container platform machine HotSpot Heap HotSpot Heap HotSpot

    Heap HotSpot Heap machine node.js node.js node.js node.js node.js node.js node.js machine go go go go go go go go go go go go go go
  11. @holly_cummins #RedHat tea: slow feedback loop→developers drink a lot of

    tea the problems: typing: verbose programming model → repetitive boilerplate
  12. @holly_cummins #RedHat tea: slow feedback loop→developers drink a lot of

    tea the problems: typing: verbose programming model → repetitive boilerplate treasure: high resource usage → cloud vendors get lots of money
  13. @holly_cummins #RedHat on-prem dedicated hardware long-lived processes deployment is an

    annual event late-binding what old frameworks were optimised for
  14. @holly_cummins #RedHat on-prem dedicated hardware long-lived processes deployment is an

    annual event late-binding re-configurable without restart what old frameworks were optimised for
  15. @holly_cummins #RedHat traditional cloud-native java stack traditional cloud-native java stack

    traditional cloud-native java stack traditional cloud-native java stack node.js node.js node.js node.js node.js node.js node.js go go machine go go go go go go go go go go go go go go go go go go go quarkus quarkus quarkus quarkus quarkus quarkus quarkus quarkus quarkus quarkus quarkus quarkus quarkus quarkus spoiler: we made stuff better :) container orchestration machine machine machine https:/ /developers.redhat.com/blog/2017/03/14/java-inside-docker/
  16. @holly_cummins #RedHat machine quarkus quarkus quarkus quarkus quarkus quarkus quarkus

    quarkus quarkus quarkus quarkus quarkus quarkus quarkus container orchestration machine traditional cloud-native java stack traditional cloud-native java stack traditional cloud-native java stack traditional cloud-native java stack … a lot better quarkus native
  17. @holly_cummins #RedHat machine quarkus quarkus quarkus quarkus quarkus quarkus quarkus

    quarkus quarkus quarkus quarkus quarkus quarkus quarkus container orchestration machine traditional cloud-native java stack traditional cloud-native java stack traditional cloud-native java stack traditional cloud-native java stack … a lot better quarkus native (but quarkus on jvm is also way smaller than traditional java)
  18. quarkus applications start fast quarkus + graalvm 0.014 Seconds rest

    application quarkus + open jdk 0.75 Seconds traditional cloud-native stack 4.3 Seconds https://quarkus.io/blog/runtime-performance/
  19. ok but does startup time matter? fast boot time means

    auto-scaling works better more resilience to load spikes
  20. quarkus + GraalVM 13 MB quarkus + OpenJDK 74 MB

    Traditional Cloud-Native Stack 140 MB rest application https://quarkus.io/blog/runtime-performance/ quarkus improves memory utilization
  21. #Quarkus @holly_cummins hey, wanna see quarkus? hey, wanna see quarkus?

    hey, wanna see quarkus? hey, wanna see quarkus? hey, wanna see quarkus?
  22. #Quarkus @holly_cummins hey, wanna see quarkus? hey, wanna see quarkus?

    hey, wanna see quarkus? hey, wanna see quarkus? hey, wanna see quarkus? uhh … are you supposed to shut down applications after using them?
  23. #Quarkus @holly_cummins hey, wanna see quarkus? hey, wanna see quarkus?

    hey, wanna see quarkus? hey, wanna see quarkus? hey, wanna see quarkus? uhh … are you supposed to shut down applications after using them? 120 instances (!)
  24. @holly_cummins #RedHat remember the airline scheduling application? “[With Quarkus], we

    can run 3 times denser deployments without sacrificing availability and response times of services. ” – Fawaz Thorsten Pohl
  25. quarkus applications also have higher throughput 48 concurrent connections quarkus

    native 3212 req/s https://www.redhat.com/en/resources/mi-quarkus-lab-validation-idc-analyst-paper
  26. quarkus applications also have higher throughput 48 concurrent connections traditional

    cloud native stack 3555 req/s quarkus native 3212 req/s https://www.redhat.com/en/resources/mi-quarkus-lab-validation-idc-analyst-paper
  27. quarkus applications also have higher throughput 48 concurrent connections traditional

    cloud native stack 3555 req/s quarkus on jvm 6389 req/s quarkus native 3212 req/s https://www.redhat.com/en/resources/mi-quarkus-lab-validation-idc-analyst-paper
  28. traditional cloud native stack 3555 req/s quarkus on jvm 6389

    req/s quarkus native 3212 req/s https://www.redhat.com/en/resources/mi-quarkus-lab-validation-idc-analyst-paper
  29. traditional cloud native stack 3555 req/s quarkus on jvm 6389

    req/s quarkus native 3212 req/s https://www.redhat.com/en/resources/mi-quarkus-lab-validation-idc-analyst-paper a trade-off of throughput against footprint
  30. traditional cloud native stack 3555 req/s quarkus on jvm 6389

    req/s quarkus native 3212 req/s https://www.redhat.com/en/resources/mi-quarkus-lab-validation-idc-analyst-paper no trade-off, just better :) a trade-off of throughput against footprint
  31. @holly_cummins #RedHat a highly dynamic runtime in a container is

    pointless loading classes that aren’t needed
  32. @holly_cummins #RedHat a highly dynamic runtime in a container is

    pointless loading classes that aren’t needed expensive, slow, reflection
  33. @holly_cummins #RedHat a highly dynamic runtime in a container is

    pointless loading classes that aren’t needed expensive, slow, reflection the same initialisation on every startup
  34. @holly_cummins #RedHat how does a java framework start? </> build

    time runtime load and parse • config files • properties • yaml • xml • etc.
  35. @holly_cummins #RedHat how does a java framework start? @ @

    </> build time runtime • classpath scanning and annotation discovery • attempt to load class to enable/disable features
  36. @holly_cummins #RedHat how does a java framework start? @ @

    </> build time runtime build a metamodel of the world
  37. @holly_cummins #RedHat how does a java framework start? @ @

    </> build time runtime start • thread pools • I/O • etc.
  38. @holly_cummins #RedHat how does a java framework start? @ @

    </> build time runtime ready to do work!
  39. @holly_cummins #RedHat @ @ </> build time runtime start •

    thread pools • I/O • etc. what if we initialize at build time?
  40. @holly_cummins #RedHat @ @ </> build time runtime ready to

    do work! start • thread pools • I/O • etc. what if we initialize at build time?
  41. ok but we don’t need native quarkus is faster and

    smaller than legacy frameworks, even running on the jvm
  42. doing more up-front enables better devex runtime build time we

    can do cool code introspections here that would be too expensive and annoying to do at runtime @ @ </>
  43. ok but we don’t need reactive quarkus is good at

    reactive, but it’s also very good at normal programming
  44. ok but we don’t need reactive quarkus is good at

    reactive, but it’s also very good at normal programming most quarkus users do not use reactive
  45. @holly_cummins #RedHat tests are run on every code change “reverse

    code coverage” means only relevant tests run mvn quarkus:dev continuous testing
  46. @holly_cummins #RedHat testcontainers integration … without quarkus @TestConfiguration(proxyBeanMethods = false)

    public class ContainersConfig { @Bean @ServiceConnection public PostgreSQLContainer<?> postgres() { return new PostgreSQLContainer<>(DockerImageName.parse("postgres:14")); } } public class TestApplication { public static void main(String[] args) { SpringApplication .from(MySpringDataApplication::main) .with(ContainersConfig.class) .run(args); } } @Import(ContainersConfig.class)
  47. @holly_cummins #RedHat zero-config testcontainers integration the only thing you need

    to do to make testcontainers work is not configure anything # configure your datasource quarkus.datasource.db-kind = postgresql quarkus.datasource.username = sarah quarkus.datasource.password = connor quarkus.datasource.jdbc.url = jdbc:postgresql://localhost:5432/mydatabase # drop and create the database at startup quarkus.hibernate-orm.database.generation = drop-and-create
  48. @holly_cummins #RedHat zero-config testcontainers integration the only thing you need

    to do to make testcontainers work is not configure anything # drop and create the database at startup quarkus.hibernate-orm.database.generation = drop-and-create
  49. @holly_cummins #RedHat zero-config testcontainers integration the only thing you need

    to do to make testcontainers work is not configure anything
  50. @holly_cummins #RedHat zero-config testcontainers integration the only thing you need

    to do to make testcontainers work is not configure anything quarkus also auto-invokes flyway and liquibase
  51. @holly_cummins #RedHat zero-config testcontainers integration realistically, use profiles so things

    work in production :) # configure your datasource %prod.quarkus.datasource.db-kind = postgresql %prod.quarkus.datasource.username = sarah %prod.quarkus.datasource.password = connor %prod.quarkus.datasource.jdbc.url = jdbc:postgresql://localhost:5432/mydatabase # on real databases, defaults to ‘none’, but let’s validate %prod.quarkus.hibernate-orm.database.generation = validate
  52. @holly_cummins #RedHat • databases • redis • keycloak • kafka

    • elasticsearch • kubernetes • … or add your own auto-provision services “dev services” using testcontainers under the hood
  53. @holly_cummins #RedHat package com.example; import org.jboss.logging.Logger; public class MyService {

    private static final Logger log = Logger.getLogger(MyService.class); public void doSomething() { log.info("It works!"); } } example: logging
  54. @holly_cummins #RedHat package com.example; import org.jboss.logging.Logger; public class MyService {

    private static final Logger log = Logger.getLogger(MyService.class); public void doSomething() { log.info("It works!"); } } example: logging import io.quarkus.logging.Log; Log
  55. @holly_cummins #RedHat package org.acme; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public

    class SpringDemo { public static void main(String[] args) { SpringApplication.run(SpringDemo.class, args); } } example: declaring an application
  56. @holly_cummins #RedHat @ApplicationScoped public class GreetingRepository { public Entity findByName(int

    name) { return find("name", name).firstResult(); } void persist(Entity entity) {} void delete(Entity entity) {} Entity findById(Id id) {} List<Entity> list(String query, Sort sort, Object... params) { return null; } Stream<Entity> stream(String query, Object... params) { return null; } long count() { return 0; } long count(String query, Object... params) { return 0; } } example: panache + hibernate
  57. @holly_cummins #RedHat example: panache + hibernate @ApplicationScoped public class GreetingRepository

    implements PanacheRepository<Greeting> { public Entity findByName(int name) { return find("name", name).firstResult(); } }
  58. @holly_cummins #RedHat DAO example: panache + hibernate @ApplicationScoped public class

    GreetingRepository implements PanacheRepository<Greeting> { public Entity findByName(int name) { return find("name", name).firstResult(); } } repository pattern
  59. @holly_cummins #RedHat example: panache + hibernate active record pattern @Entity

    public class Greeting extends PanacheEntity { public String name; public LocalDate issued; @Version public int version; public static List<Greeting> getTodaysGreetings() { return list("date", LocalDate.now()); } }
  60. @holly_cummins #RedHat int port = 8081; ClientInterceptor[] interceptors = new

    ClientInterceptor[3]; interceptors[0] = new EventLoopBlockingCheckInterceptor(); interceptors[1] = new IOThreadClientInterceptor(); interceptors[2] = new StorkMeasuringGrpcInterceptor(); // etc Channel channel = ManagedChannelBuilder .forAddress(“localhost", port) .usePlaintext() .build(); GreeterGrpc.GreeterStub greeter = GreeterGrpc .newStub(channel) .withInterceptors(interceptors); example: gRPC
  61. @holly_cummins #RedHat the old ways all still work but you

    don’t have to type all the stuff unless you want to ok but i still don’t like magic
  62. @holly_cummins #RedHat <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-spring-web</artifactId> </dependency> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-spring-data-jpa</artifactId> </dependency>

    ok but we use spring option 1: compatibility libraries option 2: migration tooling • migration toolkit for applications (mta) • windup • open rewrite
  63. @holly_cummins #RedHat “After a week of development with quarkus, I

    was able to regain the same level of productivity as when I was developing with Spring Boot.” – Fawaz Paraïso, Decathlon
  64. @holly_cummins #RedHat density Source: Clement Escoffier experiment 1: cloud Setup:

    • 800 requests/second, over 20 days • SLA > 99% • AWS instances Assumptions: • Costs are for us-east-1 data centre
  65. @holly_cummins #RedHat Setup: • 800 requests/second, over 20 days •

    SLA > 99% Assumptions: Source: Clement Escoffier x Teads cloud carbon impact of framework choice interpolated carbon metrics
  66. @holly_cummins #RedHat Setup: • 800 requests/second, over 20 days •

    SLA > 99% Assumptions: Source: Clement Escoffier x Teads cloud carbon impact of framework choice the carbon is lower because the cost is lower interpolated carbon metrics
  67. @holly_cummins #RedHat Setup: • REST + CRUD • large heap

    • RAPL energy measurement • multiple instances to support high load
 Assumptions: • US energy mix Source: John O’Hara experiment 2: RAPL measurements
  68. @holly_cummins #RedHat Setup: • REST + CRUD • large heap

    • RAPL energy measurement • multiple instances to support high load
 Assumptions: • US energy mix Source: John O’Hara experiment 2: RAPL measurements quarkus on JVM has the lowest carbon … because it has the highest throughput
  69. • quarkus cuts carbon by ~2-3x* • native consumes more

    carbon than JVM carbon measurements: conclusions
  70. @holly_cummins #RedHat Emiliia Nesterovych Emmanuel Bernard Emre Kaplan Enrique gonzález

    Martínez Enrique Mingorance Cano Eoin Gallinagh Eric Deandrea Eric Wittmann Erik Åsén Erik Mattheis Erin Schnabel Eugene Berman Evan Shortiss Fabricio Gregorio faculbsz Falko Modler Fedor Dudinskiy Felipe Carvalho dos Anjos Formentin Felipe Henrique Gross Windmoller Fernando Comunello Fernando Henrique fhavel Fikru Mengesha Filippe Spolti Florian Beutel Florian Bütler Florian Heubeck Florin Botis Foivos Zakkak Foobartender Fouad Almalki Francesco Nigro Francisco Javier Tirado Sarti Francois Steyn Frank Eichfelder franz1981 freakse-sa Fred Bricon Frédérc Blanc Freeman Fang Fu Cheng Gabriele Cardosi Galder Zamarreño galiacheng Gavin King Gavin Ray Geert Schuring Geoffrey De Smet Geoffrey GREBERT Georg Leber George Gastaldi manofthepeace Manyanda Chitimbo Marat Gubaidullin Marc Nuri Marc Schlegel Marc Wrobel Marcel Hanser Marcel Lohmann Marcell Cruz Marcelo Pereira Marcin Czeczko Marcin Kłopotek Marco Bungart Marco Schaub Marco Yeung Marco Zanghì Marcus Paulo Marek goldmann Marek Skacelik Marián Macik Mario Fusco MarioHNogueira Mark Lambert Mark Little Mark McLaughlin Mark Sailes marko-bekhta Markus Heberling Markus Himmel Markus Schwer Martin C. Richards Martin Grammelspacher Martin Kouba Martin Muzikar Martin Panzer Martin Weiler martin-kofoed-jyskebank-dk MartinWitt Marvin B. Lillehaug masini Matej Novotny Matej Vasek Matheus Cruz Mathias Holzer Matteo Mortari Matthias Andreas Benkard Matthias Cullmann mauroal Max Andersen Max Gabrielsson Max Rydahl Andersen Victor Hugo de Oliveira Molinar Vincent Sevel Vincent van Dam Vinícius Ferraz Campos Florentino Viswa Teja Nariboina Vladimir Konkov Vojtech Juranek Vratislav Hais w.glanzer Walter Medvedeo Wayne Ellis Werner Glanzer Willem Jan Glerum William Antônio Siqueira Wim goeman Wippermueller, Frank wojciech.stryjewski Xavier Xieshen xstefank Y. Luis Yann-Thomas LE MOIGNE Yannick Reifschneider YassinHajaj Yelzhas Suleimenov yesunch9 Yoann Rodière Yoshikazu Nojima Youngmin Koo Yubao Liu yugoccp Yukihiro Okada Zaheed Beita zanmagerl zedbeit Zheng Feng Žiga Deisinger Zineb Bendhiba zohar Zoran Regvart Шумов Игорь Юрьевич 出 门 三不惹 open source community of contributors
  71. @holly_cummins #RedHat tl;dpa (too long didn’t pay attention) deployment density

    lower cloud bill frictionless development experience Medium Nano auto-provision services zero-config live coding continuous testing developer UI greener
  72. @holly_cummins #RedHat tl;sdpa (too long still didn’t pay attention) what

    problems is quarkus solving? tea typing tedium taxes treasure