Nginx 反代 Gzip 内容时, sub_filter 等 content filter 无效的另一种解决 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
ryd994
V2EX    NGINX

Nginx 反代 Gzip 内容时, sub_filter 等 content filter 无效的另一种解决

  •  
  •   ryd994
    ryd994 2015-11-09 23:28:27 +08:00 17252 次点击
    这是一个创建于 3628 天前的主题,其中的信息可能已经有所发展或是发生改变。
    大家Nginx 反代时很常见的一个问题就是 sub_filter 无效。因为浏览器都是允许压缩的,所以请求头都是带 Accept-Encoding: gzip 的。而 Nginx 的 sub_filter 无法处理压缩过的请求, Nginx 自身也不会解压。事实上,要想写一个解压的插件也是不可能的,因为 Nginx 目前并没有 input filtering 相关的接口。

    一般网上的解决办法都是 proxy_set_header Accept-Encoding "";禁用上游的压缩,对客户端的压缩不受影响。但是这样入站带宽就多很多了。一个可行的改进是活用 map ,只禁用常见的 html 内容的压缩。但是这样对纯网页效果依然有限。 CrystalACG 上即使缓存命中率过半(对纯网页几乎没有静态内容的 dmm 来说很高了),入站带宽依然超过出站。

    最近尝试了另一种办法,效果不错。尽管 Nginx 没有 input filtering ,但我们可以反代自身,利用 gunzip 模块先解压。这样会有本地流量,但用 unix socks 的话额外开销只有 nginx 重新解析一次请求以及数据内存拷贝一次。几乎可以忽略。gzip 本身是很低开销的算法。就算将来Nginx加入了input filtering的支持,性能也不会比这个方案好很多。而且大多数反代站瓶颈都在带宽,CPU多一点无所谓。

    新建一个 gunzip.conf :
    修改原来的代理配置:
    proxy_pass http://unix:/var/run/nginx-gunzip.sock:$request_uri;
    proxy_set_header Host $host;
    proxy_set_header Accept-Encoding "";

    这个办法可以结合map,只反代要替换的内容,进一步减少开销。现在 CrystalACG 入站流量只有原来的一半略多,出站的 2/3 不到。
    第 1 条附言    2017-10-16 07:33:46 +08:00
    为啥好多人突然关注这个陈年老贴。。。。
    第 2 条附言    2018-10-10 14:43:05 +08:00
    20 条回复    2021-07-29 20:02:18 +08:00
    auzeonfung
        1
    auzeonfung  
       2015-11-09 23:35:21 +08:00
    想不到有方法,了
    Pastsong
        2
    Pastsong  
       2015-11-09 23:35:30 +08:00
    Nice one!
    maemual
        3
    maemual  
       2015-11-10 00:32:35 +08:00 via iPhone
    好机智
    feather12315
        4
    feather12315  
       2015-11-10 00:45:08 +08:00 via Android
    Nice !
    BOYPT
        5
    BOYPT  
       2015-11-10 00:49:38 +08:00
    其实是因为 gunzip 模块默认是尊重客户端请求,如果是 accept gzip 的就不解压;
    我的方案是 patch 了 gunzip 模块,添加了一个 gunzip 的 force 指令,然后输出的时候再由 gzip 模块压回去

    不过楼主这个思路还是挺不错的。
    br00k
        6
    br00k  
       2015-11-10 08:30:23 +08:00 via Android
    mark
    Orzpls
        7
    Orzpls  
       2015-11-10 09:46:01 +08:00 via Android
    马克,备用。
    lovedboy
        8
    lovedboy  
       2015-11-10 09:48:23 +08:00
    好机制。
    phithon
        9
    phithon  
       2015-11-10 10:31:01 +08:00
    是个好办法。。当年没想到,还用 lua 手工解压。。。
    cmheia
        10
    cmheia  
       2015-11-10 12:00:25 +08:00
    @ryd994

    @auzeonfung
    @Pastsong
    @maemual
    @feather12315
    @BOYPT
    @br00k
    @Orzpls
    @lovedboy
    @phithon

    昨晚研究了一下搂住的配置,部分成功,还有些问题。
    用的是这个配置:
    http://jude.me/2014/10/04/twitter-mirror-2.html

    今天按照 @BOYPT 的思路改了一下 ngx 的代码,是不是这样写?
    https://null.cmheia.com/nginx-1.9.6-gunzip_always-patch.diff.7z
    ryd994
        11
    ryd994  
    OP
       2015-11-10 15:08:44 +08:00
    @cmheia
    不要用 if 判断 80 ,所有 80 直接 301 https ,根本不需要 if
    你这一堆一堆的 subs_filter ,不能用 regex 么?既然有野卡,不能用泛域名么?
    有问题贴一下具体的问题配置,你的博客与本主题无关
    没事 @ 所有人很好玩么?
    BOYPT
        12
    BOYPT  
       2015-11-10 21:44:00 +08:00
    @cmheia 其实没什么技术含量,就是加了一个 if 在外面,我摘取修改部分的源码:
    http://pastebin.com/hev12rvn
    cmheia
        13
    cmheia  
       2015-11-10 23:08:07 +08:00
    @BOYPT 我也是这样改的代码。不过测试结果是 subs_filter 失效了。

    后来我在这个 if 块前后增加了 debug
    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "gunzip always: %d", conf->always);
    输出的日志中也看到了相应的文字:
    gunzip always: 1
    gunzip always--
    但是其中 subs_filter 还是失效,目前还未解决。
    相关 diff 及 conf 见 10L 的 7z 链接。

    ------
    to ryd994 :那个博客不是我的。
    不,你该是误解了。
    ryd994
        14
    ryd994  
    OP
       2015-11-11 00:01:52 +08:00
    @cmheia 你检查一下模块调用的顺序,确认 gunzip 在 subs 前面
    fengjianxinghun
        15
    fengjianxinghun  
       2015-11-14 20:33:15 +08:00 via iPad
    nginx lua 模块可以 input filter 。。我现在把客户端的加密数据在 nginx 解密丢给后端,然后把后端的数据加密后压缩给客户端
    a1044634486
        16
    a1044634486  
       2017-10-16 10:09:30 +08:00
    因为有人问了,有个大哥把你的链接写上去了,t/397854#reply7
    xiaoxiaocai1
        17
    xiaoxiaocai1  
       2018-10-10 11:13:08 +08:00
    楼主,gunzip.conf 的配置已经无法访问了
    EMLink
        18
    EMLink  
       2019-08-19 09:02:28 +08:00
    受教了,这个思路很可以
    iyangyuan
        19
    iyangyuan  
       2019-09-11 14:17:31 +08:00
    gunzip.conf 的内容可以直接贴出来吗?
    hb751968840
        20
    hb751968840  
       2021-07-29 20:02:18 +08:00
    有用
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1587 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 30ms UTC 16:26 PVG 00:26 LAX 09:26 JFK 12:26
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86