HTTP2和SPDY
SPDY是Google的研究人员为了加速Web浏览体验搞出来的一个试验性协议,旨在降低网络延迟。据这帮研究人员报告,使用SPDY协议的网站平均等待时间只有用HTTP/1.1协议网站的几分之一。SPDY协议发展到2.0版的时候突然声名雀起,几乎每个浏览器都开始支持它——没错,连最顽固的微软IE浏览器也支持了。
然而就在这个SPDY一统天下的大好时代,Google宣布放弃SPDY协议。当然Google只是放弃SPDY这个名字而已,SPDY协议中绝大部分的优化手段都被Google写进了HTTP2标准草案里。如今HTTP2协议定稿在即,Google才大方出来宣言放弃SPDY,力争推动各厂尽快切换到HTTP2上。
虽然HTTP2在浏览器上的普及势如破竹比当年SPDY不惶多让,可惜主流的开源Web服务器跟进并不迅速,Apache的nginx目前都只有SPDY模块的支持。还好spdylay的开发团队动作迅速,马上提供了HTTP2的实现,让我们可以不必多加改动地把服务器部署上HTTP2。
下面介绍一下怎么让自己的网站同时支持SPDY和HTTP2协议。
准备工作
因为SPDY只能支持SSL/TLS加密的连接,我假设网站已经有证书和密钥。如果网站还没有这两样东西,请按这里。
我在使用的是Ubuntu 14.04 LTS 64bit 系统,因为系统没有自带spdylay的软件包,所以需要从源码编译。如果服务器只想支持HTTP2而不想支持SPDY协议,也可以不安装spdylay。直接开始nghttp2的安装。
首先要安装编译环境和spdylay的依赖库:
# apt-get install build-essential pkg-config zlib1g-dev libssl-dev libxml2-dev libevent-dev libevent-openssl-2.0-5
再去spdylay的网站下载spdylay的源代码包:
# wget 'https://github.com/tatsuhiro-t/spdylay/releases/download/v1.3.2/spdylay-1.3.2.tar.xz'
安装spdylay
解包和配置:
# tar xpf spdylay-1.3.2.tar.xz
# cd spdylay-1.3.2
# ./configure
配置完成之后会显示一个配置表:
Version: 1.3.2 shared 9:0:2
Host type: x86_64-unknown-linux-gnu
Install prefix: /usr/local
C compiler: gcc
CFLAGS: -g -O2
LDFLAGS:
LIBS: -lz
CPPFLAGS:
C preprocessor: gcc -E
C++ compiler: g++
CXXFLAGS: -g -O2
CXXCPP: g++ -E
Library types: Shared=yes, Static=yes
CUnit: no
OpenSSL: yes
Libxml2: yes
Libevent(SSL): yes
Src: yes
Examples: yes
请注意Libevent(SSL)务必要显示为yes,不然编译出来的软件包里不会包含spdy的反向代理。检查好了就可以编译和安装:
# make && make install
# ldconfig
因为新安装的lib不会马上被系统读到,导致运行spdylay程序出现.so文件找不到的情况,所以需要运行ldconfig
让系统重新载入动态链接库。
此时可以运行一下SPDY的反向代理程序,看看是否工作良好:
# shrpx
Usage: shrpx [-Dh] [-s|--client|-p] [-b <HOST,PORT>]
[-f <HOST,PORT>] [-n <CORES>] [-c <NUM>] [-L <LEVEL>]
[OPTIONS...] [<PRIVATE_KEY> <CERT>]
A reverse proxy for SPDY/HTTPS.
[FATAL] Too few arguments
(shrpx.cc:1167)
出现这个提示说明spdylay已经安装正常。
安装nghttp2
先要安装nghttp2依赖的软件包:
# apt-get install libev-dev libjansson-dev libjemalloc-dev python-dev cython
下载nghttp2的源代码包:
# wget 'https://github.com/tatsuhiro-t/nghttp2/releases/download/v0.7.11/nghttp2-0.7.11.tar.xz'
解压和配置:
# tar xpf nghttp2-0.7.11.tar.xz
# cd nghttp2-0.7.11
# ./configure
配置输出一个更长的信息表:
Version: 0.7.11 shared 13:0:8
Host type: x86_64-unknown-linux-gnu
Install prefix: /usr/local
C compiler: gcc
CFLAGS: -g -O2
WARNCFLAGS:
LDFLAGS:
LIBS:
CPPFLAGS:
C preprocessor: gcc -E
C++ compiler: g++
CXXFLAGS: -g -O2 -std=c++11
CXXCPP: g++ -E
Library types: Shared=yes, Static=yes
Python:
Python: /usr/bin/python
PYTHON_VERSION: 2.7
pyexecdir: ${exec_prefix}/lib/python2.7/dist-packages
Python-dev: yes
PYTHON_CPPFLAGS:-I/usr/include/python2.7
PYTHON_LDFLAGS: -L/usr/lib -lpython2.7
Cython: cython
Test:
CUnit: no
Failmalloc: yes
Libs:
OpenSSL: yes
Libxml2: yes
Libev: yes
Libevent(SSL): yes
Spdylay: yes
Jansson: yes
Jemalloc: yes
Boost CPPFLAGS:
Boost LDFLAGS:
Boost::ASIO:
Boost::System:
Boost::Thread:
Features:
Applications: yes
HPACK tools: yes
Libnghttp2_asio:no
Examples: yes
Python bindings:yes
Threading: yes
需要确认Features中的Application是yes。可以编译和安装:
# make && make install
# ldconfig
启动nghttpx反向代理
终于到最后一步,用nghttpx为网站提供HTTP2支持。因为nghttpx是反向代理服务器,如果现在的Web服务器已经启用了https,需要先把https支持关掉,不然会发生端口冲突哦。我们使用nghttpx的Base模式就可以了,在443端口上接收https请求,转发到本机的80端口,在先安装了spdylay的情况下,nghttpx是可以同时支持HTTP/1.1、SPDY/3.1、HTTP2的。
# nghttpx -f *,443 -b localhost,80 /path/to/private.key /path/to/certification.crt
如果没有什么错误,现在网站应该可以用支持http2的浏览器访问了,当然不支持http2的浏览器会自动降级到spdy或者http1.1上。
nghttpx有一堆高级的参数可以使用,比如变成一个daemon进程,还有指定运行的用户和组,还有输出日志的方法格式等等,就不在这里详述了,可以运行nghttpx -h
阅读帮助资料。