HTTP / 2 di Jeti

1. Gambaran keseluruhan

Protokol HTTP / 2 dilengkapi dengan fitur push yang membolehkan pelayan menghantar banyak sumber kepada klien untuk satu permintaan . Oleh itu, ia meningkatkan masa memuatkan halaman dengan mengurangkan banyak perjalanan pergi balik yang diperlukan untuk mendapatkan semua sumber.

Jetty menyokong protokol HTTP / 2 untuk pelaksanaan pelanggan dan pelayan.

Dalam tutorial ini, kita akan meneroka sokongan HTTP / 2 di Jetty dan membuat aplikasi web Java untuk memeriksa fitur HTTP / 2 Push.

2. Bermula

2.1. Memuat turun Jeti

Jeti memerlukan sokongan JDK 8 atau lebih baru dan sokongan ALPN (Application-Layer Protocol Negotiation) untuk menjalankan HTTP / 2.

Biasanya, pelayan Jetty disebarkan melalui SSL dan membolehkan protokol HTTP / 2 melalui sambungan TLS (ALPN) .

Pertama, kita perlu memuat turun edaran Jeti terkini dan menetapkan pemboleh ubah JETTY_HOME .

2.2. Mengaktifkan Penyambung HTTP / 2

Seterusnya, kita dapat menggunakan perintah Java untuk mengaktifkan penyambung HTTP / 2 pada pelayan Jetty:

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

Perintah ini menambahkan sokongan protokol HTTP / 2 ke penyambung SSL pada port 8443 . Juga, secara sementara membolehkan modul ALPN untuk perundingan protokol:

INFO : server transitively enabled, ini template available with --add-to-start=server INFO : alpn-impl/alpn-1.8.0_131 dynamic dependency of alpn-impl/alpn-8 INFO : alpn-impl transitively enabled INFO : alpn transitively enabled, ini template available with --add-to-start=alpn INFO : alpn-impl/alpn-8 dynamic dependency of alpn-impl INFO : http2 initialized in ${jetty.base}/start.ini INFO : ssl transitively enabled, ini template available with --add-to-start=ssl INFO : threadpool transitively enabled, ini template available with --add-to-start=threadpool INFO : bytebufferpool transitively enabled, ini template available with --add-to-start=bytebufferpool INFO : Base directory was modified

Di sini, log menunjukkan maklumat modul seperti ssl dan alpn-impl / alpn-8 yang diaktifkan secara sementara untuk penyambung HTTP / 2.

2.3. Memulakan Pelayan Jetty

Sekarang, kami bersedia untuk memulakan pelayan Jetty:

java -jar $JETTY_HOME/start.jar

Apabila pelayan bermula, pembalakan akan menunjukkan modul yang diaktifkan:

INFO::main: Logging initialized @228ms to 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. Mengaktifkan Modul Tambahan

Begitu juga, kita boleh mengaktifkan modul lain seperti http dan http2c :

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

Mari sahkan log:

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

Kami juga boleh menyenaraikan semua modul yang disediakan oleh Jetty:

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

Hasilnya akan kelihatan seperti:

Available Modules: ================== tags: [-internal] Modules for tag '*': -------------------- Module: alpn : Enables the ALPN (Application Layer Protocol Negotiation) TLS extension. Depend: ssl, alpn-impl LIB: lib/jetty-alpn-client-${jetty.version}.jar LIB: lib/jetty-alpn-server-${jetty.version}.jar XML: etc/jetty-alpn.xml Enabled: transitive provider of alpn for http2 // ... Modules for tag 'connector': ---------------------------- Module: http2 : Enables HTTP2 protocol support on the TLS(SSL) Connector, : using the ALPN extension to select which protocol to use. Tags: connector, http2, http, ssl Depend: ssl, alpn LIB: lib/http2/*.jar XML: etc/jetty-http2.xml Enabled: ${jetty.base}/start.ini // ... Enabled Modules: ================ 0) alpn-impl/alpn-8 dynamic dependency of alpn-impl 1) http2 ${jetty.base}/start.ini // ...

2.5. Konfigurasi Tambahan

Sama seperti argumen –list-modul , kita dapat menggunakan –list-config untuk menyenaraikan semua fail konfigurasi XML untuk setiap modul:

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

Untuk mengkonfigurasi sifat umum seperti host dan port untuk pelayan Jetty, kita dapat membuat perubahan pada fail start.ini :

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

Juga, terdapat beberapa http2 sifat seperti maxConcurrentStreams dan maxSettingsKeys yang kita boleh menyelaraskan:

jetty.http2.maxConcurrentStreams=128 jetty.http2.initialStreamRecvWindow=524288 jetty.http2.initialSessionRecvWindow=1048576 jetty.http2.maxSettingsKeys=64 jetty.http2.rateControl.maxEventsPerSecond=20

3. Menyiapkan Aplikasi Pelayan Jetty

3.1. Konfigurasi Maven

Sekarang setelah kita membuat konfigurasi Jetty, inilah masanya untuk membuat aplikasi kita.

Mari tambahkan plugin jetty-maven-plugin Maven ke pom.xml kami bersama dengan pergantungan Maven seperti pelayan http2 , pelayan jetty-alpn-openjdk8 , dan jetty-servlets :

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

Kemudian, kami akan menyusun kelas menggunakan arahan Maven:

mvn clean package

Dan terakhir, kita dapat menyebarkan aplikasi Maven yang belum dipasang ke pelayan Jetty:

mvn jetty:run-forked

Secara lalai, pelayan bermula pada port 8080 dengan protokol HTTP / 1.1:

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. Konfigurasikan HTTP / 2 di jetty.xml

Seterusnya, kami akan mengkonfigurasi pelayan Jetty dengan protokol HTTP / 2 dalam fail jetty.xml kami dengan menambahkan elemen Panggilan yang sesuai :

 alpn h2 8444 

Here, the HTTP/2 connector is configured with ALPN on port 8444 along with sslContextFactory and httpConfig configs.

Also, we can add other modules like h2-17 and h2-16 (draft versions of h2) by defining comma-separated arguments in jetty.xml:

 h2,h2-17,h2-16 

Then, we'll configure the location of the jetty.xml in our pom.xml:

 org.eclipse.jetty jetty-maven-plugin 9.4.27.v20200227 8888 quit -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 / ... 

Note: To enable HTTP/2 in our Java 8 app, we've added the alpn-boot jar to the JVM BootClasspath. However, ALPN support is already available in Java 9 or later.

Let's re-compile our classes and re-run the application to verify if the HTTP/2 protocol is enabled:

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}

Here, we can observe that port 8443 is configured with the HTTP/1.1 protocol and 8444 with HTTP/2.

3.3. Configure the PushCacheFilter

Next, we need a filter that pushes the secondary resources like images, JavaScript, and CSS to the client.

To do so, we can use the PushCacheFilter class available in the org.eclipse.jetty.servlets package. PushCacheFilter builds a cache of secondary resources associated with a primary resource like index.html and pushes them to the client.

Let's configure the PushCacheFilter in our web.xml:

 push org.eclipse.jetty.servlets.PushCacheFilter ports 8444 push /* 

3.4. Configure Jetty Servlet and Servlet Mapping

Then, we'll create the Http2JettyServlet class to access the images, and we'll add the servlet-mapping in our web.xml file:

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

4. Setting up the HTTP/2 Client

Finally, to verify the HTTP/2 Push feature and the improved page-load time, we'll create an http2.html file that loads a few images (secondary resources):

 Baeldung HTTP/2 Client in Jetty 

HTTP/2 Demo

5. Testing the HTTP/2 Client

To get a baseline for the page-load time, let's access the HTTP/1.1 application at //localhost:8443/http2.html with the Developer Tools to verify the protocol and load time:

Here, we can observe that the images are loaded in 3-6ms using the HTTP/1.1 protocol.

Then, we'll access the HTTP/2 application, which has Push enabled, at //localhost:8444/http2.html:

Here, we observe that the protocol is h2, the initiator is Push, and the loading time is 1ms for all the images (secondary resources).

Therefore, the PushCacheFilter caches the secondary resources for http2.html, pushes them on port 8444, and provides a great improvement in the load time of the page.

6. Conclusion

In this tutorial, we've explored HTTP/2 in Jetty.

First, we examined how to start Jetty with the HTTP/2 protocol along with its configurations.

Then, we've seen a Java 8 web application with the HTTP/2 Push feature, configured with a PushCacheFilter, and observed how the load time of a page containing secondary resources improved over what we saw with the HTTP/1.1 protocol.

As usual, all the code implementations are available over on GitHub.