Ubuntu 16.04 开启 Apache2 HTTP2支持

Ubuntu 16.04的默认Apache 包中不包含http2,解决方法有2种。

  1. 使用PPA源
  2. 自行编译mod_http2

方法一,使用ppa源

[codesyntax lang=”bash”]

sudo add-apt-repository ppa:ondrej/apache2
sudo apt-get update
sudo apt-get install apache2
sudo a2enmod http2
sudo systemctl restart apache2

[/codesyntax]

方法二,自行编译mod_http2

1. 首先,需要开启源码源,已经开启的可以跳过这节

如果正在使用官方版本的Ubuntu,且未移除过apt的sources.list中deb-src部分则可以使用以下命令
[codesyntax lang=”bash”]

sed -i 's/^#\ deb-src/deb-src/g' /etc/apt/sources.list

[/codesyntax]
对于阿里云用户,可以使用以下命令
[codesyntax lang=”bash”]

sed -i 's/^#\ deb-src/deb-src/g' /etc/apt/sources.list.d/sources-aliyun-0.list

[/codesyntax]
对于其他用户,需要手工修改sources.list
可以将以下地址换成更快的镜像。
[codesyntax lang=”bash”]

echo "deb-src http://archive.ubuntu.com/ubuntu/ xenial main universe restricted multiverse" >> /etc/apt/sources.list
echo "deb-src http://security.ubuntu.com/ubuntu xenial-security main universe restricted multiverse" >> /etc/apt/sources.list 
echo "deb-src http://archive.ubuntu.com/ubuntu/ xenial-updates main universe restricted multiverse" >> /etc/apt/sources.list

[/codesyntax]

刷新apt缓存
[codesyntax lang=”bash”]

apt update

[/codesyntax]

2. 安装依赖项

[codesyntax lang=”bash”]

apt install curl devscripts build-essential fakeroot libnghttp2-dev

[/codesyntax]
注意:如果执行编译的机器不是服务器仅需要在服务器上安装libnghttp2
[codesyntax lang=”bash”]

apt install libnghttp2-14

[/codesyntax]

3. 准备工作目录和编译源代码

[codesyntax lang=”bash”]

cd ~
apt source apache2
apt build-dep apache2
cd apache2-2.4.18

[/codesyntax]
修改Apache 2编译配置
[codesyntax lang=”bash”]

sed -i '81a --enable-http2 \\' debian/rules

[/codesyntax]
执行编译
[codesyntax lang=”bash”]

fakeroot debian/rules binary

[/codesyntax]
复制mod_http2到apache2 模块目录
[codesyntax lang=”bash”]

cp debian/apache2-bin/usr/lib/apache2/modules/mod_http2.so /usr/lib/apache2/modules/

[/codesyntax]

4. 配置Apache

创建配置文件
[codesyntax lang=”bash”]

cat > /etc/apache2/mods-available/http2.load <<EOF
LoadModule http2_module /usr/lib/apache2/modules/mod_http2.so
EOF

[/codesyntax]
将mpm模式由prefork改为mpm event模式
注意: HTTP/2在httpd附带的所有多处理模块中都受到支持。但是,如果您使用prefork mpm,将会有严格的限制。在prefork mod_http2中,每次连接只处理一个请求。但是客户端,比如浏览器,会同时发送很多请求。如果其中一个需要很长时间来处理(或者是长轮询),其他请求将会停止。默认情况下,mod_http2不能在这个限制下工作。原因是,如果您运行的处理引擎不是为多线程准备的,那么现在只选择prefork,例如,它将在多个请求中崩溃。
如果您的设置能够处理它,那么现在配置 event mpm是最好的(如果您的平台支持的话)。

PHP默认安装不能工作在Apache MPM Event模式,请参见PHP配置节解决该问题
[codesyntax lang=”bash”]

a2dismod mpm_prefork
a2enmod mpm_event

[/codesyntax]
配置网站,在需要启用http2的VirtualHost中增加以下内容。建议在ServerName之后

    • HTTPS 网站
      [codesyntax lang=”apache”]

      Protocols h2 http/1.1

      [/codesyntax]

    • HTTP 网站
      [codesyntax lang=”apache”]

      Protocols h2c http/1.1

      [/codesyntax]

重启apache,注意如需要配置PHP,这里可以先不重启Apache
[codesyntax lang=”bash”]

systemctl restart apache2

[/codesyntax]

5. 配置PHP

请根据使用的PHP版本修改命令。
安装PHP-FPM
[codesyntax lang=”bash”]

apt install php7.0-fpm

[/codesyntax]
修改Apache 配置
[codesyntax lang=”bash”]

a2enmod proxy_fcgi setenvif
a2dismod php7.0
a2enconf php7.0-fpm

[/codesyntax]
重启Apache
[codesyntax lang=”bash”]

systemctl restart apache2

[/codesyntax]

参考资料

[1] HTTP/2 guide https://httpd.apache.org/docs/trunk/howto/http2.html
[2] UBUNTU 16.04 APACHE2开启HTTP2支持