NGINX
NGINX Trac
3rd Party Modules
Security Advisories
CHANGES
OpenResty
ngx_lua
Tengine
在线学习资源
NGINX 开发从入门到精通
NGINX Modules
ngx_echo
ryd994
V2EX  ›  NGINX

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

  •  
  •   ryd994 ·
    ryd994 · Nov 9, 2015 · 17878 views
    This topic created in 3836 days ago, the information mentioned may be changed or developed.
    大家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 不到。
    Supplement 1  ·  Oct 16, 2017
    为啥好多人突然关注这个陈年老贴。。。。
    Supplement 2  ·  Oct 10, 2018
    20 replies    2021-07-29 20:02:18 +08:00
    auzeonfung
        1
    auzeonfung  
       Nov 9, 2015
    想不到還有這種方法,學習了
    Pastsong
        2
    Pastsong  
       Nov 9, 2015
    Nice one!
    maemual
        3
    maemual  
       Nov 10, 2015 via iPhone
    好机智
    feather12315
        4
    feather12315  
       Nov 10, 2015 via Android
    Nice !
    BOYPT
        5
    BOYPT  
       Nov 10, 2015
    其实是因为 gunzip 模块默认是尊重客户端请求,如果是 accept gzip 的就不解压;
    我的方案是 patch 了 gunzip 模块,添加了一个 gunzip 的 force 指令,然后输出的时候再由 gzip 模块压回去

    不过楼主这个思路还是挺不错的。
    br00k
        6
    br00k  
       Nov 10, 2015 via Android
    mark
    Orzpls
        7
    Orzpls  
       Nov 10, 2015 via Android
    马克,备用。
    lovedboy
        8
    lovedboy  
       Nov 10, 2015
    好机制。
    phithon
        9
    phithon  
       Nov 10, 2015
    是个好办法。。当年没想到,还用 lua 手工解压。。。
    cmheia
        10
    cmheia  
       Nov 10, 2015
    @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
       Nov 10, 2015
    @cmheia
    不要用 if 判断 80 ,所有 80 直接 301 https ,根本不需要 if
    你这一堆一堆的 subs_filter ,不能用 regex 么?既然有野卡,不能用泛域名么?
    有问题贴一下具体的问题配置,你的博客与本主题无关
    没事 @ 所有人很好玩么?
    BOYPT
        12
    BOYPT  
       Nov 10, 2015
    @cmheia 其实没什么技术含量,就是加了一个 if 在外面,我摘取修改部分的源码:
    http://pastebin.com/hev12rvn
    cmheia
        13
    cmheia  
       Nov 10, 2015
    @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
       Nov 11, 2015
    @cmheia 你检查一下模块调用的顺序,确认 gunzip 在 subs 前面
    fengjianxinghun
        15
    fengjianxinghun  
       Nov 14, 2015 via iPad
    nginx lua 模块可以 input filter 。。我现在把客户端的加密数据在 nginx 解密丢给后端,然后把后端的数据加密后压缩给客户端
    a1044634486
        16
    a1044634486  
       Oct 16, 2017
    因为有人问了,有个大哥把你的链接写上去了,https://www.v2ex.com/t/397854#reply7
    xiaoxiaocai1
        17
    xiaoxiaocai1  
       Oct 10, 2018
    楼主,gunzip.conf 的配置已经无法访问了
    EMLink
        18
    EMLink  
       Aug 19, 2019
    受教了,这个思路很可以
    iyangyuan
        19
    iyangyuan  
       Sep 11, 2019
    gunzip.conf 的内容可以直接贴出来吗?
    hb751968840
        20
    hb751968840  
       Jul 29, 2021
    有用
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   3200 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 56ms · UTC 14:29 · PVG 22:29 · LAX 07:29 · JFK 10:29
    ♥ Do have faith in what you're doing.