服务器切换到HTTP2
2018-09-21 Server花时间整理了一下服务器,期间在群里看到学长聊到HTTP/2,看了一下,发现自己的服务器还都是HTTP/1.1,于是也切换到了HTTP/2。
Server
> Linux --- Arch Linux x86_64
> Kernel --- 4.18.8-arch1-1-ARCH
> Apache --- 2.4.34-1
> PHP --- 7.2.10-1
HTTP/2
作为HTTP协议的第二个主要版本,2015年正式发布,到年末时主要的浏览器就已经支持并启用。
HTTP/2比较突出的特点有多路复用,头部压缩,服务器推送等,主要就是为了提升HTTP协议的性能表现。
HTTP/2本身允许非加密的HTTP协议(h2c),未强制要求使用加密,但大多数浏览器只实现了通过TLS加密的HTTP/2协议(h2),h2c 相当于被废弃。
更多相关信息可以参考维基百科:HTTP/2
切换过程
服务器之前使用libphp和mpm_prefork模块,只需要从官方源安装php-apache
即可在Apache下使用PHP。
但是mpm_prefork_module和HTTP/2并不兼容,所以我换用了ArchWiki中指明的第二种方法,利用php-fpm和mod_proxy_fcgi处理PHP,具体步骤如下:
- 修改
/etc/httpd/conf/httpd.conf
,不再使用libphp处理PHP:- 取消注释
LoadModule mpm_event_module modules/mod_mpm_event.so
- 注释
LoadModule mpm_prefork_module modules/mod_mpm_prefork.so
- 注释
LoadModule php7_module modules/libphp7.so
- 注释
AddHandler php7-script php
- 注释
Include conf/extra/php7_module.conf
- 重启
httpd.service
- 取消注释
- 修改
/etc/httpd/conf/httpd.conf
,换用php-fpm和mod_proxy_fcgi:- 取消注释
LoadModule proxy_module modules/mod_proxy.so
- 取消注释
LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so
- 在Include列表末尾添加
Include conf/extra/php-fpm.conf
- 创建文件
/etc/httpd/conf/extra/php-fpm.conf
,写入DirectoryIndex index.php index.html <FilesMatch \.php$> SetHandler "proxy:unix:/run/php-fpm/php-fpm.sock|fcgi://localhost/" </FilesMatch>
- 重启
httpd.service
和php-fpm.service
- 取消注释
- 开启HTTP/2:
- 修改
/etc/httpd/conf/httpd.conf
,取消LoadModule http2_module modules/mod_http2.so
的注释 - 在各个站点的
<VirtualHost *:443>
和</VirtualHost>
之间加入Protocols h2 http/1.1
- 重启
httpd.service
和php-fpm.service
- 修改
问题
以上一系列操作结束后尝试访问网页,却发现打不开,使用systemctl status httpd
查看,发现错误出现在两个地方:
/etc/httpd/conf/extra/httpd-vhosts.conf
的php_flag
处报错:<Directory "/srv/http/share/upload/"> php_flag engine off </Directory>
/etc/httpd/conf/extra/nextcloud.conf
的php_admin_value
处报错<Directory /usr/share/webapps/nextcloud/> Options FollowSymlinks AllowOverride all Require all granted php_admin_value open_basedir "/srv/http/:/dev/urandom:/tmp/:/usr/share/pear/:/usr/share/webapps/nextcloud/:/etc/webapps/nextcloud:/proc/" </Directory>
两处报错原因相同。
因为之前是相当于使用Apache的一个模块对PHP进行处理,所以在Apache负责读取的配置文件中可以设置PHP的选项。但是现在我们是让Apache把php文件的解析请求转发给php-fpm,由php-fpm对PHP进行处理,所以在Apache中将无法再设置PHP解释器的选项,因此需要对之前的配置文件进行适当修改:
- 第一处报错,原目的是禁止PHP解释器对指定目录的解析,防止上传目录中的恶意文件造成不良影响。既然无法修改PHP的选项,那么我们就修改Apache的选项,在
/etc/httpd/conf/extra/php-fpm.conf
文件中添加<Directory "/srv/http/share/upload/"> <FilesMatch \.php$> SetHandler none </FilesMatch> </Directory>
不把该文件夹中的PHP文件交给解释器,即可达到同样的效果。
- 第二处报错,原目的是修改PHP解释器的
open_basedir
,使得nextcloud对相应的目录或文件具有操作权限。因此作为修改,直接在/etc/php/php.ini
的open_basedir
变量中增加上述路径即可。
除此之外需要注意的地方还有:
- HTTP/2的正常使用需要建立在TLS基础上,在Let’s Encrypt上申请并部署免费证书即可。
- 修改PHP选项后需要重启
php-fpm.service
才可以生效,而不是像以前一样只需要重启httpd.service
。
效果
只是单纯开启HTTP/2,没有进行额外配置的话,主要是多路复用和头部压缩两个特点对性能的提升,因此请求数量较少的网页,例如whoisnian.com的提升效果不是很明显,打开时间主要受到的还是延迟的影响。而请求数量较多的网页,例如cloud.whoisnian.com登录后首次打开主界面需要100多个请求,花费的时间从15s减少到了11s,提升效果还是比较明显的。