Grizzly 2.3+SPDY/3

We announced earlier in the week that we released Grizzly 2.3!  One of the major features of this release is the inclusion of SPDY/3 support.

SPDY is, per the following quote from Wikipedia:

The goal of SPDY is to reduce web page load time. This is achieved by prioritizing and multiplexing the transfer of web page subresources so that only one connection per client is required.

Another good quote:

SPDY does not replace HTTP; it modifies the way HTTP requests and responses are sent over the wire. This means that all existing server-side applications can be used without modification if a SPDY-compatible translation layer is put in place. When sent over SPDY, HTTP requests are processed, tokenized, simplified and compressed.

You can read all of the nitty-gritty details of SPDY here.

SPDY also typically is only used with transport layer security (TLS) using an extension called Next Protocol Negotiation (referred to as NPN).  In a nutshell, this allows application-level protocols to be negotiated during the SSL handshake for easy tunnelling.  See this RFC draft for more details on NPN.

In order for the Grizzly SPDY/3 implementation to function, you’ll need our SPDY and NPN runtimes.

The one gotcha right now with NPN and Java is that the SSL runtime does not natively support it.  So initially we decided on using Jetty’s NPN implementation. This worked fine with our initial implementation, however, due to potential red-tape issues, we decided to roll our own.  The end result, is fairly similar to Jetty’s due to how we bridged to their implementation.  As such we have similar restrictions.  As of this time, we only support SPDY/3 when using OpenJDK 7u14.  Versions later than this may or may not work as the SSL internals appear to change frequently as we’re replacing key SSL classes via the JVM bootclasspath mechanism.  If you do find a bug or an incompatibility with later versions of OpenJDK, please let us know and log an issue.

The maven coordinates for everything you need are:

So, how does one use SPDY with Grizzly 2.3 standalone?  It’s pretty simple to configure.

Before you actually start the server, the grizzly-npn-bootstrap.jar needs to be added to the JVM’s bootclasspath.  For example, if the JAR was in my home directory, then the bootclasspath would look something like:  -Xbootclasspath/p:/Users/catsnac/grizzly-npn-bootstrap-1.0.jar.

How do you know it’s working?  Well, there’s a couple possibilities.  Chrome, for example, has an extension that indicates whether or not the site you’re visiting is using SPDY or not.  A more primitive option, which I’ll be showing here, is using the -Djavax.net.debug=ssl:handshake JVM option on the server-side.

Simply start the standalone Grizzly/SPDY application with the aforementioned ssl debug option and connect using an SPDY-enabled browser.  Assuming the Grizzly NPN implementation is properly set in the bootclasspath, you should see:

It may be difficult to see, but if you search for “<===” in the content above, you can see where I’ve pointed out the specific NPN messages.

So, what about GlassFish?  We do have integration code for GlassFish 4(we recommend using the latest promoted builds). There are a few extra steps to getting it working in that environment.

Like the standalone example, you’ll need to add the same bootclasspath definition to the domain.xml.  You’ll also need to copy the grizzly-npn-osgi-1.0.jar and grizzly-spdy-2.3.jar to $GF_HOME/modules.  The grizzly-spdy module includes a command to enable spdy.  So once the jars are in place, the bootclasspath updated, you can run the enable-spdy command against the secure HTTP listener.  Assuming you’re doing this against the default configuration, this would be http-listener-2:  asadmin enable-spdy http-listener-2.

Once the above is done, you can ensure it’s working in the same way as was previously described.

What about tuning?  At this point in time we offer the following configuration options.  These can be set either via the SpdyAddon (Grizzly standalone) or using asadmin set.

maxConcurrentStreams Configures how many streams may be multiplexed over a single connection. The default is 100.
initialWindowSizeInBytes Configures how much memory each stream will consume on the server side. The default is 64KB.
maxFrameLength Configures the upper bound on allowable frame sizes. Frames above this bound will be rejected.  The default is 2^24 bytes in length – the max allowed by the spec.

Lastly, there are some limitations that should be spelled out.  Please see our documentation for details.  We’d like to encourage you give it a shot and log any problems or features you like to see resolved/implemented.

Enjoy!

 

This entry was posted in Java and tagged , . Bookmark the permalink.

Comments are closed.