当前位置: 首页 > 编程笔记 >

Nginx服务器中使用gzip压缩的相关配置解析

谈灵均
2023-03-14
本文向大家介绍Nginx服务器中使用gzip压缩的相关配置解析,包括了Nginx服务器中使用gzip压缩的相关配置解析的使用技巧和注意事项,需要的朋友参考一下

gzip压缩
使用 gzip 压缩可以降低网站带宽消耗,同时提升访问速度。
主要在nginx服务端将页面进行压缩,然后在浏览器端进行解压和解析,
目前大多数流行的浏览器都迟滞gzip格式的压缩,所以不用担心。
默认情况下,Nginx的gzip压缩是关闭的,同时,Nginx默认只对text/html进行压缩
主要配置如下:

gzip on;#开启 
gzip_http_version 1.0;#默认1.1 
gzip_vary on; 
gzip_comp_level 6; 
gzip_proxied any; 
gzip_types text/plain text/html text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;#压缩的文件类型 
 
gzip_buffers 16 8k;#设置gzip申请内存的大小,其作用是按块大小的倍数申请内存空间设置gzip申请内存的大小,其作用是按块大小的倍数申请内存空间 
 
# Disable gzip for certain browsers. 
gzip_disable “MSIE [1-6].(?!.*SV1)”;#ie6不支持gzip,需要禁用掉ie6,可恶啊!!!! 

注意: 其中的gzip_http_version的设置,它的默认值是1.1,就是说对HTTP/1.1协议的请求才会进行gzip压缩
如果我们使用了proxy_pass进行反向代理,那么nginx和后端的upstream server之间是用HTTP/1.0协议通信的。

gzip参数说明:
决定是否开启gzip模块
param:on|off
example:gzip on;

gzip_buffers
设置gzip申请内存的大小,其作用是按块大小的倍数申请内存空间
param1:int 增加的倍数
param2:int(k) 后面单位是k
example: gzip_buffers 4 8k;

gzip_comp_level
设置gzip压缩等级,等级越底压缩速度越快文件压缩比越小,反之速度越慢文件压缩比越大
param:1-9
example:gzip_com_level 1;

gzip_min_length
当返回内容大于此值时才会使用gzip进行压缩,以K为单位,当值为0时,所有页面都进行压缩
param:int
example:gzip_min_length 1000;

gzip_http_version
用于识别http协议的版本,早期的浏览器不支持gzip压缩,用户会看到乱码,所以为了支持前期版本加了此选项,目前此项基本可以忽略
param: 1.0|1.1
example:gzip_http_version 1.0

gzip_proxied
Nginx做为反向代理的时候启用,
param:off|expired|no-cache|no-sotre|private|no_last_modified|no_etag|auth|any]
expample:gzip_proxied no-cache;
off – 关闭所有的代理结果数据压缩
expired – 启用压缩,如果header中包含”Expires”头信息
no-cache – 启用压缩,如果header中包含”Cache-Control:no-cache”头信息
no-store – 启用压缩,如果header中包含”Cache-Control:no-store”头信息
private – 启用压缩,如果header中包含”Cache-Control:private”头信息
no_last_modified – 启用压缩,如果header中包含”Last_Modified”头信息
no_etag – 启用压缩,如果header中包含“ETag”头信息
auth – 启用压缩,如果header中包含“Authorization”头信息
any – 无条件压缩所有结果数据

gzip_types
设置需要压缩的MIME类型,非设置值不进行压缩
param:text/html|application/x-javascript|text/css|application/xml
example:gzip_types text/html;

gzip_vary on;
和http头有关系,加个vary头,给代理服务器用的,有的浏览器支持压缩,有的不支持,所以避免浪费不支持的也压缩,所以根据客户端的HTTP头来判断,是否需要压缩

Nginx与Gzip请求
一般线程的Nginx的Gzip模块都是和Response相关的Gzip,但如果需要的是和Request相关的Gzip呢?来看下面:
方案

第一个选择是使用lua-zlib:

local zlib = require "zlib"

local encoding = ngx.req.get_headers()["Content-Encoding"]

if encoding == "gzip" then
  local body = ngx.req.get_body_data()

  if body then
    local stream = zlib.inflate()
    ngx.req.set_body_data(stream(body))
  end
end

第二个选择是通过LuaJIT的FFI库来包装ZLIB模块,官方教程里有一些现成的可供参考的的例子,不过例子里介绍的是Deflate,而不是Gzip,自己用FFI封装Gzip的话又有点小复杂,好在别人已经做了相关的工作,那就是lua-files:

local ffi = require "ffi"
local zlib = require "zlib"

local function reader(s)
  local done
  return function()
    if done then return end
    done = true
    return s
  end
end

local function writer()
  local t = {}
  return function(data, sz)
    if not data then return table.concat(t) end
    t[#t + 1] = ffi.string(data, sz)
  end
end

local encoding = ngx.req.get_headers()["Content-Encoding"]

if encoding == "gzip" then
  local body = ngx.req.get_body_data()

  if body then
    local write = writer()
    zlib.inflate(reader(body), write, nil, "gzip")
    ngx.req.set_body_data(write())
  end
end

如上例子代码源自zlib_test.lua,乍看上去,代码里的reader和writer可能会令人费解,其实你可以把它们理解成输入输出接口,可以修改成文件,数据库等等形式。

别高兴太早,当你运行时,很可能会遇到如下错误:

libzlib.so: cannot open shared object file.

实际上这是因为如下zlib.lua代码的缘故:

local C = ffi.load 'zlib'

运行时,ffi.load会自动补全文件名,如果是Windows,则加载zlib.dll文件,如果是Linux,则加载libzlib.so,但实际上在Linux下,ZLIB扩展的名字是libz.so,而非libzlib.so。

知道的问题的原委,我们自然就知道如何修改代码了:

local C

if ffi.os == "Windows" then
  C = ffi.load "zlib"
else
  C = ffi.load "z"
end

有时候我们不推荐直接修改第三方库的代码,因为这样的话,每次第三库更新代码,我们都要做对应的修改,一旦忘记就会出错,这时候可以考虑做一个软连接别名。

测试

开篇说过,接口都是用PHP做的,不过请求里的Gzip数据是用LUA处理的,如何让PHP使用LUA处理后的数据呢?不同的语言似乎是个难题,好在Nginx有Phases一说,PHP作为FastCGI模块工作在content阶段,LUA可以工作在access阶段,这样它们就和谐了:

location ~ \.php$ {
  access_by_lua_file /path/to/lua/file;

  include fastcgi.conf;
  fastcgi_pass 127.0.0.1:9000;
}

那么lua-zlib和lua-files两种方案效率如何?下面是我用PHP写的测试脚本:

<?php

$url = 'http://url';

$header = implode("\r\n", array(
  'Content-Type: application/x-www-form-urlencoded',
  'Content-Encoding: gzip',
  'Connection: close',
));

$content = gzencode(http_build_query(array(
  'foo' => str_repeat('x', 100),
  'bar' => str_repeat('y', 100),
)));

$options = array(
  'http' => array(
    'protocol_version' => '1.1',
    'method' => 'POST',
    'header' => $header,
    'content' => $content,
  ),
);

$context = stream_context_create($options);

for ($i = 0; $i < 1000; $i++) {
  file_get_contents($url, false, $context);
}

?>

很多人写测试脚本的时候,喜欢在开始结束部分加上时间,这样相减就得到了代码实际运行的时间,其实这是不必要的,利用Linux自带的time就可以获取运行时间:

shell> time php /path/to/php/file
 类似资料:
  • 我试图启用gzip压缩的组件我的网站。我有ubuntu 11.04服务器和nginx 1.2。 在网站的nginx配置中,我有以下内容 Yslow和谷歌的速度测量建议我使用gzip来减少网络传输。现在,当我尝试时,我得到了 是否知道我做错了什么,或者我应该做什么来获得压缩内容?

  • 我的项目部署在weblogic 12 c中。它有多个web项目,包括一个用于restful服务的spring mvc web项目。在weblogic domain wide web应用程序配置中,我可以提供任何支持gZip压缩的解决方案吗? 我试着跟踪这个链接。 但我找不到任何字段来将值放入GZIP Compression Enabled、GZIP Compression Min.Content

  • 我想在JavaScript中做解压缩图像。我已经用C#使用gzip压缩了图像。如何在JavaScript中解压缩gzipped数据? C#代码

  • 问题内容: 我正在使用php的功能来执行HTTP请求。为了节省带宽,我决定使用添加标题。 显然,输出一个gzip编码的字符串,所以我用来解码该编码的字符串,但是将作为参数传递的数据出错。 我知道还有另一个功能可以解压缩压缩后的数据,但是它不包含在我的PHP版本中(也许仅在SVN上可用)。 我知道cUrl可以即时解码gzip流(没有任何问题),但是有人建议我使用它而不是cUrl。 您是否知道以其他方

  • 本文向大家介绍Nodejs关于gzip/deflate压缩详解,包括了Nodejs关于gzip/deflate压缩详解的使用技巧和注意事项,需要的朋友参考一下 0x01.关于 写http时候,在接收http请求时候,出现乱码,后来发现是gzip没有解压。 关于gzip/deflate压缩,有放入管道压缩,和非管道压缩方法。 0x02.管道压缩 Node中的I/O是异步的,因此对磁盘和网络的读写需要

  • 本文向大家介绍Nginx服务器中关于SSL的安全配置详解,包括了Nginx服务器中关于SSL的安全配置详解的使用技巧和注意事项,需要的朋友参考一下  本文向你们展示如何在nginx的web服务器上设置更强的SSL。我们是通过使SSL无效来减弱CRIME攻击的这种方法实现。不使用在协议中易受攻击的SSLv3以及以下版本并且我们会设置一个更强的密码套件为了在可能的情况下能够实现Forward Secr