在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
gzip压缩 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压缩 gzip参数说明: gzip_buffers gzip_comp_level gzip_min_length gzip_http_version gzip_proxied gzip_types gzip_vary on; Nginx与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 |
请发表评论