带有memcache,gunzip和ssi的Nginx不能一起工作

时间:2018-03-31 17:17:57

标签: nginx memcached ssi

我正在尝试在Memcached中保存packed(gzip)html并在nginx中使用:

  1. memcached module
  2. 的memcached加载html
  3. 通过nginx gunzip module解压缩(如果已打包)
  4. ssi module
  5. 处理ssi插入
  6. 将结果返回给用户
  7. 主要是配置工作,除了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模块的解决方案

1 个答案:

答案 0 :(得分:0)

基本上有两个问题需要考虑 - 过滤器模块的顺序是否合适,以及gunzip是否适用于您的情况。

0。 gunzip / ssi / gzip的顺序。

一个简单的search for "nginx order of filter modules"表明订单是在编译时根据auto/modules shell脚本的内容确定的:

快速浏览一下auto/modules,可以看出ssi介于gzipgunzip之间,但是,目前还不清楚模块执行的方式(从上到下或从下到上),因此,默认值可能是合理的,或者,您可能需要切换两个(不一定支持,恕我直言)。

此处的一个提示是http_not_modified过滤器的位置,该过滤器作为上述EMiller指南中If-Modified-Since处理的示例给出;我会想象它必须在所有其他的之后,最后,如果是这样,那么,确实,似乎gunzip / ssi / gzip的顺序恰好与你需要的相反。

1。 gunzip有用吗?

根据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标题或其他一些标题。