HTTP / 2 in Jetty

1. Overzicht

Het HTTP / 2-protocol wordt geleverd met een push-functie waarmee de server meerdere bronnen naar de client kan sturen voor één verzoek. Daarom verbetert het de laadtijd van de pagina door het aantal rondreizen dat nodig is om alle bronnen op te halen, te verminderen.

Jetty ondersteunt het HTTP / 2-protocol voor zowel client- als serverimplementaties.

In deze zelfstudie verkennen we HTTP / 2-ondersteuning in Jetty en maken we een Java-webtoepassing om de HTTP / 2 Push-functie te onderzoeken.

2. Aan de slag

2.1. Jetty downloaden

Jetty vereist JDK 8 of hoger en ALPN-ondersteuning (Application-Layer Protocol Negotiation) voor het uitvoeren van HTTP / 2.

Typisch, de Jetty-server wordt geïmplementeerd via SSL en maakt het HTTP / 2-protocol mogelijk via de TLS-extensie (ALPN).

Eerst moeten we de nieuwste Jetty-distributie downloaden en het JETTY_HOME variabele.

2.2. De HTTP / 2-connector inschakelen

Vervolgens kunnen we een Java-commando gebruiken om de HTTP / 2-connector op de Jetty-server in te schakelen:

java -jar $ JETTY_HOME / start.jar --add-to-start = http2

Met deze opdracht wordt HTTP / 2-protocolondersteuning toegevoegd aan de SSL-connector op de poort 8443. Het maakt ook transitief de ALPN-module mogelijk voor protocolonderhandeling:

INFO: server transitief ingeschakeld, ini-sjabloon beschikbaar met --add-to-start = server INFO: alpn-impl / alpn-1.8.0_131 dynamische afhankelijkheid van alpn-impl / alpn-8 INFO: alpn-impl transitief ingeschakeld INFO: alpn transitief ingeschakeld, ini-sjabloon beschikbaar met --add-to-start = alpn INFO: alpn-impl / alpn-8 dynamische afhankelijkheid van alpn-impl INFO: http2 geïnitialiseerd in $ {jetty.base} /start.ini INFO: ssl transitief ingeschakeld, ini-sjabloon beschikbaar met --add-to-start = ssl INFO: threadpool transitief ingeschakeld, ini-sjabloon beschikbaar met --add-to-start = threadpool INFO: bytebufferpool transitief ingeschakeld, ini-sjabloon beschikbaar met --add-to- start = bytebufferpool INFO: Basismap is gewijzigd

Hier tonen de logboeken de informatie van modules zoals ssl en alpn-impl / alpn-8 die tijdelijk zijn ingeschakeld voor de HTTP / 2-connector.

2.3. De steigerserver starten

Nu zijn we klaar om de Jetty-server te starten:

java -jar $ JETTY_HOME / start.jar

Wanneer de server start, toont de logboekregistratie de modules die zijn ingeschakeld:

INFO :: main: Logging geïnitialiseerd @ 228ms naar org.eclipse.jetty.util.log.StdErrLog ... INFO: oejs.AbstractConnector: main: Started [email protected] {SSL, (ssl, alpn, h2)} {0.0 .0.0: 8443} INFO: oejs.Server: main: Started @ 872ms

2.4. Aanvullende modules inschakelen

Evenzo kunnen we andere modules inschakelen, zoals http en http2c:

java -jar $ JETTY_HOME / start.jar --add-to-start = http, http2c

Laten we de logboeken verifiëren:

INFO: oejs.AbstractConnector: main: Started [email protected] {SSL, (ssl, alpn, h2)} {0.0.0.0:8443} INFO: oejs.AbstractConnector: main: Started [email protected] {HTTP / 1.1, ( http / 1.1, h2c)} {0.0.0.0:8080} INFO: oejs.Server: main: Started @ 685ms

We kunnen ook alle modules opsommen die door Jetty worden aangeboden:

java -jar $ JETTY_HOME / start.jar --list-modules

De uitvoer ziet er als volgt uit:

Beschikbare modules: ================== tags: [-internal] Modules voor tag '*': ---------------- ---- Module: alpn: schakelt de ALPN (Application Layer Protocol Negotiation) TLS-extensie in. Afhankelijk: ssl, alpn-impl LIB: lib / jetty-alpn-client - $ {jetty.version} .jar LIB: lib / jetty-alpn-server - $ {jetty.version} .jar XML: etc / jetty-alpn .xml ingeschakeld: transitieve provider van alpn voor http2 // ... Modules voor tag 'connector': ---------------------------- Module: http2: Schakelt HTTP2-protocolondersteuning in op de TLS (SSL) Connector,: gebruikt de ALPN-extensie om te selecteren welk protocol moet worden gebruikt. Tags: connector, http2, http, ssl Depend: ssl, alpn LIB: lib / http2 / *. Jar XML: etc / jetty-http2.xml Ingeschakeld: $ {jetty.base} /start.ini // ... Ingeschakeld Modules: ================ 0) alpn-impl / alpn-8 dynamische afhankelijkheid van alpn-impl 1) http2 $ {jetty.base} /start.ini // .. .

2.5. Aanvullende configuratie

Net als bij de –Lijst-modules argument kunnen we gebruiken –List-config om alle XML-configuratiebestanden voor elke module weer te geven:

java -jar $ JETTY_HOME / start.jar --list-config

Om de algemene eigenschappen zoals gastheer en haven voor de Jetty-server kunnen we wijzigingen aanbrengen in het start.ini het dossier:

jetty.ssl.host = 0.0.0.0 jetty.ssl.port = 8443 jetty.ssl.idleTimeout = 30000

Er zijn er ook een paar http2 eigenschappen zoals maxConcurrentStreams en maxSettingsKeys die we kunnen configureren:

steiger.http2.maxConcurrentStreams = 128 steiger.http2.initialStreamRecvWindow = 524288 steiger.http2.initialSessionRecvWindow = 1048576 steiger.http2.maxSettingsKeys = 64 steiger.http2.rate = 20Pontroler.maxSettingsKeys = 64 steiger.http2.rate = 20Pontroler.maxSettingsKeys = 64 steiger.

3. Het opzetten van een Jetty Server-applicatie

3.1. Maven-configuratie

Nu we Jetty hebben geconfigureerd, is het tijd om onze applicatie te maken.

Laten we de steiger-maven-plugin Maven-plug-in naar onze pom.xml samen met Maven-afhankelijkheden zoals http2-server, steiger-alpn-openjdk8-server, en steiger-servlets:

   org.eclipse.jetty steiger-maven-plugin 9.4.27.v20200227 org.eclipse.jetty.http2 http2-server 9.4.27.v20200227 org.eclipse.jetty steiger-alpn-openjdk8-server 9.4.27.v20200227 org.eclipse . steiger-servlets 9.4.27.v20200227 

Vervolgens compileren we de klassen met behulp van het Maven-commando:

mvn schoon pakket

En als laatste kunnen we onze niet-gemonteerde Maven-app op de Jetty-server implementeren:

mvn-steiger: run-forked

Standaard start de server op poort 8080 met het HTTP / 1.1-protocol:

oejmp.Starter: main: Started Jetty Server oejs.AbstractConnector: main: Started [email protected] {HTTP / 1.1, (http / 1.1)} {0.0.0.0:8080} oejs.Server: main: Started @ 1045ms

3.2. Configureer HTTP / 2 in jetty.xml

Vervolgens configureren we de Jetty-server met het HTTP / 2-protocol in onze jetty.xml bestand door het juiste Bel element:

             alpn h2 8444 

Hier is de HTTP / 2-connector geconfigureerd met ALPN op poort 8444 samen met sslContextFactory en httpconfiguratie configs.

We kunnen ook andere modules toevoegen, zoals h2-17 en h2-16 (conceptversies van h2) door door komma's gescheiden argumenten te definiëren in jetty.xml:

  h2, h2-17, h2-16 

Vervolgens configureren we de locatie van het jetty.xml in onze pom.xml:

 org.eclipse.jetty jetty-maven-plugin 9.4.27.v20200227 8888 stop -Xbootclasspath / p: $ {settings.localRepository} /org/mortbay/jetty/alpn/alpn-boot/8.1.11.v20170118/alpn-boot -8.1.11.v20170118.jar $ {basedir} /src/main/config/jetty.xml / ... 

Opmerking: om HTTP / 2 in onze Java 8-app in te schakelen, we hebben de alpn-laarzenpot naar het JVM BootClasspath. Echter, ALPN-ondersteuning is al beschikbaar in Java 9 of hoger.

Laten we onze klassen opnieuw compileren en de applicatie opnieuw starten om te controleren of het HTTP / 2-protocol is ingeschakeld:

oejmp.Starter: main: Started Jetty Server oejs.AbstractConnector: main: Started [email protected] {SSL, (ssl, http / 1.1)} {0.0.0.0:8443} oejs.AbstractConnector: main: Started [email protected] { SSL, (ssl, alpn, h2)} {0.0.0.0:8444}

Hier kunnen we die poort observeren 8443 is geconfigureerd met het HTTP / 1.1-protocol en 8444 met HTTP / 2.

3.3. Configureer het PushCacheFilter

Vervolgens hebben we een filter nodig dat de secundaire bronnen zoals afbeeldingen, JavaScript en CSS naar de client pusht.

Om dit te doen, kunnen we de PushCacheFilter klasse beschikbaar in de org.eclipse.jetty.servlets pakket. PushCacheFilter bouwt een cache met secundaire bronnen die zijn gekoppeld aan een primaire bron, zoals index.html en duwt ze naar de klant.

Laten we het PushCacheFilter in onze web.xml:

 push org.eclipse.jetty.servlets.PushCacheFilter-poorten 8444 push / * 

3.4. Configureer Jetty Servlet en Servlet Mapping

Vervolgens maken we het Http2JettyServlet klasse om toegang te krijgen tot de afbeeldingen, en we zullen de servlet-mapping in onze web.xml het dossier:

 http2Jetty com.baeldung.jetty.http2.Http2JettyServlet http2Jetty / images / * 

4. Instellen van de HTTP / 2-client

Ten slotte, om de HTTP / 2 Push-functie en de verbeterde laadtijd van de pagina te verifiëren, maken we een http2.html bestand dat een paar afbeeldingen laadt (secundaire bronnen):

   Baeldung HTTP / 2-client in Jetty 

HTTP / 2-demo

5. Testen van de HTTP / 2-client

Om een ​​basislijn te krijgen voor de laadtijd van de pagina, gaan we naar de HTTP / 1.1-applicatie op //localhost:8443/http2.html met de Developer Tools om het protocol en de laadtijd te verifiëren:

Hier kunnen we zien dat de afbeeldingen in 3-6 ms worden geladen met behulp van het HTTP / 1.1-protocol.

Vervolgens openen we de HTTP / 2-applicatie, waarvoor Push is ingeschakeld, op //localhost:8444/http2.html:

Hier zien we dat het protocol is h2, de initiatiefnemer is Duwen, en de laadtijd is 1 ms voor alle afbeeldingen (secundaire bronnen).

Daarom, de PushCacheFilter cachet de secundaire bronnen voor http2.html, duwt ze op bakboord 8444, en zorgt voor een grote verbetering in de laadtijd van de pagina.

6. Conclusie

In deze tutorial hebben we HTTP / 2 in Jetty onderzocht.

Eerst hebben we onderzocht hoe Jetty kan worden gestart met het HTTP / 2-protocol en de bijbehorende configuraties.

Vervolgens hebben we een Java 8-webtoepassing gezien met de HTTP / 2 Push-functie, geconfigureerd met een PushCacheFilter, en zagen hoe de laadtijd van een pagina met secundaire bronnen verbeterde ten opzichte van wat we zagen met het HTTP / 1.1-protocol.

Zoals gewoonlijk zijn alle code-implementaties beschikbaar op GitHub.