Sammenligning av innebygde servletbeholdere i vårstøvel

1. Introduksjon

Den økende populariteten til cloud-native applikasjoner og mikrotjenester genererer en økt etterspørsel etter innebygde servletcontainere. Spring Boot lar utviklere enkelt bygge applikasjoner eller tjenester ved hjelp av de 3 mest modne containerne som er tilgjengelige: Tomcat, Undertow og Jetty.

I denne opplæringen vil vi demonstrere en måte å raskt sammenligne containerimplementeringer ved hjelp av beregninger oppnådd ved oppstart og under litt belastning.

2. Avhengigheter

Vårt oppsett for hver tilgjengelige containerimplementering vil alltid kreve at vi erklærer en avhengighet av spring-boot-starter-web i vår pom.xml.

Generelt vil vi spesifisere foreldrene våre som spring-boot-starter-parent, og inkluder deretter forretterne vi ønsker:

 org.springframework.boot spring-boot-starter-parent 2.2.2.RELEASE org.springframework.boot spring-boot-starter org.springframework.boot spring-boot-starter-web 

2.1. Tomcat

Ingen ytterligere avhengigheter er nødvendig når du bruker Tomcat fordi den er inkludert som standard når du bruker spring-boot-starter-web.

2.2. Brygge

For å kunne bruke brygge, må vi først ekskludere spring-boot-starter-tomcat fra spring-boot-starter-web.

Så erklærer vi ganske enkelt en avhengighet av vår-støvel-start-brygge:

 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-tomcat org.springframework.boot spring-boot-starter-jetty 

2.3. Undertow

Å sette opp for Undertow er identisk med brygge, bortsett fra at vi bruker spring-boot-starter-undertow som vår avhengighet:

 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-tomcat org.springframework.boot spring-boot-starter-undertow 

2.4. Aktuator

Vi bruker Spring Boot's Actuator som en praktisk måte å både stresse systemet og spørre etter beregninger.

Sjekk ut denne artikkelen for detaljer om aktuator. Vi legger ganske enkelt til en avhengighet i vår pom for å gjøre den tilgjengelig:

 org.springframework.boot spring-boot-starter-actuator 

2.5. Apache Bench

Apache Bench er et verktøy for åpen testing av belastningstesting som følger med Apache-webserveren.

Windows-brukere kan laste ned Apache fra en av tredjepartsleverandørene som er koblet her. Hvis Apache allerede er installert på Windows-maskinen din, bør du kunne finne den ab.exe i din apache / søppel katalog.

Hvis du bruker en Linux-maskin, ab kan installeres ved hjelp av apt-get med:

$ apt-get installer apache2-utils

3. Oppstartsmålinger

3.1. Samling

For å samle oppstartmålingene våre registrerer vi en hendelsesbehandler for å skyte på Spring Boot's ApplicationReadyEvent.

Vi trekker programmatisk ut beregningene vi er interessert i, ved å jobbe direkte med MeterRegistry brukt av aktuatorkomponenten:

@Komponent offentlig klasse StartupEventHandler {// logger, konstruktør privat streng [] METRICS = {"jvm.memory.used", "jvm.classes.loaded", "jvm.threads.live"}; privat streng METRIC_MSG_FORMAT = "Oppstartsmåling >> {} = {}"; private MeterRegistry meterRegistry; @EventListener public void getAndLogStartupMetrics (ApplicationReadyEvent event) {Arrays.asList (METRICS) .forEach (this :: getAndLogActuatorMetric); } privat ugyldig prosessMetrik (strengmåling) {Meter meter = meterRegistry.find (metric) .meter (); Kartstatistikk = getSamples (meter); logger.info (METRIC_MSG_FORMAT, metrisk, stats.get (Statistic.VALUE) .longValue ()); } // andre metoder}

Vi unngår behovet for å spørre REST-sluttpunkter manuelt, eller å kjøre en frittstående JMX-konsoll ved å logge interessante beregninger ved oppstart i hendelsesbehandleren.

3.2. Utvalg

Det er et stort antall beregninger som aktuator gir ut av boksen. Vi valgte 3 beregninger som hjelper deg med å få et høyt nivå oversikt over viktige kjøretidskarakteristikker når serveren er oppe:

  • jvm.memory.used - det totale minnet som JVM har brukt siden oppstart
  • jvm.classes.loaded - totalt antall lastede klasser
  • jvm.threads.live - det totale antallet aktive tråder. I vår test kan denne verdien sees på som tråden "i ro"

4. Runtime Metrics

4.1. Samling

I tillegg til å gi oppstartsmålinger, bruker vi / beregninger endepunkt eksponert av aktuatoren som mål-URL når vi kjører Apache Bench for å legge applikasjonen under belastning.

For å teste et reelt program under belastning, kan vi i stedet bruke sluttpunkter levert av applikasjonen vår.

Når serveren har startet, får vi en ledetekst og utfører ab:

ab -n 10000 -c 10 // localhost: 8080 / aktuator / metrics

I kommandoen ovenfor har vi spesifisert totalt 10.000 forespørsler ved hjelp av 10 samtidige tråder.

4.2. Utvalg

Apache Bench kan veldig raskt gi oss nyttig informasjon, inkludert tilkoblingstider og prosentandelen av forespørsler som blir servert innen en viss tid.

For våre formål, vi fokuserte på forespørsler per sekund og tid per forespørsel (gjennomsnitt).

5. Resultater

Ved oppstart fant vi det minnefotavtrykket til Tomcat, Jetty og Undertow var sammenlignbart med Undertow som krever litt mer minne enn de to andre og Jetty krever det minste beløpet.

For vår referanse, fant vi det forestillingen til Tomcat, Jetty og Undertow var sammenlignbar men det Undertow var helt klart den raskeste og Jetty bare litt mindre rask.

MetriskTomcatBryggeUndertow
jvm.memory.used (MB)168155164
jvm.classes.loaded986997849787
jvm.threads.live251719
Forespørsler per sekund154216271650
Gjennomsnittlig tid per forespørsel (ms)6.4836.1486.059

Vær oppmerksom på at beregningene, naturlig nok, er representative for bare-bein-prosjektet; Beregningene for din egen applikasjon vil helt sikkert være forskjellige.

6. Referansediskusjon

Å utvikle egnede referansetester for å utføre grundige sammenligninger av serverimplementeringer kan bli komplisert. For å hente ut den mest relevante informasjonen, det er viktig å ha en klar forståelse av hva som er viktig for den aktuelle brukssaken.

Det er viktig å merke seg at referansemålingene samlet i dette eksemplet ble tatt med en veldig spesifikk arbeidsmengde bestående av HTTP GET-forespørsler til et aktuatorendepunkt.

Det forventes at forskjellige arbeidsbelastninger sannsynligvis vil resultere i forskjellige relative målinger på tvers av containerimplementeringer. Hvis det kreves mer robuste eller presise målinger, vil det være en veldig god idé å sette opp en testplan som passer bedre sammen med produksjonsbruken.

I tillegg vil en mer sofistikert benchmarking-løsning som JMeter eller Gatling trolig gi mer verdifull innsikt.

7. Velge en beholder

Å velge riktig containerimplementering bør sannsynligvis være basert på mange faktorer som ikke kan oppsummeres pent med en håndfull beregninger alene. Komfortnivå, funksjoner, tilgjengelige konfigurasjonsalternativer og policy er ofte like viktige, om ikke mer.

8. Konklusjon

I denne artikkelen så vi på Tomcat, Jetty og Undertow innebygde implementeringer av servletcontainere. Vi undersøkte kjøretidskarakteristikkene til hver container ved oppstart med standardkonfigurasjonene ved å se på beregninger eksponert av aktuatorkomponenten.

Vi utførte en konstruert arbeidsmengde mot det kjørende systemet og målte deretter ytelsen ved hjelp av Apache Bench.

Til slutt diskuterte vi fordelene ved denne strategien og nevnte noen få ting å huske på når vi sammenligner implementerings benchmarks. Som alltid kan all kildekode bli funnet på GitHub.


$config[zx-auto] not found$config[zx-overlay] not found