【问题标题】:Nginx with memcache, gunzip and ssi don't working together带有 memcache、gunzip 和 ssi 的 Nginx 不能一起工作
【发布时间】:2018-09-10 10:32:04
【问题描述】:

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

  1. memcached module 的memcached 加载html
  2. 如果已打包,则由 nginx gunzip module 解包
  3. 通过ssi module处理ssi插入
  4. 返回结果给用户

大多数情况下,配置工作,除了 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 模块的解决方案

【问题讨论】:

  • 你能先从配置中删除缓存,看看它是否有效吗?您应该一次使用一层来解决问题
  • 没有缓存或没有 gzip 一切正常。但我需要 ssi =) 的 gziped 缓存
  • 我已经看过了。使用 ssi 进行缓存工作正常
  • @demon101 如果你清除所有缓存,然后请求带有curl 的页面,而不使用任何更高级别的 UA,会发生什么?

标签: nginx memcached ssi


【解决方案1】:

基本上有两个问题需要考虑——过滤器模块的顺序是否合适,以及 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 模块将永远不会有任何有效的处理.这就是为什么我建议您确定 gunzip 在通过 curl 执行简单纯文本请求与使用包含 gzipAccept-Encoding 浏览器发出的请求之间是否正常工作和/或不同。

解决方案。

根据上述调查结果,我会尝试确定模块的顺序,如果不正确,可以选择重新编译或双重代理。

随后,如果问题仍然没有解决,我会确保gunzip过滤器会无条件地对来自memcached的数据进行解压;我想您可能不得不忽略或重置 Accept-Encoding 标头或类似的标头。

【讨论】:

  • gunzip 运行良好。试图将 memcached + gunzip 的结果作为 SSI 片段插入页面。 (另一种方式。在问题中——SSI 片段到 memcached + gunzip 页面)。我认为,过滤顺序的问题。但在这种情况下,我不明白为什么使用服务器配置的解决方案也不起作用
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-06-16
  • 1970-01-01
  • 1970-01-01
  • 2012-04-24
  • 1970-01-01
  • 2021-10-21
  • 1970-01-01
相关资源
最近更新 更多