Sunday, January 3, 2016

What are SPDY and HTTP/2 and How to Enable Them on Nginx

One of the core technologies powering the web is HTTP. Unfortunately HTTP/1.1 was designed for static HTML sites and was last updated around 1999. The web today has changed quit a lot. Websites are more and more dynamic, contains quit a lot of resources. In this tutorial I will explain waht are SPDY and HTTP/2 and how to enable them on Nginx and also how to test them.


SPDY


In 2009 Google introduced a new protocol called SPDY (pronounced speedy). SPDY offers three key improvments over HTTP/1.1.


1. Header Compression


Every HTTP request and response include a sizeable amount of data in the header. HTTP/1.1 can only compress the content and can not compress the header. SPDY signicantly shrink the header size. In the future SPDY will support sending header once for an entire connection instead of sending them for every repetitive single connection.


2. Parallel Requests


HTTP is a message-based protocol. Once you have established a TCP connection and you send an HTTP request you have to site there and wait for response to arrive before you can send the next request. Each such request requires at least one round trip between the browser and the server which can take hundreds of milliseconds. This is a significant delay.


If one of the responses was slow, it will delay all the other requests. This is called head-of-line blocking. In HTTP, the relationship between the request message and the response message is implicit. The server does not explicitly say I’m the response to that request. You can only identify it’s the response the that request becuase the response follows that request in order.


SPDY offers true multiplexing. With SPDY you can send as many requests as you like at a single connection and get the responses in whatever order. So browsers don’t have to open multiple connections per hostname. SPDY enables them to open one connection per hostname. This will also reduce the load on the server becuase less connections means less sockets are open on the server.


3. Server Push and Server Hint


In HTTP, all communications between the browser and server is initiated by the browser. If the server has something to say, it actually has to wait for the browser to ask for the information. When the browser request HTML, the server knows the browser needs the associated css, javascript or image which needs to be fetched by browser in order to fully render the page. But in HTTP the server has to wait for the browser to request those css, javascript and image.


With SPDY, the server is able to proactively push data without the browser requesting it.


In some cases, server push may be wasteful. For instance maybe the browser already had the css file in its cache and woudn’t download it again. SPDY had a lite version of server push called server hint which means the server only offers suggestions to the browser but the request is still made by the client.


The following techniques are no longer needed with SPDY.


  • CSS Sprite

  • Inline Image

  • Sharding to improve parallel requests.

  • CSS/Javascript Concatenation

Limitations


SPDY is great but it still has some limitations.


  1. The first is that it limits to HTTPS.

  2. SPDY communicates separately with each host. The browse may have to communicates with multiple hosts in order to fully render a webpage. Even if all of them support SPDY, the browser still have to open one connection per host. Multiplexing can only occure on a per host basis.

How to Enable SPDY On Nginx


As said before, you need to enable HTTPS in order to use SPDY. Fortunately now you can easily get a free SSL/TLS certificate from Let’s Encrypt. If you have not yet enabled HTTPS, please use the following link to get a free SSL/TLS certificate.


An oveview of HTTPS encryption and Let’s Encrypt SSL/TLS certificate delopyment with Nginx


If you have enabled HTTPS, check if Nginx is compiled with SPDY module


sudo nginx -V

If you see the following text, then SPDY module is included in your Nginx installation.


--with-http_spdy_module

Configure server block file


sudo vi /etc/nginx/conf.d/yourdomain.conf

or


sudo vi /etc/nginx/sites-available/yourdomain.conf

In the server section, add spdy after listen 443 ssl.


server {
listen 443 ssl spdy;
server_name www.linuxbabe.com;

ssl_certificate /etc/ssl/fullchain.pem;
ssl_certificate_key /etc/ssl/privkey.pem;

......

Then save and close the file. Reload Nginx configuration.


sudo service nginx reload

or


sudo systemctl reload nginx

And you are done. Very easy!


As of Nginx 1.9.5, ngx_http_spdy_module was superseded by ngx_http_v2_module. So if you are using a version higher than 1.9.5, you don’t need to enable SPDY. See the following text to learn HTTP/2 and how to enable it with Nginx.


HTTP/2


HTTP/2 is based on SPDY. The HTTP/2 specification was published as RFC 7540 in May 2015. HTTP/2 is binary, instead of textual.


Improvements over SPDY


HPACK Compression


HPACK is a faster and smarter way to compress header. The ngx_http_spdy_module of Nginx disables header gzip  compression by default becuase it can be attacked by CRIME.


Requires No SSL/TLS


HTTP/2 protocol itself requires no SSL/TLS connection. But the implementation in all major browser vendors Firefox, Chrome, Opera say they will require TLS.



Enable HTTP/2 on Nginx


As of version 1.9.5, Nginx supports HTTP/2, so you have to install a Nginx version at least 1.9.5. I also suggest compiling the latest Nginx with ngx_pagespeed module, but it’s up to you. Use the following link to see how they’re done.


Install latest version of Nginx on Ubuntu server


Boost site speed by compiling latest Nginx version with ngx_pagespeed module on Ubuntu server


Like SPDY, it’s really simple to enable HTTP/2 on Nginx. Check if Nginx is compiled with HTTP/2 module


sudo nginx -V

Since your Nginx version is at least 1.9.5, you should see the following text in the output.


--with-http_v2_module

Then configure server block file


sudo vi /etc/nginx/conf.d/yourdomain.conf

or


sudo vi /etc/nginx/sites-available/yourdomain.conf

In the server section, add http2 after listen 443 ssl.


server {
listen 443 ssl http2;
server_name www.linuxbabe.com;

ssl_certificate /etc/ssl/fullchain.pem;
ssl_certificate_key /etc/ssl/privkey.pem;

......

Then save and close the file. Reload Nginx configuration.


sudo service nginx reload

or


sudo systemctl reload nginx

And you are done. Very easy!


How to Check if HTTP/2 is Working on Your Website


Go to https://tools.keycdn.com/http2-test. And enter your domain. Cloudflare has an excellent post about tools for testing and debugging HTTP/2.



What are SPDY and HTTP/2 and How to Enable Them on Nginx

No comments:

Post a Comment