记一次Nginx ngx_http_substitutions_filter_module 无法正常工作问题的解决方案

由于项目需要使用Nginx做反向代理时,需要对源站返回的内容做一些替换,这些内容有 HTML,CSS,和JS等,Nginx自带的ngx_http_sub_module 模块可以实现替换的功能,但相对于YaoWenBin开发的ngx_http_substitutions_filter_module来说,功能还是稍弱一些:1、不支持大小写区分;2、不支持正则表达式;3、不支持替换多个字符串(ngx_http_sub_module从1.9.4版本开始支持此功能)。

但在使用ngx_http_substitutions_filter_module发现 HTML的内容可以替换,但是JS\CSS文件却替换不了,我将Respone Body内容复制到另外一台服务器上,然后再做反代,发现并没有什么问题,可以正常工作。

我的核心配置文件如下(已经设置了禁用gzip压缩)

location /demo/ {
		proxy_pass http://192.168.1.2
		proxy_set_header Accept-Encoding '';
		subs_filter src_string dst_string;
		subs_filter_types *;
		proxy_redirect off;
	}

排查了近两天,尝试过升级Nginx版本等一系列操作,并没有解决我的问题。

最后只能使用Nginx的Debug功能来排查,发现Debug的日志如下:

2016/05/20 10:47:59 [debug] 390#0: *1 http proxy header: "Content-Encoding: gzip"
2016/05/20 10:47:59 [warn] 390#0: *1 http subs filter header ignored, this may be a compressed response. while reading response header from upstream, client: 192.168.1.2, server: demo.xxxx.com, request: "GET /demo/login.js HTTP/1.1", upstream: "http://192.168.1.2:80/demo/login.js", host: "demo.xxxx.com"

日志反映两个问题:1、响应的HTTP HEADER中显示内容使用GZIP格式压缩;2、响应的内容可能时压缩过的,http subs filter 模块忽略,不处理!原来源站返回的JS和CSS内容还是被压缩了,但是我已经设置了proxy_set_header Accept-Encoding ''了啊?为何返回的内容还是压缩的?决定使用Wireshark抓包查看底层的数据包。

image

从数据包来看,请求的HEADER确实设置了不压缩,但返回的内容确还是压缩的,看来问题出在源站的WEB服务器。

向源站的管理员求证,得到的结果是:JS和CSS的文件已经是被压缩过了的,所以不论请求的是否接收压缩,返回的内容都是被压缩的,这一点不能修改。

源站不能修改,只能从Nginx这里想办法了,但是Nginx替换必须得不是解压缩的,这就不好办了。

摸索中发现这篇文章: Nginx 反代 Gzip 内容时, sub_filter 等 content filter 无效的另一种解决

虽然多了一次请求,但更加节省网络带宽资源。由于使用gunzip模块解压缩,只能再次重新编译Nginx(这次排查问题,重新编译了10次都不止啊Crying face)。

文章中采用的是unix socket的方式,但从一些网友的测试来看,并不如tcp socket稳定(Php-fpm TcpSocket vs UnixSocket),我觉得还是采用监听TCP端口的方式。最终的配置如下:

location /demo-gzip/ {
        proxy_pass http://192.168.1.2/;	
	gunzip on;
        allow 127.0.0.1/32;
        deny all;
}
location /demo/ {
        proxy_pass http://127.0.0.1/t5060-gzip/;			
	proxy_set_header Host demo.xxxx.com;
	proxy_set_header Accept-Encoding '';
	subs_filter src_string dst_string;
	subs_filter_types application/javascript text/css;
}
posted @ 2016-05-21 14:40  HaiyangYu  阅读(3586)  评论(0编辑  收藏  举报