Helospark is now on h2

Finally helospark.com is also available via HTTP/2.0.
The Java world was in a bit of a lag to support h2 but the (beta) support has arrived with Java 9 and Tomcat 9.

Introduction

HTTP/2.0 (or as the cool kids are calling it h2) is a new protocol in town which is in the process of replacing the ubiquitous HTTP/1.1.
HTTP1.1 is an old protocoll (really old) it's RFC is from 1999, the internet was a really different place back than, most sites were small, usually with a only a couple of resources assiciated with each page, Google was just in Beta mode, Facebook was still not even imagined.

Google in 1999
Google in 1999


in short there has been a lot of change since than, and while HTTP/1.1 is still usable, in today's web it proved to be slow.

HTTP/2.0 brings many things to the table that could make the browsing a faster experience, main features:

  •   - Binary easily parsable protocol
  •   - True multiplexed TCP connection (with streams)
  •   - Header/cookie compression
  •   - Server pushing

These features make unnecessary (and mostly even detremental) many of the workarounds that HTTP1.1 required, like

  •   - Image tiling
  •   - Concatenating resources (like CSS and JS)
  •   - Domain sharding

H2 has a variant called h2c that can use clear text, but it is not supported by browsers, really the only reasonably way to go to HTTP2 is to use h2 (HTTP2 over TLS), this encrypt comminucation and using ALPN protocol to do the negotiation between HTTP1.1 and HTTP2.
Simply by just going h2 the speed of an avarage website will increase, and it can be increased more by also introducing server push.


HTTP/2.0 in Java

Java is known for the delays it takes to adopt to new protocols and features, Java prides on stability, let others do the experimenting and only once it looks advantagous will it go ahead and implement. This is both a good and a bad thing, good because it's mostly stable and does not have too much (compared to it's age) deprecated and dead code. Bad because we have to wait a long time for cool new features (like ALPN that was needed for h2). 
Several new technologies had to be released (really they are in beta at the moment) for this site to be moved to h2 at this time.

Java 9


Java 9 provides a lot of awesome new features, but the one I needed was the ALPN implementation that support h2.
There has been a couple of challanges with Java 9 early access release, while it is already feature complete, the support from different libraries are not great, even though I have raised almost all of my dependency's version to the latest (and many times beta).
Several libraries are using internal Java APIs whose access has been prohibited by the Jigsaw in Java 9.
Until the developers update their implementation the best option was to just use --permit-illegal-access in my JAVA_OPTS to basically turn off Jigsaw.


The other problem was the format of `java.version` has been changed as part of JEP223 in the most recent Java version, previously the format looked like the following: 1.8_123, while in Java 9 it was changed to simple 9 for final, and 9-ea for early access version. This broke two libraries I have used transitively in this website who tried to parse it as subtringing the first three characters (which are no longer the format they expected it).

Tomcat 9


Tomcat 9 is also the first Tomcat who has h2 support (though later it was backported to 8.5 as well). At the moment it is still not the final release only a milestone, but it seems stable enough for me to release my website to it.
At first glance the update was pretty smooth, I just downloaded it, copied over my settings and HTTP2 support was already there. After a bit of an investigation though it turned out that now my website is available ONLY through h2, no longer via HTTP1.1 which said that the ALPN protocol negotiation failed. I think this is not supposed to happen, after playing with the settings it turned out that the only way I can support both is to use Tomcat's native (APR) connector.
Simply building the connection (./configure; make; make install) and setting the installation path to java.library.path solved the issue (and I wanted to do it anyway for performance reason). Still it was a lot of painful debugging, I think the regular NIO connection should have worked fine for both HTTP1.1 and HTTP2.


Another thing that needed changing was that without the <Certificate..> tag in the UpgradeProtocol (only in the main definition) it throwed NullPointerException. While this NPE did not seem to have any effect on the page rendering, it cluttered up the logs, so I had to create a Certificate tag.
Anyway I will wait further for the stable version (and the rest of the crowd).

Ways to go


One important aspect is still missing from the migration, namely the HTTP2 Server Push feature. Unfortunatelly I have not found any out of box solution for Tomcat (only Jetty's PushCacheFilter), so I have started to work on a similar project in my GitHub repository:
https://github.com/helospark/learning-http2-push-filter
While it kinda works, it is not yet production ready, there are slight issues and missing features at the time of this writing (hopefully that soon changes).

Article was created by helospark (2017-05-01 17:39:19)
Rate article: 0
Ask questions or share your opinion.
You need to login to comment.