我正在尝试在Memcached中保存packed(gzip)html并在nginx中使用:
主要是配置工作,除了ssi步骤:
location / {
ssi on;
set $memcached_key "$uri?$args";
memcached_pass memcached.up;
memcached_gzip_flag 2; # net.spy.memcached use second byte for compression flag
default_type text/html;
charset utf-8;
gunzip on;
proxy_set_header Accept-Encoding "gzip";
error_page 404 405 400 500 502 503 504 = @fallback;
}
看起来,nginx在通过gunzip模块解压缩之前执行ssi处理。
在结果HTML中,我看到未解决的ssi指令:
<!--# include virtual="/remote/body?argument=value" -->
nginx日志中没有错误。
尝试过 ssi_types * - 没效果
知道怎么解决吗?
nginx 1.10.3(Ubuntu)
更新
已经尝试了一个上游。相同的结果=(
在日志中,我看到,ssi过滤器在上游请求后应用,但没有检测到包含。
upstream memcached {
server localhost:11211;
keepalive 100;
}
upstream unmemcached {
server localhost:21211;
keepalive 100;
}
server {
server_name dev.me;
ssi_silent_errors off;
error_log /var/log/nginx/error1.log debug; log_subrequest on;
location / {
ssi on;
ssi_types *;
proxy_pass http://unmemcached;
proxy_max_temp_file_size 0;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
location @fallback {
ssi on;
proxy_pass http://proxy.site;
proxy_max_temp_file_size 0;
proxy_http_version 1.1;
proxy_set_header Connection "";
error_page 400 500 502 503 504 /offline.html;
}
}
server {
access_log on;
listen 21211;
server_name unmemcached;
error_log /var/log/nginx/error2.log debug; log_subrequest on;
location / {
set $memcached_key "$uri?$args";
memcached_pass memcached;
memcached_gzip_flag 2;
default_type text/html;
charset utf-8;
gunzip on;
proxy_set_header Accept-Encoding "gzip";
error_page 404 405 400 500 502 503 504 = @fallback;
}
location @fallback {
#ssi on;
proxy_pass http://proxy.site;
proxy_max_temp_file_size 0;
proxy_http_version 1.1;
proxy_set_header Connection "";
error_page 400 500 502 503 504 /offline.html;
}
}
我希望尽可能避免使用动态nginx模块的解决方案
答案 0 :(得分:0)
基本上有两个问题需要考虑 - 过滤器模块的顺序是否合适,以及gunzip是否适用于您的情况。
一个简单的search for "nginx order of filter modules"表明订单是在编译时根据auto/modules
shell脚本的内容确定的:
http://www.evanmiller.org/nginx-modules-guide.html
多个过滤器可以挂钩到每个位置,以便(例如)可以压缩响应然后分块。它们的执行顺序在编译时确定。过滤器具有经典的“责任链”设计模式:调用一个过滤器,它是否有效,然后调用下一个过滤器,直到调用最终过滤器,并且Nginx完成响应。
https://allthingstechnical-rv.blogspot.de/2014/07/order-of-execution-of-nginx-filter.html
过滤器的顺序源自nginx模块的执行顺序。 nginx模块的执行顺序在nginx源代码中的auto / modules文件中实现。
快速浏览一下auto/modules
,可以看出ssi
介于gzip
和gunzip
之间,但是,目前还不清楚模块执行的方式(从上到下或从下到上),因此,默认值可能是合理的,或者,您可能需要切换两个(不一定支持,恕我直言)。
此处的一个提示是http_not_modified
过滤器的位置,该过滤器作为上述EMiller指南中If-Modified-Since
处理的示例给出;我会想象它必须在所有其他的之后,最后,如果是这样,那么,确实,似乎gunzip / ssi / gzip的顺序恰好与你需要的相反。
根据http://nginx.org/r/gunzip,过滤器的文档中包含以下文本:
启用或禁用对缺少gzip支持的客户端的gzip压缩解压缩。
上述陈述是否应被解释为模块的描述(例如,缺少gzip支持的客户端是您可能想要使用此模块的原因),或者是否是行为的描述(目前尚不完全清楚)例如,模块是否自己确定客户端是否支持gzip)。 src/http/modules/ngx_http_gunzip_filter_module.c处的源代码似乎暗示它只是检查回复的Content-Encoding
是否为gzip
,如果是,则继续。但是,文档中的下一个句子(在上面引用的一个之后)似乎表明它与gzip
模块有更多的交互,因此,也许还有其他内容。
我的猜测是,如果您正在使用浏览器进行测试,那么浏览器支持gzip,因此,gunzip
不参与是合理的,因此,SSI模块永远不会有任何有效的内容处理。这就是为什么我建议您确定通过curl
执行简单的纯文本请求与使用包含Accept-Encoding
的{{1}}的浏览器做出的正确文本请求之间的枪口是否正常和/或不同。
根据上述调查的结果,我会尝试确定模块的顺序,如果不正确,可以选择重新编译还是双重代理是解决方案。
随后,如果问题仍然无法解决,我会确保gzip
过滤器无条件地对来自memcached
的数据进行解压缩;我想你可能不得不忽略或重置gunzip
标题或其他一些标题。