HTTP1.1 vs HTTP/2
Limitations of HTTP/1.1
The HTTP/1.1 protocol is fraught with the following shortcomings that make it less ideal especially when running high-traffic web servers:
1.Delays in loading web pages due to long HTTP headers.
2.HTTP/1.1 is only able to send one request for each file per TCP connection.
3. Given that HTTP/1.1 processes one request for every TCP connection, browsers are forced to send a deluge of parallel TCP connections to simultaneously process the requests. This leads to TCP congestion and ultimately bandwidth wastage and network degradation.
The above-mentioned problems often led to performance degradation and high overhead costs in bandwidth usage.
address these problems and is now the future for HTTP protocols.
Advantages of Using HTTP/2
It offers the following advantages:
HTTP/2
came into the picture to
1.Header compression that minimizes client requests and thereby lowers bandwidth consumption. The resultant effect is fast page load speeds.
2.Multiplexing several requests over one TCP connection. Both the server and the client can break down an HTTP request into multiple framesand regroup them at the other end.
3.Faster web performances which consequently lead to better SEO ranking.
4.Improved security since most mainstream browsers loads HTTP/2 over HTTPS.
5.HTTP/2 is considered more mobile-friendly thanks to the header compression feature
HTTP/2 is the fourth version of the HTTP protocol that was released in 2015. The performance enhancements over the HTTP/1.1 protocol include:
- End-user perceived latency improvements
- Network overhead improvements
- Server resource usage improvements
Drawbacks of HTTP/2
- Nonetheless, there are also some limitations businesses should take into account before switching to the new protocol.
- Be aware of your audience: Although 75% of UK users are using browsers than can take advantage of the protocol, a number of people continue to use older browsers which don’t. Additionally, not all web servers out there support HTTP/2. Therefore, current page speed optimization techniques will remain necessary.
- HTTPS Prerequisite: Switching from HTTP/1.1 will be more difficult if a site isn’t already using HTTPS, since HTTP/2 has the prerequisite of the site already being on HTTPS. Migrating a website to HTTPS will need some work, requiring all HTTP URLs to be redirected to the HTTPS secure version of the protocol. However, HTTPS is a positive ranking factor for Google and, since security is a top priority for the search engine, we expect them to apply more weight to this signal in the future. Therefore, it would be a good idea to upgrade your site as and when you can.
- Performance impact could be minimal: Switching from HTTP/1.1 to HTTP/2 could take a lot of time and resources so it’s important to be sure that the impact in site speed worth it. If a website is already well-optimized for speed, the performance improvements might be smaller than expected.
HTTP/2 Unknowns: The protocol is still relatively new; a lot of studies will have to be conducted in order to determine best practices and possible pitfalls.
Multiplexing
One of the limitations of HTTP/1.1 is that it is only able to request files one by one on a single connection – this means requesting the file, waiting for a response, downloading the file and then requesting the next one.
This process can significantly increase page load time, especially for pages with a high number of requests. As illustrated in the image below, HTTP/2 changes how requests and responses travel between browser and server by “multiplexing” multiple files over one single connection
Header Compression
HTTP/1.1 requests and responses are transmitted in plain text (causing a lot of unnecessary bytes being downloaded) but with HTTP/2, each bit of information is compressed and transmitted in binary code, making it more compact and efficient which avoids the user’s computer to wasting time translating the information into a format it understands.
This means that the overhead of each request will be smaller than the uncompressed HTTP/1.1 equivalent, saving significant bandwidth in some user sessions. Page load speed is critical upon mobile users, where the benefits of this feature become even more important.
Requirements and OS Compatibility Matrix
As you click on the tab the page content will also change for that particular technology
Notes
- NginX can do NPN with OpenSSL 1.0.1 only. You need EL7.4+ with OpenSSL 1.0.2 to work with both NPN and APN. See NginX blog post in reference section below
- Ubuntu 14.04 LTS : Nginx version 1.4.x provided by Ubuntu does not support HTTP2. Install Nginx from ppa:nginx/stable which provided supported version 1.12.x
- Ubuntu 16.04 LTS accidentally included http2 when it was still experimental, but removed it afterwards, even though the httpd version remains high enough
- Ubuntu 18.04 LTS requires the http2 module be manually enabled
- IUS http24u includes mod_http2
- CentOS 8 has Apache with mod_http2 already compiled
- Unsupported Repositories and ppa:
Red Hat Software Collections – RHSCL – SCL rh-nginx110 or rh-nginx112 (RHEL 7)
Red Hat Software Collections – RHSCL – SCL rh-nginx110 (RHEL6)
Red Hat Software Collections – RHSCL – SCL http24 includes mod_http2 - ondrej
- Supported Repositories
- Ubuntu 20.04 and CentOS 8 is not currently available in dedicated. Currently only in the cloud.
Apache
Red Hat Support
From https://access.redhat.com/solutions/2159801
- Red Hat only supports http2 on JBoss Core Services Apache HTTP Server 2.4.23.
- Red Hat only provides “experimental” support under RHSCL 2.2 or newer (which provides httpd24, which is httpd 2.4.18).
Ubuntu Support
Vendor support appears to be Ubuntu 18.04 LTS only.
RHEL6/CentOS 6
Not Supported – Don’t try. While IUS httpd24 for RHEL6/CentOS 6 is sufficient, we are unable to obtain any supported and continually patched version of OpenSSL
RHEL7/CentOS 7
Apache+PHP72u+PHP-FPM
I used Apache 2.4 with PHP-FPM#fpm-CentOS7:Apache2.4withphp-fpmusingTCPport
And works with additional Apache 2.4 with PHP-FPM#fpm-CentOS7:Apache2.4withphp-fpmusingaUNIXsocket
Prerequistites
[root@742027-RHEL7a ~]# cat /etc/redhat-release
Red Hat Enterprise Linux Server release 7.5 (Maipo)
[root@742027-RHEL7a ~]# openssl version
OpenSSL 1.0.2k-fips 26 Jan 2017
[root@742027-RHEL7a ~]# httpd -v
Server version: Apache/2.4.34 (IUS)
Server built: Aug 7 2018 19:41:14
[root@742027-RHEL7a ~]# php -v
PHP 7.2.9 (cli) (built: Aug 17 2018 08:23:28) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
[root@742027-RHEL7a ~]# php-fpm -v
PHP 7.2.9 (fpm-fcgi) (built: Aug 17 2018 08:25:26)
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
Load the mod_http2 in /etc/httpd/conf.modules.d/00-base.conf
echo “LoadModule http2_module modules/mod_http2.so” >> /etc/httpd/conf.modules.d/00-base.conf
Enforce TLS only in /etc/http/conf.d/ssl.conf
echo “protocols h2 http/1.1” >> /etc/httpd/conf.d/ssl.conf
Enable TLS and cleartext(HTTP) in /etc/httpd/conf/httpd.conf
# Probably not a good idea
Protocols h2 h2c http/1.1
Verify http2 functionality
Before
[root@742027-RHEL7a ~]# curl -I -v http://127.0.0.1/index.php
* About to connect() to 127.0.0.1 port 80 (#0)
* Trying 127.0.0.1…
* Connected to 127.0.0.1 (127.0.0.1) port 80 (#0)
> HEAD /index.php HTTP/1.1
> User-Agent: curl/7.29.0
> Host: 127.0.0.1
> Accept: */*
>
< HTTP/1.1 200 OK
HTTP/1.1 200 OK
< Date: Fri, 21 Sep 2018 14:08:09 GMT
Date: Fri, 21 Sep 2018 14:08:09 GMT
< Server: Apache
Server: Apache
< X-Powered-By: PHP/7.2.9
X-Powered-By: PHP/7.2.9
< Content-Type: text/html; charset=UTF-8
Content-Type: text/html; charset=UTF-8
<
* Connection #0 to host 127.0.0.1 left intact
### After
[root@742027-RHEL7a ~]# systemctl restart httpd
[root@742027-RHEL7a ~]# curl -I -v http://127.0.0.1/index.php
* About to connect() to 127.0.0.1 port 80 (#0)
* Trying 127.0.0.1…
* Connected to 127.0.0.1 (127.0.0.1) port 80 (#0)
> HEAD /index.php HTTP/1.1
> User-Agent: curl/7.29.0
> Host: 127.0.0.1
> Accept: */*
>
< HTTP/1.1 200 OK
HTTP/1.1 200 OK
< Date: Fri, 21 Sep 2018 14:12:17 GMT
Date: Fri, 21 Sep 2018 14:12:17 GMT
< Server: Apache
Server: Apache
< X-Powered-By: PHP/7.2.9
X-Powered-By: PHP/7.2.9
< Upgrade: h2
Upgrade: h2
< Connection: Upgrade
Connection: Upgrade
< Content-Type: text/html; charset=UTF-8
Content-Type: text/html; charset=UTF-8
<
* Connection #0 to host 127.0.0.1 left intact
RHEL8/CentOS 8
In RHEL/CentOS 8 when the Apache module is installed it also installs the http2 module and loads by default. Next is just to enable http2 at the vhost. I tested both html and php.
The domain example.com pointed to the local ip via “/etc/hosts”. As you can see from the the below, Apache is responding with “HTTP/1.1”.
before enabling http2
# curl -I -s https://example.com/index.php –insecure |grep HTTP
HTTP/1.1 200 OK
# curl -I -s https://example.com/index.html –insecure |grep HTTP
HTTP/1.1 200 OK
To enable http2 add the line “Protocols h2 http/1.1” to the vhost as below and restart Apache.
Enable http2
<VirtualHost *:443>
Protocols h2 http/1.1
DocumentRoot /var/www/vhost
ServerName example.com
SSLEngine on
SSLCertificateKeyFile /etc/pki/tls/private/localhost.key
SSLCertificateFile /etc/pki/tls/certs/localhost.crt
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1 +TLSv1.2
# Proxy declaration
<Proxy “unix:/run/php-fpm/www.sock|fcgi://php-fpm”>
# we must declare a parameter in here (doesn’t matter which) or
# it’ll not register the proxy ahead of time
ProxySet disablereuse=off
# Note: If you configure php-fpm to use the “pm = ondemand”
#then use “ProxySet disablereuse=on”
</Proxy>
<FilesMatch \.php$>
SetHandler proxy:fcgi://php-fpm
</FilesMatch>
</VirtualHost>
After enabling http2 you will now notice that Apache is responding with “HTTP/2”
http2 Enabled
# curl -I -s https://example.com/index.php –insecure |grep HTTP
HTTP/2 200
# curl -I -s https://example.com/index.html –insecure |grep HTTP
HTTP/2 200
At the time of testing:
Testing performed using the following
# cat /etc/redhat-release
CentOS Linux release 8.2.2004 (Core)
# openssl version
OpenSSL 1.1.1c FIPS 28 May 2019
# php -v
PHP 7.2.24 (cli) (built: Oct 22 2019 08:28:36) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
# php-fpm -v
PHP 7.2.24 (fpm-fcgi) (built: Oct 22 2019 08:28:36)
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
# httpd -v
Server version: Apache/2.4.37 (centos)
Server built: Jun 8 2020 20:14:33
Ubuntu 14.04 LTS
Don’t do it. This OS will EOL in April 2019. Neither OpenSSL nor Apache versions are high enough.
Ubuntu 16.04 LTS
OpenSSL is a high enough version, but the included Apache version does not include http2 functionality (though it was once accidentally included, before being removed since Ubuntu doesn’t want to support “experimental” technology in LTS releases).
Apache 2 PPA
sudo apt install software-properties-common
sudo add-apt-repository ppa:ondrej/apache2
sudo apt update
sudo apt install apache2
Otherwise, its a custom compile task. Again, Rackspace should never do this on a customer’s behalf.
Custom Compile (for reference only, do not do this for customers)
# To proceed anyways building http2 from source, it can be done by:
Install lamp stack normally, then:
vim /etc/apt/sources.list
<uncomment>
deb-src http://us.archive.ubuntu.com/ubuntu/ xenial main restricted
deb-src http://us.archive.ubuntu.com/ubuntu/ xenial-updates main restricted
# Now build http2.so from source and copy it into /usr/lib/apache2/modules:
apt-get update
apt-get install libnghttp2-dev
mkdir /root/apache2
cd /root/apache2
apt-get source apache2
apt-get build-dep apache2
cd apache2-2.4.18
fakeroot debian/rules binary
cp debian/apache2-bin/usr/lib/apache2/modules/mod_http2.so /usr/lib/apache2/modules/
echo “LoadModule http2_module /usr/lib/apache2/modules/mod_http2.so” > /etc/apache2/mods-available/http2.load
# Then install php-fpm as mod_php will not work with mpm-event… and mod_http2 only works with mpm-event or
mpm-worker:
apt-get install php7.0-fpm
a2enmod proxy_fcgi setenvif
a2enconf php7.0-fpm
a2dismod php7.0
a2dismod mpm_prefork
a2enmod mpm_event
# Update config to use TLS1.2:
vim /etc/apache2/mods-enabled/ssl.conf
SSLProtocol -all TLSv1.2
a2enmod http2
systemctl restart apache2
vim /etc/apache2/sites-enabled/example.com.conf
<VirtualHost *:443>
Protocols h2 http/1.1
…
apachectl restart
# Test with:
curl -I -v https://example.com/test.html –insecure
…
< Upgrade: h2
Upgrade: h2
< Connection: Upgrade
Connection: Upgrade
…
Ubuntu 18.04 LTS
Enable HTTP2 on Ubuntu 18.04 LTS
The mpm module (prefork.c) is not supported by mod_http2. So have to figure out how to use mpm worker or
event… which means php7.2 will need to use something like php-fpm
# Install lamp stack normally, then:
apt-get update
apt-get install php7.2-fpm
a2enmod proxy_fcgi setenvif
a2enconf php7.2-fpm
a2dismod php7.2
a2dismod mpm_prefork
a2enmod mpm_event
# Update config to use TLS1.2:
vim /etc/apache2/mods-enabled/ssl.conf
SSLProtocol -all TLSv1.2
# Enable module
a2enmod http2
systemctl restart apache2
vim /etc/apache2/sites-enabled/example.com.conf
<VirtualHost *:443>
Protocols h2 http/1.1
…
# Restart Apache
apachectl restart
# Test with:
curl -I -v https://example.com/test.html –insecure
…
* ALPN, offering h2
…
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* ALPN, server accepted to use h2
…
< HTTP/2 200
HTTP/2 200
…
Ubuntu 20.04 LTS
The following is the check to verify if http2 is already enable. The domain example.com pointed to the local ip via “/etc/hosts”. As you can see from the the below, Apache is responding with “HTTP/1.1”.
Before http2
# curl -I -s https://example.com/index.php –insecure |grep HTTP
HTTP/1.1 200 OK
# curl -I -s https://example.com/index.html –insecure |grep HTTP
HTTP/1.1 200 OK
Set TLS to TLSV1.2
set TLSV1.2
# Update config to use TLS1.2:
vim /etc/apache2/mods-enabled/ssl.conf
SSLProtocol -all TLSv1.2
Enable the following modules
Enable module
a2enmod actions alias proxy_fcgi setenvif http2
Add the line “Protocols h2 http/1.1” to the vhost configuration to enable it for the domain, as in the following example. Afterwards you need to restart Apache
Enable http2
<VirtualHost *:443>
Protocols h2 http/1.1
DocumentRoot /var/www/vhost
ServerName example.com
SSLEngine on
SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem
# Proxy declaration
<FilesMatch \.php$>
SetHandler “proxy:unix:/var/run/php/php7.4-fpm.sock|fcgi://localhost”
</FilesMatch>
</VirtualHost>
After enabling http2 you will now notice that Apache is responding with “HTTP/2”
Verify http2
# curl -I -s https://example.com/index.html –insecure |grep HTTP
HTTP/2 200
# curl -I -s https://example.com/index.php –insecure |grep HTTP
HTTP/2 200
The configuration at the time of testing
during testing
~# lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 20.04.1 LTS
Release: 20.04
Codename: focal
~# openssl version
OpenSSL 1.1.1f 31 Mar 2020
~# php -v
PHP 7.4.3 (cli) (built: May 26 2020 12:24:22) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
with Zend OPcache v7.4.3, Copyright (c), by Zend Technologies
~# php-fpm7.4 -v
PHP 7.4.3 (fpm-fcgi) (built: May 26 2020 12:24:22)
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
with Zend OPcache v7.4.3, Copyright (c), by Zend Technologies
~# apache2ctl -v
Server version: Apache/2.4.41 (Ubuntu)
Server built: 2020-08-12T19:46:17
Nginx
HTTP2 is available by default and is fully supported on servers running Nginx. Nginx has had HTTP2 support built in as of Nginx 1.9.5.
The table below outlines which packages support HTTP2 on Nginx
Verify that http2 has been compiled in nginx
Verify module
# strings /usr/sbin/nginx | grep _module | grep -v configure| sort | grep ^ngx_http_v2_module
ngx_http_v2_module
ngx_http_v2_module
Enable HTTP2 on Nginx is as simple as modifying an existing Nginx vhost to enable HTTP2 as shown below:
[root@web01 ~]# vim /etc/nginx/sites-enabled/example.com.conf
…
server {
listen 443 ssl http2;
server_name example.com www.example.com;
…
[root@web01 ~]# nginx -t
[root@web01 ~]# service nginx restart
Test to confirm HTTP2 is working by:
[user@workstation ~]# curl -IL https://www.example.com –insecure
HTTP/2 200 <—
server: nginx/1.14.0 (Ubuntu)
date: Mon, 22 Oct 2018 18:46:25 GMT