将 VPS 操作系统升级到 CentOS 7,有了 Apache 2.4 便迫不及待的尝试了一下 MPM event + PHP-FPM 组合。使用 Google PageSpeed 测试性能的时候却发现提示没开启网页 gzip 压缩。这个问题的解决很意外,记录在这里与大家分享。
之前服务器 Apache 运行在 prefork 模式,一直采用 mod_deflate 提供网页压缩传输功能。切换 Apache MPM 模式的时候除了有限的几个需要调整的参数外其它的都没有变化。所以 deflate 怎么就突然不工作了呢?
第一时间想到的就是,因为 PHP-FPM 是 Apache 之外的,可能与 deflate 协调不好。就试了试不需要通过 PHP-FPM 解释的 html 网页,果然是开启了 gzip 的。然后在网上拼命 Google 相关问题。别说,还真有人提到这个问题,只不过他是在 Apache 2.2 上,其它组件一样但这里是 Zend Opcache 而不是 APC。症状一样:
UPDATE: The problems seems to be with anything that is processed by PHP, if I copy the html output to a .html file and then fetch it, it will be compressed, if I rename the same file to .php and fetch it the output won’t be compressed.
我一度为了能使用网页压缩而开启了 PHP 内置的 Zlib 压缩,在 /etc/php.ini 中修改 Zlib 压缩参数为,
zlib.output_compression on
但是WordPress 中的 WP Super Cache 一个劲儿的提示说开了 Zlib 不太好之类的 blah blah。
于是继续找解决办法,结果却是无意中解决了。这是在调整 Apache 的参数配置文件,那一大堆 conf 文件的时候解决的。方法倒是很简单,简单到至今我都不太确定是不是真的是这个情况:将 deflate 配置放到 <Location /> 而不是 <Directory /> 里面。( )
因为 Apache 2.4 里将本来放在 httpd.conf 里的配置分割开来放到了 conf.modules.d 文件夹下面的多个 conf 文件里。受到启发,我也把 vhost.conf 里的全局配置提出来放到了新的 00-common.conf 里面。我的具体部署是,在 Apache 的 conf.d 文件夹下新增了两个配置文件, 00-common.conf 放置全局 vhost 配置,比如 deflate 设置等;01-bad.conf 放置屏蔽一些 spider 和 乱七八糟广告 bot 的配置。
为了对所有的虚拟主机(同一服务器 Apache 上配置的多个网站)同时适用,就把 mod_deflate 的配置改成下面的样子(其中一些具体的指令规则已经是很久很久前从网上搜集的了,没记录具体的出处):
# Enclose configurations of mod_deflate # by <Location /> </Location> # instead of <Directory /> </Directory> # to make them effective to PHP-FPM. <Location /> # mod_gzip <ifModule mod_gzip.c> mod_gzip_on Yes mod_gzip_dechunk Yes mod_gzip_item_include file \.(html?|txt|css|js|php|pl|css\?.*|js\?.*)$ mod_gzip_item_include handler ^cgi-script$ mod_gzip_item_include mime ^text/.* mod_gzip_item_include mime ^application/x-javascript.* mod_gzip_item_exclude rspheader ^Content-Encoding:.*gzip.* </ifModule> # mod_deflate <IfModule deflate_module> <IfModule filter_module> AddOutputFilterByType DEFLATE text/plain AddOutputFilterByType DEFLATE text/css AddOutputFilterByType DEFLATE text/css\?(.*) AddOutputFilterByType DEFLATE text/xml application/xml application/xhtml+xml application/xml-dtd AddOutputFilterByType DEFLATE image/svg+xml AddOutputFilterByType DEFLATE application/rss+xml AddOutputFilterByType DEFLATE application/atom_xml AddOutputFilterByType DEFLATE application/x-javascript AddOutputFilterByType DEFLATE application/x-httpd-php AddOutputFilterByType DEFLATE application/x-httpd-fastphp AddOutputFilterByType DEFLATE application/x-httpd-eruby AddOutputFilterByType DEFLATE text/html text/htm AddOutputFilterByType DEFLATE font/otf font/opentype application/font-otf application/x-font-otf AddOutputFilterByType DEFLATE font/ttf font/truetype application/font-ttf application/x-font-ttf </IfModule> SetOutputFilter DEFLATE BrowserMatch ^Mozilla/4 gzip-only-text/html BrowserMatch ^Mozilla/4\.0[678] no-gzip BrowserMatch \bMSIE !no-gzip !gzip-only-text/html BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png)$ no-gzip dont-vary SetEnvIfNoCase Request_URI \.(?:exe|t?gz|zip|bz2|sit|rar|7z)$ no-gzip dont-vary SetEnvIfNoCase Request_URI \.pdf$ no-gzip dont-vary SetEnvIfNoCase Request_URI \.avi$ no-gzip dont-vary SetEnvIfNoCase Request_URI \.mov$ no-gzip dont-vary SetEnvIfNoCase Request_URI \.mp3$ no-gzip dont-vary SetEnvIfNoCase Request_URI \.mp4$ no-gzip dont-vary SetEnvIfNoCase Request_URI \.rm$ no-gzip dont-vary SetEnvIfNoCase Request_URI \.(?:docx?|pptx?|pptm|xlsx?)$ no-gzip dont-vary </IfModule> </Location>
跟之前的最大区别就是代码上下两端的 <Location /> </Location>
。Enclose configurations of mod_deflate by <Location /> </Location> instead of <Directory /> </Directory> to make it effective to PHP-FPM in case of php files are not compressed before sending to client but html files and others are compressed..
不过,到底是不是因为这个才使得在 Apache + PHP-FPM 的情况下能对 PHP 文件执行 deflate 压缩,只在虚拟机里试了试,没在服务器上验证。主要是累得不想折腾了。如果有朋友有这方面的经历,请一定留言告知一声。©
本文发表于水景一页。永久链接:<https://cnzhx.net/blog/apache-php-fpm-and-mod_deflate/>。转载请保留此信息及相应链接。
你的评论設定沒有接受語法,所以有些字被過濾掉。
对不起,评论里只接受少量语法。另外,为了过滤一些比较明显的spam,还自己设定了一些条件,可能会误挡某些正常评论。
你提供的代码是为了补充 deflate 设置的吗?好像在哪里看到过测试,说压缩级别设置高了虽然可以压缩得更多,但是相比较更多的CPU消耗是不划算的。所以这里没设置。
BrowerMatch 是干什么的?另外,Cache Control 是与 mod_deflate 无关的,所以没有在这里写出来。