Apache模块 mod_deflate
说明 | 压缩发送给客户端的内容 |
---|---|
状态 | 扩展(E) |
模块名 | deflate_module |
源文件 | mod_deflate.c |
概述
mod_deflate
模块提供了DEFLATE
输出过滤器,允许服务器在将输出内容发送到客户端以前进行压缩,以节约带宽。
配置举例
这是一个针对心急者的示范配置:
仅仅压缩少数几种类型
AddOutputFilterByType DEFLATE text/html text/plain text/xml
以下允许压缩更多内容的配置更加复杂。除非你明白所有的配置细节,否则请不要使用。
Compress everything except images
<Location />
# 插入过滤器
SetOutputFilter DEFLATE
# Netscape 4.x 有一些问题...
BrowserMatch ^Mozilla/4 gzip-only-text/html
# Netscape 4.06-4.08 有更多的问题
BrowserMatch ^Mozilla/4/.0[678] no-gzip
# MSIE 会伪装成 Netscape ,但是事实上它没有问题
BrowserMatch /bMSIE !no-gzip !gzip-only-text/html
# 不压缩图片
SetEnvIfNoCase Request_URI /
/.(?:gif|jpe?g|png)$ no-gzip dont-vary
# 确保代理不会发送错误的内容
Header append Vary User-Agent env=!dont-vary
</Location>
启用压缩
输出压缩
压缩是由DEFLATE
过滤器实现的。下面的指令会对其所在容器中的文档启用压缩:
SetOutputFilter DEFLATE
一些流行的浏览器不能正确处理所有压缩内容,因此你可能需要将gzip-only-text/html
标记设为"1
"来仅仅允许压缩html文件(见下面)。如果你设置了"1
"以外的任何值,都将被忽略。
如果你想将压缩限制在几种特定的MIME类型上,可以使用AddOutputFilterByType
指令。下面的例子仅仅允许对html文档进行压缩:
<Directory "/your-server-root/manual">
AddOutputFilterByType DEFLATE text/html
</Directory>
对于那些不能正确处理所有压缩内容的浏览器,可以使用BrowserMatch
指令针对特定的浏览器设置no-gzip
标记以取消压缩。为了取得更好的效果,你可以将no-gzip
和gzip-only-text/html
配合使用。在这种情况下,下面的设置将会覆盖上面的设置。看看从配置示例中摘录的片断:
BrowserMatch ^Mozilla/4 gzip-only-text/html
BrowserMatch ^Mozilla/4/.0[678] no-gzip
BrowserMatch /bMSIE !no-gzip !gzip-only-text/html
第一条指令表示如果User-Agent
字符串表示它是一个Navigator 4.x的浏览器,这种浏览器不能正确处理除text/html
之外的所有类型。而4.06, 4.07, 4.08版的Navigator完全不能处理任何压缩内容,因此第二条指令对这些浏览器完全禁用压缩。
第三个BrowserMatch
指令修正了上面两条对浏览器的推测,因为微软的IE也将它自己标识成"Mozilla/4"但是它实际上能够处理所有的压缩内容。因此又在User-Agent
头中额外匹配了字符串"MSIE"("/b
"表示"单词边界"),并且取消了前面的限制。
注意
DEFLATE
过滤器总是在类似于PHP或SSI之类的资源过滤器之后插入,它永远不会触及到内部请求。
输出解压
mod_deflate
模块还提供了一个解压gzip格式的应答体的功能。为了激活这个特性你必须使用SetOutputFilter
或AddOutputFilter
指令将INFLATE
过滤器插入到输入过滤器链:
<Location /dav-area>
ProxyPass http://example.com/
SetOutputFilter INFLATE
</Location>
这个例子将会解压来自example.com的输出,这样其它过滤器就可以做进一步的处理了。
输入解压
mod_deflate
模块还提供了一个解压gzip格式的请求体的功能。为了激活这个特性你必须使用SetInputFilter
或AddInputFilter
指令将DEFLATE
过滤器插入到输入过滤器链。例如:
<Location /dav-area>
SetInputFilter DEFLATE
</Location>
这样,如果包含"Content-Encoding: gzip
"头的请求体将会被自动解压。极少有浏览器压缩请求体。然而有些程序的确这么做了,比如一些WebDAV客户端程序。
注意 Content-Length
如果你自己处理请求体,请注意Content-Length
头仅仅表示客户端输入的数据长度,而不是解压后的实际数据长度。
代理服务器
mod_deflate
模块发送一个"Vary: Accept-Encoding
"HTTP应答头以提醒代理服务器:只对发送了正确"Accept-Encoding
"头的客户端发送缓存的应答。这样可以防止不能正确处理压缩内容的浏览器接受到经过压缩的内容。
如果你按照某些特殊的条件拒绝了某些客户端的访问(比如User-Agent
头),你必须手动配置一个额外的Vary
头提醒代理服务器做额外的限制。比如,在一个典型的配置中的某处,如果额外的DEFLATE
过滤器是否生效取决于User-Agent
头,你应当在此处添加:
Header append Vary User-Agent
如果依照除请求头以外的其他条件决定是否使用压缩(例如:HTTP版本),你必须设置Vary
头的值为"*
"来完全阻止代理服务器的缓存。
示例
Header set Vary *
DeflateBufferSize 指令
说明 | 用于zlib一次压缩的片断大小(字节) |
---|---|
语法 | DeflateBufferSize value |
默认值 | DeflateBufferSize 8096 |
作用域 | server config, virtual host |
状态 | 扩展(E) |
模块 | mod_deflate |
DeflateBufferSize
指令定义了zlib一次压缩的片断的字节数。
DeflateCompressionLevel 指令
说明 | 将输出内容压缩的程度 |
---|---|
语法 | DeflateCompressionLevel value |
默认值 | Zlib的默认值 |
作用域 | server config, virtual host |
状态 | 扩展(E) |
模块 | mod_deflate |
兼容性 | 仅在 Apache 2.0.45 及以后的版本中可用 |
DeflateCompressionLevel
指令设置压缩程度,越高的压缩程度就会有越好的压缩效果,同时也意味着占用越多的CPU资源。
取值范围在 1(最低压缩率) 到 9(最高压缩率)之间。
DeflateFilterNote 指令
说明 | 在日志中放置压缩率标记 |
---|---|
语法 | DeflateFilterNote [type] notename |
作用域 | server config, virtual host |
状态 | 扩展(E) |
模块 | mod_deflate |
兼容性 | type仅在2.0.45以后版本中可用 |
DeflateFilterNote
指令指定将一个指示压缩率的标记附加在请求之后。notename就表示这个标记的名字。你可以为了某种统计目的将这个标记的名字添加到访问日志中。
示例
DeflateFilterNote ratio
LogFormat '"%r" %b (%{ratio}n) "%{User-agent}i"' deflate
CustomLog logs/deflate_log deflate
如果你想从日志中得到更多精确的数据,可以使用type参数指定notename标记所记录的数据类型。type的取值范围如下:
- 在标记中存储过滤器输入流的字节数。
- 在标记中存储过滤器输出流的字节数。
-
在标记中存储过滤器的压缩比(
输出/输入*100
)。这是 type的默认值。
Input
Output
Ratio
于是,就可以这样记录:
Accurate Logging
DeflateFilterNote Input instream
DeflateFilterNote Output outstream
DeflateFilterNote Ratio ratio
LogFormat '"%r" %{outstream}n/%{instream}n (%{ratio}n%%)' deflate
CustomLog logs/deflate_log deflate